Полное руководство: перемешивание строк DataFrame в pandas
Узнайте лучшие способы перемешать строки DataFrame в pandas, сохраняя целостность данных. Используйте sample(frac=1) и random_state для воспроизводимых результатов.
Как перемешать строки в DataFrame pandas, чтобы типы были разбросаны?
У меня есть DataFrame pandas со следующей структурой:
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 так, чтобы все типы были смешаны. Возможный результат может выглядеть так:
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():
df_shuffled = df.sample(frac=1)
Этот метод работает так:
frac=1указывает, что мы хотим выбрать 100 % строкsample()случайным образом выбирает строки без замены- Все исходные значения и структура колонок сохраняются
- Оригинальные индексы сохраняются, но в случайном порядке
Как объясняет GeeksforGeeks, этот подход случайным образом перемешивает все строки, выбирая 100 % данных. Однако он оставляет оригинальные метки индексов, что может выглядеть «нечисто».
Для более чистого результата объедините его с reset_index():
df_shuffled = df.sample(frac=1).reset_index(drop=True)
Параметр drop=True предотвращает добавление старого индекса как нового столбца, давая вам чистый 0‑базовый последовательный индекс. Как отмечает Delft Stack, это создаёт профессионально выглядящий DataFrame с правильной индексацией.
Метод 2: Использование numpy.random.shuffle()
Если вы предпочитаете возможности случайного выбора NumPy, можно воспользоваться numpy.random.shuffle():
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:
df_shuffled = df.sample(frac=1, random_state=42).reset_index(drop=True)
Как объясняется в официальной документации pandas, вы можете использовать random_state для воспроизводимости. Это особенно важно, когда вам нужно:
- Делать код совместимым с другими людьми и получать одинаковые результаты
- Отлаживать пайплайн машинного обучения
- Создавать воспроизводимые исследовательские результаты
Параметр random_state может быть любым целым числом или объектом numpy.random.RandomState. При использовании того же значения random_state вы получите одинаковый перемешанный DataFrame каждый раз.
Для более контролируемой воспроизводимости вы также можете сохранить случайный индекс:
# Генерируем и сохраняем случайный индекс для воспроизводимости
random_index = df.sample(frac=1).index
# Используем этот индекс для последовательного перемешивания
df_shuffled = df.loc[random_index].reset_index(drop=True)
Этот подход, как упомянуто в Stack Overflow, позволяет повторно воспроизвести перемешивание, если вам нужно точно воспроизвести вывод алгоритма.
Сохранение целостности данных
Все вышеуказанные методы сохраняют полную целостность данных, потому что:
- Нет потерь данных: все строки и столбцы сохраняются
- Нет изменения данных: значения ячеек остаются неизменными
- Структура колонок сохраняется: все колонки сохраняют имена и типы данных
- Связи сохраняются: внутренние корреляции между колонками сохраняются
Как подчёркивает Medium’s Hey Amit, перемешивание помогает сохранить случайность и целостность данных, что приводит к более надёжным результатам. Случайность особенно полезна при работе с данными, которые могут иметь внутренний порядок, вводящий смещение в анализ.
Полный практический пример
Ниже приведён полный пример, показывающий, как перемешать ваш DataFrame:
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))
Лучшие практики и рекомендации
- Используйте
sample(frac=1).reset_index(drop=True)как основной метод — это самый лаконичный и идиоматический способ перемешать строки. - Всегда используйте
random_state, когда важна воспроизводимость:pythondf_shuffled = df.sample(frac=1, random_state=42).reset_index(drop=True) - Проверьте перемешивание, проверяя распределение ваших категориальных переменных:python
print("Распределение типов в исходном:", df['Type'].value_counts()) print("Распределение типов в перемешанном:", df_shuffled['Type'].value_counts()) - Обрабатывайте большие DataFrame эффективно — метод
sample()оптимизирован для производительности и хорошо работает с большими наборами данных. - Сохраняйте исходный DataFrame, если вам нужны обе версии:python
df_original = df.copy() # Сохраняем оригинал df_shuffled = df.sample(frac=1).reset_index(drop=True) # Создаём перемешанный
Как отмечает Towards Data Science, если вы хотите, чтобы перемешивание было воспроизводимым, обязательно укажите корректное значение для аргумента random_state. Это гарантирует, что ваши результаты будут последовательными при разных запусках и легко проверяемыми другими.
Источники
- pandas.DataFrame.sample — pandas 2.3.3 documentation
- How to Randomly Shuffle DataFrame Rows in Pandas | Delft Stack
- How to shuffle a DataFrame rows in Pandas - GeeksforGeeks
- Pandas Shuffle DataFrame Rows Examples - Spark By Examples
- How to Shuffle a Pandas DataFrame? | Hey Amit | Medium
- Shuffling Rows in Pandas DataFrames | Towards Data Science
- python - Shuffle DataFrame rows - Stack Overflow
Заключение
Перемешивание строк в pandas DataFrame для смешения разных типов простое с помощью sample(frac=1).reset_index(drop=True). Этот подход сохраняет полную целостность данных, одновременно достигая нужной случайности. Для воспроизводимых результатов всегда включайте параметр random_state. Перемешанный DataFrame будет содержать все ваши исходные данные с той же структурой колонок и типами данных, но строки будут расположены в случайном порядке, смешивая все типы вместе. Эта техника необходима для машинного обучения, статистического анализа и любых сценариев, где вы хотите избежать смещения, вызванного порядком данных.