У меня есть следующий DataFrame:
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, чтобы все Type
смешалось. Возможный результат может быть:
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
...
Как мне этого добиться?
.copy()
вы по-прежнему ссылаетесь на тот же базовый объект.Вы можете просто использовать sklearn для этого
источник
Вы можете перетасовать строки фрейма данных, проиндексировав их с помощью перетасованного индекса. Для этого вы можете, например, использовать
np.random.permutation
(ноnp.random.choice
это также возможно):Если вы хотите сохранить индекс с номерами 1, 2, .., n, как в вашем примере, вы можете просто сбросить индекс:
df_shuffled.reset_index(drop=True)
источник
TL; DR :
np.random.shuffle(ndarray)
может сделать работу.Итак, в вашем случае
DataFrame
, под капотом, использует NumPy ndarray в качестве держателя данных. (Вы можете проверить из исходного кода DataFrame )Так что, если вы используете
np.random.shuffle()
, он будет перетасовывать массив вдоль первой оси многомерного массива. Но индексDataFrame
остается не перетасованным.Тем не менее, есть некоторые моменты, которые следует учитывать.
sklearn.utils.shuffle()
, как предложил пользователь tj89, может назначитьrandom_state
наряду с другой опцией для управления выводом. Вы можете хотеть это для цели разработки.sklearn.utils.shuffle()
быстрее. Но будет перетасовывать информацию об оси (индекс, столбец)DataFrame
вместе сndarray
содержащейся в ней.Результат теста
между
sklearn.utils.shuffle()
иnp.random.shuffle()
.ndarray
0,10793248389381915 сек. В 8 раз быстрее
0,8897626010002568 с
DataFrame
0,3183923360193148 сек. В 3 раза быстрее
0,9357550159329548 сек
используемый код
питонбенчмаркинг
источник
df = df.sample(frac=1)
делает то же самое, что иdf = sklearn.utils.shuffle(df)
? По моим измерениямdf = df.sample(frac=1)
быстрее и, кажется, выполняет точно такое же действие. Они также выделяют новую память.np.random.shuffle(df.values)
самый медленный, но не выделяет новую память.df.sample(frac=1)
это примерно на 20% быстрее, чемsklearn.utils.shuffle(df)
при использовании того же кода выше. Или вы могли бы сделать,sklearn.utils.shuffle(ndarray)
чтобы получить другой результат.(У меня недостаточно репутации, чтобы комментировать это в верхнем посте, поэтому я надеюсь, что кто-то другой может сделать это для меня.) Была обеспокоенность, что первый метод:
сделал глубокую копию или просто изменил фрейм данных. Я запустил следующий код:
и мои результаты были:
Это означает, что метод не возвращает тот же объект, как было предложено в последнем комментарии. Так что этот метод действительно делает случайную копию .
источник
id
), базовый объект не копируется. Другими словами, операция эффективно выполняется в памяти (хотя, по общему признанию, это не очевидно).Что также полезно, если вы используете его для Machine_learning и хотите всегда разделять одни и те же данные, вы можете использовать:
это гарантирует, что ваш случайный выбор будет всегда воспроизводимым
источник
AFAIK самое простое решение:
источник
np.random.permutation
: «... Если x является массивом, сделайте копию и перемешайте элементы случайным образом». ДокументацияDataFrame.reindex
: « Новый объект создается, если новый индекс не эквивалентен текущему и copy = False». Таким образом, ответ совершенно безопасен (хотя и создает копию).np.random.permutation says
, и в зависимости от версий NumPy, вы получаете эффект, который я описал или тот, который вы упоминаете. При numpy> 1.15.0, при создании фрейма данных и выполнении простогоnp.random.permutation(df.index)
, индексы в исходном df изменяются. То же самое не верно для numpy == 1.14.6. Поэтому, как никогда ранее, я повторяю свое предупреждение: такой способ действий опасен из-за непредвиденных побочных эффектов и зависимостей версий.Index
типа ... В любом случае я основываю свои рекомендации / предупреждения на фактическом поведении, а не на документах: pперетасуйте фрейм данных Pandas, взяв образец массива в этом случае индекса и рандомизируйте его порядок, а затем установите массив в качестве индекса фрейма данных. Теперь отсортируйте фрейм данных по индексу. Вот твой перетасованный кадр данных
вывод
Вставьте свой фрейм данных вместо моего в приведенном выше коде.
источник
Вот еще один способ:
df['rnd'] = np.random.rand(len(df)) df = df.sort_values(by='rnd', inplace=True).drop('rnd', axis=1)
источник