Перемешивание строк фрейма данных
у меня есть следующий фрейм данных:
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
...
фрейм данных считывается из файла csv. Все строки, которые имеют Type
1 сверху, а затем строки с Type
2, после строки Type
3, etc.
Я хотел бы перетасовать строки фрейма данных, так что все 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
...
как видно из результата, порядок строк перемешивается, но столбцы остаются прежними. Я не знаю если я объясняю это ясно. Дай мне знать, если я этого не сделаю.
как я могу добиться этого?
7 ответов:
более идиоматичный способ сделать это с пандами-использовать
.sample
метод вашего фрейма данных, т. е.df.sample(frac=1)
The
frac
аргумент ключевого слова указывает долю строк, возвращаемых в случайной выборке, поэтомуfrac=1
означает возврат всех строк (в случайном порядке).Примечание: если вы хотите перетасовать свой фрейм данных на месте и сбросить индекс, вы можете сделать, например,
df = df.sample(frac=1).reset_index(drop=True)
здесь, указав
drop=True
предотвращает.reset_index
от создания столбца, содержащего старые записи индекса.
вы можете перемешать строки фрейма данных путем индексирования с перемешанным индексом. Для этого вы можете, например, использовать
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
если вы хотите, чтобы индекс был пронумерован от 1, 2,.., n как и в вашем примере, вы можете просто сбросить индекс:
df_shuffled.reset_index(drop=True)
TL; DR:
np.random.shuffle(ndarray)
может сделать работу.
Итак, в вашем случаеnp.random.shuffle(DataFrame.values)
исходя из моего понимания, DataFrame, под капотом, использует NumPy ndarray в качестве держателя данных. Вы можете проверить от исходный код фрейма данных. Так что если вы используете
np.random.shuffle()
, он будет перетасовывать массив вдоль первой оси многомерного массива. Но колонны-мудрый остается тем же самым.некоторые ограничения следующие.
- функция возвращает none. В случае, если вы хотите сохранить копию исходного объекта, вы должны сделать это прежде, чем вы передадите в функцию.
sklearn.utils.shuffle()
пользователь tj89 предложил, может назначитьrandom_state
вместе с другим вариантом для того чтобы контролировать выход. Вы можете, что для цели разработки.результат теста
между
sklearn.utils.shuffle()
иnp.random.shuffle()
.ndarray
nd = sklearn.utils.shuffle(nd)
0.10793248389381915 сек. в 8 раз быстрее
np.random.shuffle(nd)
0.8897626010002568 сек
DataFrame
df = sklearn.utils.shuffle(df)
0.3183923360193148 сек. 3x быстрее
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)
(у меня недостаточно репутации, чтобы прокомментировать это на верхнем посту, поэтому я надеюсь, что кто-то еще может сделать это для меня.) была высказана озабоченность тем, что первый метод:
df.sample(frac=1)
сделал глубокую копию или просто изменил фрейм данных. Я запустил следующий код:
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
что означает, что метод не возвращает тот же объект, как было предложено в последнем комментарии. Так что этот метод делает действительно сделать перетасовал скопировать.
перетасуйте фрейм данных pandas, взяв образец массива в этом случае индекс и рандомизируйте его порядок, затем установите массив в качестве индекса фрейма данных. Теперь отсортируйте фрейм данных по индексу. Вот идет ваш перетасованный фрейм данных
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
вставьте фрейм данных в место моего в вышеуказанном коде .