Подмножество pandas dataframe
У меня есть DataFrame
загруженный из файла .tsv
. Я хотел создать несколько поисковых участков. Проблема заключается в том, что набор данных большой (~ 1 миллион строк), поэтому на графике слишком много точек, чтобы увидеть тренд. Плюс, это занимает некоторое время, чтобы построить.
Я хотел сделать выборку 10000 случайно распределенных строк. Это должно быть воспроизводимо, чтобы одна и та же последовательность случайных чисел генерировалась в каждом прогоне.
Это: Пример двух выборок данных для панд одинаковым образом, кажется, на правильном пути, но я не могу гарантировать размер подвыборки.
Ответы
Ответ 1
Вы можете выбрать случайные элементы из вашего индекса с помощью np.random.choice
. Например, чтобы выбрать 5 случайных строк:
df = pd.DataFrame(np.random.rand(10))
df.loc[np.random.choice(df.index, 5, replace=False)]
Эта функция новая в 1.7. Если вы хотите решение со старым numpy, вы можете перетасовать данные и первыми элементами этого:
df.loc[np.random.permutation(df.index)[:5]]
Таким образом, DataFrame больше не сортируется, но если это необходимо для plottin (например, для линейного графика), вы можете просто сделать .sort()
впоследствии.
Ответ 2
К сожалению, np.random.choice
для небольших выборок (менее 10% всех строк) выглядит довольно медленным, вам может быть лучше использовать простой образец ol:
from random import sample
df.loc[sample(df.index, 1000)]
Для большого DataFrame (миллион строк) мы видим небольшие образцы:
In [11]: %timeit df.loc[sample(df.index, 10)]
1000 loops, best of 3: 1.19 ms per loop
In [12]: %timeit df.loc[np.random.choice(df.index, 10, replace=False)]
1 loops, best of 3: 1.36 s per loop
In [13]: %timeit df.loc[np.random.permutation(df.index)[:10]]
1 loops, best of 3: 1.38 s per loop
In [21]: %timeit df.loc[sample(df.index, 1000)]
10 loops, best of 3: 14.5 ms per loop
In [22]: %timeit df.loc[np.random.choice(df.index, 1000, replace=False)]
1 loops, best of 3: 1.28 s per loop
In [23]: %timeit df.loc[np.random.permutation(df.index)[:1000]]
1 loops, best of 3: 1.3 s per loop
Но около 10% он получает примерно то же самое:
In [31]: %timeit df.loc[sample(df.index, 100000)]
1 loops, best of 3: 1.63 s per loop
In [32]: %timeit df.loc[np.random.choice(df.index, 100000, replace=False)]
1 loops, best of 3: 1.36 s per loop
In [33]: %timeit df.loc[np.random.permutation(df.index)[:100000]]
1 loops, best of 3: 1.4 s per loop
и если вы отбираете все (не используйте образец!):
In [41]: %timeit df.loc[sample(df.index, 1000000)]
1 loops, best of 3: 10 s per loop
Примечание: оба numpy.random и random принимают семя, чтобы воспроизвести случайно сгенерированный вывод.
Как отмечает @joris в комментариях, выбор (без замены) на самом деле сахар для перестановки, поэтому он не удивляет его постоянным временем и замедлением для небольших образцов...
Ответ 3
В наши дни можно просто использовать метод sample
для DataFrame:
>>> help(df.sample)
Help on method sample in module pandas.core.generic:
sample(self, n=None, frac=None, replace=False, weights=None, random_state=None, axis=None) method of pandas.core.frame.DataFrame instance
Returns a random sample of items from an axis of object.
Репликативность может быть достигнута с помощью ключевого слова random_state
:
>>> len(set(df.sample(n=1, random_state=np.random.RandomState(0)).iterations.values[0] for _ in xrange(1000)))
1
>>> len(set(df.sample(n=1).iterations.values[0] for _ in xrange(1000)))
40