Перетасуйте ряды DataFrame

У меня есть следующий 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. Все ряды, которые имеют Тип 1 находятся на вершине, сопровождаемой рядами с Тип 2, сопровождаются рядами с Тип 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
...

Как видно от результата, перетасован заказ рядов, но колонки остаются тем же самым. Я не знаю, объясняю ли я это ясно. Сообщите мне, не делаю ли я.

Как я могу достигнуть этого?

161

7 ответы

Более идиоматический способ сделать это с пандами должно использовать .sample метод вашего dataframe, т.е.

df.sample(frac=1)

frac аргумент ключевого слова определяет часть рядов, чтобы возвратиться в случайной выборке, таким образом frac=1 средства возвращает все ряды (в произвольном порядке).

Note: If you wish to shuffle your dataframe in-place and reset the index, you could do e.g.

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

Здесь, определяя drop=True предотвращает .reset_index от создания колонки, содержащей старые элементы индекса.

329
добавлено
reset_index делает перетасовку, чтобы работать!!!
добавлено автор 0709_, источник
Ре. ваш примечание , образец() метод doesn' t имеют оперативный параметр, таким образом, кажется, что (в настоящее время) не возможно сделать то, что вы предложили, не создавая новый объект.
добавлено автор m-dz, источник
Цитирование от вышеупомянутого "Примечания: Если вы хотите перетасовать свое dataframe оперативное [...]".
добавлено автор m-dz, источник
Несомненно, пожалуйста объясните как df.sample (frac=1) .reset_index (drop=True) перетасовки df оперативный ?
добавлено автор m-dz, источник
Да, это точно, что я хотел показать в моем первом комментарии, необходимо назначить необходимую память дважды, которая довольно далека от выполнения его в месте.
добавлено автор m-dz, источник
Насколько я знаю, не после использования образец() , который возвращает новый объект. Попробуйте печать (ведьма (id (df))) и печать (ведьма (id (df.sample (frac=1) .reset_index (drop=True)))) . Но я мог бы неправильно, в основном требоваться, чтобы попросить подтверждение или отрицание здесь.
добавлено автор m-dz, источник
Ценил бы звон здесь, если у вас есть результаты.
добавлено автор m-dz, источник
@m-dz вы на самом деле читали то, что я предложил?
добавлено автор Kris, источник
@m-dz Да... вы читали остальную часть того предложения?
добавлено автор Kris, источник
Это doesn' t. Та линия просто повторно назначает df объект, таким образом эффективно изменяя объект в месте. Посмотрите его как работу.
добавлено автор Kris, источник
@m-dz Исправьте меня если I' m неправильно, но если вы don' t действительно .copy() you' ре, все еще ссылающееся на тот же самый основной объект.
добавлено автор Kris, источник
Хорошо, I' ll управляют им с профилировщиком памяти, когда у меня есть время. Спасибо
добавлено автор Kris, источник
нет, это doesn' t копируют DataFrame, просто смотрят на эту линию: github.com/pandas-dev/pandas/blob/v0.23.0/pandas/core/…
добавлено автор ngọcminh.oss, источник

Можно просто использовать sklearn для этого

from sklearn.utils import shuffle
df = shuffle(df)
97
добавлено

Можно перетасовать ряды dataframe, внеся в указатель с перетасованным индексом. Для этого вы можете, например, использование np.random.permutation (но np.random.choice является также возможностью):

In [12]: df = pd.read_csv(StringIO(s), sep="\s+")

In [13]: df
Out[13]: 
    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

In [14]: df.iloc[np.random.permutation(len(df))]
Out[14]: 
    Col1  Col2  Col3  Type
46    16    17    18     3
45    13    14    15     3
20     7     8     9     2
0      1     2     3     1
1      4     5     6     1
21    10    11    12     2

If you want to keep the index numbered from 1, 2, .., n as in your example, you can simply reset the index: df_shuffled.reset_index(drop=True)

44
добавлено

TL;DR: np.random.shuffle(ndarray) can do the job.
So, in your case

np.random.shuffle(DataFrame.values)

На основе моего понимания DataFrame, под капотом, использует NumPy ndarray в качестве держателя данных. Можно проверить от Исходный код DataFrame. Таким образом, если вы используете np.random.shuffle (), это было бы перетасовывать множество вдоль первой оси многомерного массива. Но мудрое колонками остается тем же самым.

Некоторые ограничения следуют.

  • function returns none. In case you want to keep a copy of the original object, you have to do so before you pass to the function.
  • sklearn.utils.shuffle() user tj89 suggested, can designate random_state along with another option to control output. You may want that for dev purpose.

Эталонный результат

между sklearn.utils.shuffle () и np.random.shuffle ().

ndarray

nd = sklearn.utils.shuffle(nd)

0.10793248389381915 sec. 8x faster

np.random.shuffle(nd)

0.8897626010002568 секунды

DataFrame

df = sklearn.utils.shuffle(df)

0.3183923360193148 sec. 3x faster

np.random.shuffle(df.values)', setup=setup, number=1000)

0.9357550159329548 секунды

Заключение: использовать sklearn.utils.shuffle (), если это возможно.

используемый код

setup = '''
import numpy as np
import pandas as pd
from sklearn.utils import shuffle
nd = np.random.random((1000, 100))
df = pd.DataFrame(nd)
'''

timeit.timeit('nd = sklearn.utils.shuffle(nd)', setup=setup, number=1000)
timeit.timeit('np.random.shuffle(nd)', setup=setup, number=1000)
timeit.timeit('df = sklearn.utils.shuffle(df)', setup=setup, number=1000)
timeit.timeit('np.random.shuffle(df.values)', setup=setup, number=1000)

13
добавлено

(I don't have enough reputation to comment this on the top post, so I hope someone else can do that for me.) There was a concern raised that the first method:

df.sample(frac=1)

сделанный глубокой копией или просто измененный dataframe. Я управлял следующим кодом:

print(hex(id(df)))
print(hex(id(df.sample(frac=1))))
print(hex(id(df.sample(frac=1).reset_index(drop=True))))

и мои результаты были:

0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70

что означает, что метод <�силен> не возвращение того же самого объекта, как был предложен в последнем комментарии. Таким образом, этот метод действительно делает перетасованную <�сильную> копию </сильной>.

2
добавлено

AFAIK простое решение:

df_shuffled = df.reindex(np.random.permutation(df.index))
1
добавлено

перетасуйте структуру данных о пандах, беря типовое множество в этом случае индекс и рандомизируйте его заказ, тогда устанавливает множество как индекс структуры данных. Теперь сортируйте структуру данных согласно индексу. Здесь идет ваш перетасованный dataframe

import random
df = pd.DataFrame({"a":[1,2,3,4],"b":[5,6,7,8]})
index = [i for i in range(df.shape[0])]
random.shuffle(index)
df.set_index([index]).sort_index()

продукция

    a   b
0   2   6
1   1   5
2   3   7
3   4   8

Введите вас структура данных вместо моего в вышеупомянутом коде.

0
добавлено
Python
Python
7 654 участник(ов)

Уютный чат для профессионалов, занимающихся поиском питоньих мудростей. Как не получить бан: https://t.me/ru_python/577926

Python beginners
Python beginners
4 449 участник(ов)

Вопросы про Python для чайников. Cпам и троллинг неприемлем. Не злоупотребляйте стикерами. Частозадаваемые вопросы: https://github.com/ru-python-beginners/faq/blob/master/README.md Статистика тут: https://grstats.me/chat/x4qym2k5uvfkr3al6at7

pro.python
pro.python
1 090 участник(ов)

Сообщество разработчиков под Python Создатель: @rodgelius

Rude Python
Rude Python
971 участник(ов)

Python без „девочек”, здесь матерятся и унижают Django. Not gay friendly. Правила: t.me/rudepython/114107 @rudepython | t.me/rudepython

rupython
rupython
509 участник(ов)

Группа создана с целью оперативного получения ответов на возникающие вопросы по разработке на яп python, смежные темы, а также человеческого общения. Приветствую!

Python-programming
Python-programming
266 участник(ов)

Чат группы вконтакте https://vk.com/python_community