Losowy wybór wierszy w ramce danych Pandas

159

Czy istnieje sposób na wybranie losowych wierszy z DataFrame w Pandas.

W R, korzystając z pakietu samochodowego, jest przydatna funkcja, some(x, n)która jest podobna do head, ale w tym przykładzie wybiera losowo 10 wierszy z x.

Przejrzałem również dokumentację dotyczącą wycinania i wydaje się, że nie ma nic równoważnego.

Aktualizacja

Teraz korzystam z wersji 20. Istnieje przykładowa metoda.

df.sample(n)

Jan
źródło
1
Jeśli szukasz próbki, której rozmiar jest większy niż oryginał, użyj df.sample(N, replace=True). Więcej szczegółów tutaj .
cs95,

Odpowiedzi:

57

Coś takiego?

import random

def some(x, n):
    return x.ix[random.sample(x.index, n)]

Uwaga: od wersji 0.20.0 Pandas ix został wycofany na korzyść locindeksowania na podstawie etykiet.

eumiro
źródło
8
Dzięki @eumiro. Opracowałem też, że df.ix[np.random.random_integers(0, len(df), 10)]to też zadziała.
John,
7
Jeśli chcesz używać numpy, możesz też to zrobić df.ix[np.random.choice(df.index, 10)].
naught101
7
Ktoś w innym poście wspomniał, że np.random.choicejest dwa razy szybszy niżrandom.sample
Phani
5
Jeśli używasz np.random.choice, musisz określić replace = False, w przeciwnym razie otrzymasz zduplikowane wiersze!
stmax
2
Myślę, że „.ix” jest przestarzały i do indeksowania opartego na etykietach należy używać rozszerzenia .loc
compguy24,
266

W przypadku wersji pandy 0.16.1i nowszych jest teraz DataFrame.sample wbudowana metoda :

import pandas

df = pandas.DataFrame(pandas.np.random.random(100))

# Randomly sample 70% of your dataframe
df_percent = df.sample(frac=0.7)

# Randomly sample 7 elements from your dataframe
df_elements = df.sample(n=7)

W przypadku obu powyższych metod pozostałe wiersze można uzyskać, wykonując:

df_rest = df.loc[~df.index.isin(df_percent.index)]
ryanjdillon
źródło
df_0.7nie jest prawidłową nazwą. Ponadto, proponuję zastąpienie df_rest = df.loc[~df.index.isin(df_0_7.index)]z df_rest = df.loc[df.index.difference(df_0_7.index)].
Pietro Battiston
@PietroBattiston Thanks. Próbowałem wyjaśnić odpowiedź, ale zgadzam się, że niedziałający przykład nie jest jasny. Miło ze wskazówką dotyczącą różnicy. Chociaż nadal wolę pisać wycinanie tak, aby odczytywać je jako indeksy „nie w indeksie mojej próbki”. Czy jest wzrost wydajności z difference()?
ryanjdillon
1
@ryanjdillon pozostała literówka, poprawiłem ją. Jeśli chodzi o metodę, faktycznie cofam swoją sugestię, ponieważ jest ona nieco mniej wydajna. df_percent.index.get_indexer(df.index) == -1jest o wiele bardziej wydajny (ale też brzydszy) ...
Pietro Battiston
18

sample

Od wersji 0. 20.0 można użyć pd.DataFrame.sample, który może służyć do zwracania losowej próbki o stałej liczbie wierszy lub odsetku wierszy:

df = df.sample(n=k)     # k rows
df = df.sample(frac=k)  # int(len(df.index) * k) rows

Aby random_statezapewnić odtwarzalność, możesz określić liczbę całkowitą , równoważną użyciu np.ramdom.seed. Tak więc zamiast ustawiania np.random.seed = 0, możesz na przykład :

df = df.sample(n=k, random_state=0)
jpp
źródło
7

Najlepszym sposobem na to jest użycie funkcji próbki z modułu random,

import numpy as np
import pandas as pd
from random import sample

# given data frame df

# create random index
rindex =  np.array(sample(xrange(len(df)), 10))

# get 10 random rows from df
dfr = df.ix[rindex]
rlmlr
źródło
4

Właściwie to da ci powtarzające się indeksy, np.random.random_integers(0, len(df), N)gdzie Njest duża liczba.

rlmlr
źródło
3

Poniższy wiersz losowo wybierze n liczbę wierszy spośród wszystkich istniejących numerów wierszy z ramki danych df bez zastępowania.

df=df.take(np.random.permutation(len(df))[:n])

Mojgan Mazouchi
źródło