У меня есть следующие таблицы данных:
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. Все строки, которые имеют " тип " 1 находятся на верхней, а затем строки с Тип
2, затем строки с Тип
3, и т. д.
Я хотел бы, чтобы перетасовать порядок таблицы данных's строк, так что все тип
's являются смешанными. Возможным результатом может быть:
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
...
Как я могу добиться этого?
Идиоматические способ сделать это в панды является использование .образец метод таблицы данных, т. е. ``питон ДФ.образец(ГРП=1) `` Аргумент ключевого слова
ГРПопределяет долю возвращаемых строк в выборке, так
ГРП=1` значит вернуть все строки (в произвольном порядке).
Примечание:
Если вы хотите, чтобы перетасовать вашу таблицу данных на месте и сбросить индекс, вы могли бы сделать, например
питон ДФ = ДФ.образец(ГРП=1).reset_index(капля=истина)
Здесь, указывая капля=правда
мешает `.reset_index от создания столбца, содержащей старые записи индекса.
Последующие Примечание: хотя он не может выглядеть, как описанная выше операция на месте, Python и панды достаточно умен, чтобы не делать еще один аналог для тасуется объекта. То есть, даже несмотря на ссылка объект изменился (я имею в виду ИД(df_old)не совпадает с
ИД(df_new)`), базовый объект С является все тот же. Чтобы показать, что это действительно так, вы можете запустить простой профайлер памяти:
``
$ питон3 -м memory_profiler .\test.py
Имя файла: .\test.py
5 68.5 68.5 МИБ МИБ @профилю 6 деф перемешать(): 7 847.8 779.3 МИБ МИБ ДФ = др.Таблицы данных(НП.случайные.randn(100, 1000000)) 8 847.9 МИБ 0.1 Мб ДФ = ДФ.образец(ГРП=1).reset_index(капля=истина)
``
Вы можете просто использовать sklearn для этого
from sklearn.utils import shuffle
df = shuffle(df)
Вы можете тасовать строки таблицы данных путем индексирования с перетасованную индекса. Для этого, например, можно использовать НП.случайные.перестановка(но
НП.случайные.выбор-это также возможность):
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(капля=истина)
Сюжет: `НП.случайные.перетасовать(ndarray) может сделать работу. Таким образом, в вашем случае
np.random.shuffle(DataFrame.values)
Таблицы данных
, под капотом, использует библиотеки numpy ndarray как держатель данных. (Вы можете проверить с исходный код таблицы данных)
Так что если вы используете np.random.shuffle()
он бы перемешивает массив вдоль первой оси многомерного массива. Но индекс в таблице данных остается unshuffled.
Хотя, есть некоторые моменты, которые следует учитывать.
sklearn.utils.shuffle()
как пользователь tj89 предложил, может назначить random_state
наряду с другой вариант для выходного контроля. Вы можете, что для цели разработки.sklearn.utils.shuffle()
быстрее. Но будут тасовать оси информация(индекс столбца) из таблицы данныхнаряду с
ndarray` содержит.Тест ## результат
между sklearn.utils.shuffle()
и np.random.shuffle()
.
nd = sklearn.utils.shuffle(nd)
0.10793248389381915 сек. В 8 раз быстрее
np.random.shuffle(nd)
0.8897626010002568 сек
df = sklearn.utils.shuffle(df)
0.3183923360193148 сек. В 3 раза быстрее
np.random.shuffle(df.values)
0.9357550159329548 сек
вывод: если это нормально, чтобы ось инфо(индекс столбца), чтобы быть перетасованы вместе с ndarray, использовать
sklearn.utils.shuffle()
. В противном случае, используйтеnp.random.shuffle()
import timeit
setup = '''
import numpy as np
import pandas as pd
import sklearn
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
что означает метод ** не возвращался один и тот же объект, как было предложено в последнем комментарии. Поэтому этот метод действительно делает тасуется копия**.
Что также полезно, если вы используете его для Machine_learning и хочу отдельно всегда одни и те же данные, вы могли бы использовать:
ДФ.выборки(N=лен(ДФ), random_state=42)
это гарантирует, что вы держите свой случайный выбор всегда replicatable
перетасовать панды фрейма данных путем отбора пробы массива в этом случае индекс и перемешайте его, чтобы потом установить время как индекс фрейма данных. Теперь вроде фрейма данных по индексу. Вот идет ваш тасуется таблицы данных
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
Вставить фрейм данных в места, где я в приведенном выше коде .
Вот еще один способ:
ДФ['рнд'] = НП.случайные.Рэнд(лен(ДФ)) ДФ = ДФ.sort_values(счет='рнд', "на месте" =правда).падение('рнд', оси=1)