Numpy: Uzyskaj losowy zestaw wierszy z tablicy 2D


160

Mam bardzo dużą tablicę 2D, która wygląda mniej więcej tak:

a=
[[a1, b1, c1],
 [a2, b2, c2],
 ...,
 [an, bn, cn]]

Używając numpy, czy istnieje łatwy sposób na uzyskanie nowej tablicy 2D z np. 2 losowymi wierszami z początkowej tablicy a(bez zamiany)?

na przykład

b=
[[a4,  b4,  c4],
 [a99, b99, c99]]

8
głupio jest mieć pytanie jedno do zastąpienia, a drugie bez, powinieneś po prostu pozwolić na obie odpowiedzi i faktycznie zachęcać do obu odpowiedzi.
Pinokio

Odpowiedzi:


195
>>> A = np.random.randint(5, size=(10,3))
>>> A
array([[1, 3, 0],
       [3, 2, 0],
       [0, 2, 1],
       [1, 1, 4],
       [3, 2, 2],
       [0, 1, 0],
       [1, 3, 1],
       [0, 4, 1],
       [2, 4, 2],
       [3, 3, 1]])
>>> idx = np.random.randint(10, size=2)
>>> idx
array([7, 6])
>>> A[idx,:]
array([[0, 4, 1],
       [1, 3, 1]])

Składając to razem dla ogólnego przypadku:

A[np.random.randint(A.shape[0], size=2), :]

W przypadku produktów niewymiennych (numpy 1.7.0+):

A[np.random.choice(A.shape[0], 2, replace=False), :]

Nie wierzę, że istnieje dobry sposób na wygenerowanie losowej listy bez wymiany przed 1.7. Być może możesz ustawić małą definicję, która zapewni, że te dwie wartości nie będą takie same.


4
Może nie ma dobrego sposobu, ale sposób, który jest tak dobry, jak np.random.choice, i to np.random.permutation(A.shape[0])[:2]właściwie nie jest świetny, ale to jest to, co np.random.choicew tej chwili ... lub jeśli nie chcesz zmieniać swojej tablicy w- miejsce,np.random.shuffle
seberg

1
Przed numpy 1.7 użyj random .sample (xrange (10), 2)
denis

3
dlaczego nazywasz swoje zmienne A i B i tak dalej? utrudnia czytanie.
Pinokio

48

To jest stary post, ale to działa najlepiej dla mnie:

A[np.random.choice(A.shape[0], num_rows_2_sample, replace=False)]

zmień replace = False na True, aby uzyskać to samo, ale z wymianą.


2
@SalvadorDali Zredagowałem post Hezi, aby nie wybierać z wymianą. Gdy zmiana zostanie zweryfikowana, zobaczysz dodany replace=Falseparametr do choice.
0x24a537r9

8
@ 0x24a537r9 nie powinieneś tego robić. To jest jego odpowiedź i ty ją zmieniasz. Jeśli chcesz - dodaj swoją odpowiedź i nie zmieniaj odpowiedzi innych osób, co znacząco zmienia odpowiedź
Salvador Dali

@SalvadorDali, czemu nie?
Scott

25

Inną opcją jest utworzenie losowej maski, jeśli chcesz po prostu zmniejszyć próbkowanie danych o określony czynnik. Powiedzmy, że chcę pobrać próbkowanie do 25% mojego pierwotnego zestawu danych, który jest obecnie przechowywany w tablicy data_arr:

# generate random boolean mask the length of data
# use p 0.75 for False and 0.25 for True
mask = numpy.random.choice([False, True], len(data_arr), p=[0.75, 0.25])

Teraz możesz wywoływać data_arr[mask]i zwracać ~ 25% wierszy, losowo próbkowanych.


Możesz dodać, replace = Falsejeśli nie chcesz próbkowania z wymianą.
Sarah

10

Jest to odpowiedź podobna do tej, którą dostarczył Hezi Rasheff, ale jest uproszczona, dzięki czemu nowi użytkownicy Pythona rozumieją, co się dzieje (zauważyłem, że wielu nowych studentów nauki danych pobiera losowe próbki w najdziwniejszy sposób, ponieważ nie wiedzą, co robią w Pythonie).

Możesz uzyskać wiele losowych indeksów ze swojej tablicy, używając:

indices = np.random.choice(A.shape[0], amount_of_samples, replace=False)

Następnie możesz użyć wycinania z tablicą numpy, aby pobrać próbki w tych indeksach:

A[indices]

Dzięki temu uzyskasz określoną liczbę losowych próbek z Twoich danych.


5

Widzę, że zaproponowano permutację. W rzeczywistości można to zrobić w jednej linii:

>>> A = np.random.randint(5, size=(10,3))
>>> np.random.permutation(A)[:2]

array([[0, 3, 0],
       [3, 1, 2]])


2

Jeśli chcesz wygenerować wiele losowych podzbiorów wierszy, na przykład jeśli wykonujesz RANSAC.

num_pop = 10
num_samples = 2
pop_in_sample = 3
rows_to_sample = np.random.random([num_pop, 5])
random_numbers = np.random.random([num_samples, num_pop])
samples = np.argsort(random_numbers, axis=1)[:, :pop_in_sample]
# will be shape [num_samples, pop_in_sample, 5]
row_subsets = rows_to_sample[samples, :]
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.