Другое

Полное руководство: перемешивание строк DataFrame в pandas

Узнайте лучшие способы перемешать строки DataFrame в pandas, сохраняя целостность данных. Используйте sample(frac=1) и random_state для воспроизводимых результатов.

Как перемешать строки в DataFrame pandas, чтобы типы были разбросаны?

У меня есть DataFrame pandas со следующей структурой:

python
    Col1  Col2  Col3  Type
0      1     2     3     1
1      4     5     6     1
...
20     7     8     9     2
21    10    11    12     2
...
45    13    14    15     3
46    16    17    18     3
...

DataFrame читается из CSV‑файла. В данный момент все строки с Type = 1 находятся вверху, затем идут строки с Type = 2, потом Type = 3 и т.д.

Мне нужно перемешать порядок строк DataFrame так, чтобы все типы были смешаны. Возможный результат может выглядеть так:

python
    Col1  Col2  Col3  Type
0      7     8     9     2
1     13    14    15     3
...
20     1     2     3     1
21    10    11    12     2
...
45     4     5     6     1
46    16    17    18     3
...

Какой лучший способ перемешать строки в pandas, сохранив целостность данных?

Понимание проблемы

Ваш DataFrame организован по колонке Type, где все строки с Type 1 идут первыми, затем Type 2, потом Type 3 и так далее. Такая упорядоченная структура может вводить смещение в моделях машинного обучения или статистических анализах, когда вы хотите иметь репрезентативные выборки из всех категорий.

Как отмечает Spark By Examples, перемешивание строк при сохранении чистого последовательного индекса — распространённый способ обеспечить случайность данных. Цель — достичь «контролируемого хаоса», где порядок строк случайный, но все значения и связи данных остаются неизменными.

Метод 1: Использование sample() с frac=1

Самый прямой и идиоматический для pandas способ — использовать метод sample():

python
df_shuffled = df.sample(frac=1)

Этот метод работает так:

  • frac=1 указывает, что мы хотим выбрать 100 % строк
  • sample() случайным образом выбирает строки без замены
  • Все исходные значения и структура колонок сохраняются
  • Оригинальные индексы сохраняются, но в случайном порядке

Как объясняет GeeksforGeeks, этот подход случайным образом перемешивает все строки, выбирая 100 % данных. Однако он оставляет оригинальные метки индексов, что может выглядеть «нечисто».

Для более чистого результата объедините его с reset_index():

python
df_shuffled = df.sample(frac=1).reset_index(drop=True)

Параметр drop=True предотвращает добавление старого индекса как нового столбца, давая вам чистый 0‑базовый последовательный индекс. Как отмечает Delft Stack, это создаёт профессионально выглядящий DataFrame с правильной индексацией.

Метод 2: Использование numpy.random.shuffle()

Если вы предпочитаете возможности случайного выбора NumPy, можно воспользоваться numpy.random.shuffle():

python
import numpy as np

# Получаем значения как массив NumPy
values = df.values

# Перемешиваем массив
np.random.shuffle(values)

# Создаём новый DataFrame из перемешанных значений
df_shuffled = pd.DataFrame(values, columns=df.columns)

Согласно Spark By Examples, вы можете использовать numpy.random.shuffle() для изменения порядка строк DataFrame. Однако этот метод требует, чтобы вы импортировали NumPy до использования и пересоздаёт DataFrame из перемешанных значений.

Преимущество этого подхода в том, что он даёт прямой контроль над процессом случайного выбора, но он более громоздкий, чем метод sample().

Повторяемое перемешивание с random_state

Для воспроизводимых результатов — то есть чтобы получать одинаковый порядок перемешивания каждый раз при запуске кода — используйте параметр random_state:

python
df_shuffled = df.sample(frac=1, random_state=42).reset_index(drop=True)

Как объясняется в официальной документации pandas, вы можете использовать random_state для воспроизводимости. Это особенно важно, когда вам нужно:

  • Делать код совместимым с другими людьми и получать одинаковые результаты
  • Отлаживать пайплайн машинного обучения
  • Создавать воспроизводимые исследовательские результаты

Параметр random_state может быть любым целым числом или объектом numpy.random.RandomState. При использовании того же значения random_state вы получите одинаковый перемешанный DataFrame каждый раз.

Для более контролируемой воспроизводимости вы также можете сохранить случайный индекс:

python
# Генерируем и сохраняем случайный индекс для воспроизводимости
random_index = df.sample(frac=1).index

# Используем этот индекс для последовательного перемешивания
df_shuffled = df.loc[random_index].reset_index(drop=True)

Этот подход, как упомянуто в Stack Overflow, позволяет повторно воспроизвести перемешивание, если вам нужно точно воспроизвести вывод алгоритма.

Сохранение целостности данных

Все вышеуказанные методы сохраняют полную целостность данных, потому что:

  1. Нет потерь данных: все строки и столбцы сохраняются
  2. Нет изменения данных: значения ячеек остаются неизменными
  3. Структура колонок сохраняется: все колонки сохраняют имена и типы данных
  4. Связи сохраняются: внутренние корреляции между колонками сохраняются

Как подчёркивает Medium’s Hey Amit, перемешивание помогает сохранить случайность и целостность данных, что приводит к более надёжным результатам. Случайность особенно полезна при работе с данными, которые могут иметь внутренний порядок, вводящий смещение в анализ.

Полный практический пример

Ниже приведён полный пример, показывающий, как перемешать ваш DataFrame:

python
import pandas as pd
import numpy as np

# Создаём примерный DataFrame, похожий на ваш
data = {
    'Col1': [1, 4, 7, 10, 13, 16] + [2, 5, 8, 11, 14, 17] + [3, 6, 9, 12, 15, 18],
    'Col2': [2, 5, 8, 11, 14, 17] + [3, 6, 9, 12, 15, 18] + [4, 7, 10, 13, 16, 19],
    'Col3': [3, 6, 9, 12, 15, 18] + [4, 7, 10, 13, 16, 19] + [5, 8, 11, 14, 17, 20],
    'Type': [1]*6 + [2]*6 + [3]*6
}

df = pd.DataFrame(data)

print("Исходный DataFrame:")
print(df.head(12))
print("\nРаспределение типов в исходном:")
print(df['Type'].value_counts())

# Метод 1: Базовое перемешивание
df_shuffled = df.sample(frac=1).reset_index(drop=True)

print("\nПеремешанный DataFrame (первые 12 строк):")
print(df_shuffled.head(12))
print("\nРаспределение типов в перемешанном:")
print(df_shuffled['Type'].value_counts())

# Метод 2: Воспроизводимое перемешивание
df_reproducible = df.sample(frac=1, random_state=42).reset_index(drop=True)

print("\nВоспроизводимое перемешивание (одинаковый результат каждый раз):")
print(df_reproducible.head(12))

Лучшие практики и рекомендации

  1. Используйте sample(frac=1).reset_index(drop=True) как основной метод — это самый лаконичный и идиоматический способ перемешать строки.
  2. Всегда используйте random_state, когда важна воспроизводимость:
    python
    df_shuffled = df.sample(frac=1, random_state=42).reset_index(drop=True)
    
  3. Проверьте перемешивание, проверяя распределение ваших категориальных переменных:
    python
    print("Распределение типов в исходном:", df['Type'].value_counts())
    print("Распределение типов в перемешанном:", df_shuffled['Type'].value_counts())
    
  4. Обрабатывайте большие DataFrame эффективно — метод sample() оптимизирован для производительности и хорошо работает с большими наборами данных.
  5. Сохраняйте исходный DataFrame, если вам нужны обе версии:
    python
    df_original = df.copy()  # Сохраняем оригинал
    df_shuffled = df.sample(frac=1).reset_index(drop=True)  # Создаём перемешанный
    

Как отмечает Towards Data Science, если вы хотите, чтобы перемешивание было воспроизводимым, обязательно укажите корректное значение для аргумента random_state. Это гарантирует, что ваши результаты будут последовательными при разных запусках и легко проверяемыми другими.

Источники

  1. pandas.DataFrame.sample — pandas 2.3.3 documentation
  2. How to Randomly Shuffle DataFrame Rows in Pandas | Delft Stack
  3. How to shuffle a DataFrame rows in Pandas - GeeksforGeeks
  4. Pandas Shuffle DataFrame Rows Examples - Spark By Examples
  5. How to Shuffle a Pandas DataFrame? | Hey Amit | Medium
  6. Shuffling Rows in Pandas DataFrames | Towards Data Science
  7. python - Shuffle DataFrame rows - Stack Overflow

Заключение

Перемешивание строк в pandas DataFrame для смешения разных типов простое с помощью sample(frac=1).reset_index(drop=True). Этот подход сохраняет полную целостность данных, одновременно достигая нужной случайности. Для воспроизводимых результатов всегда включайте параметр random_state. Перемешанный DataFrame будет содержать все ваши исходные данные с той же структурой колонок и типами данных, но строки будут расположены в случайном порядке, смешивая все типы вместе. Эта техника необходима для машинного обучения, статистического анализа и любых сценариев, где вы хотите избежать смещения, вызванного порядком данных.

Авторы
Проверено модерацией
Модерация