Подмножество 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