Numpy: Ruft einen zufälligen Satz von Zeilen aus dem 2D-Array ab

159

Ich habe ein sehr großes 2D-Array, das ungefähr so ​​aussieht:

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

Gibt es mit numpy eine einfache Möglichkeit, ein neues 2D-Array mit z. B. 2 zufälligen Zeilen aus dem ursprünglichen Array zu erhalten a(ohne Ersatz)?

z.B

b=
[[a4,  b4,  c4],
 [a99, b99, c99]]
gha
quelle
8
Es ist albern, eine Frage zu haben, eine als Ersatz und eine ohne. Sie sollten einfach beide Antworten zulassen und tatsächlich beide Antworten fördern.
Pinocchio

Antworten:

193
>>> 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]])

Zusammenstellen für einen allgemeinen Fall:

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

Bei Nichtersatz (numpy 1.7.0+):

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

Ich glaube nicht, dass es eine gute Möglichkeit gibt, eine zufällige Liste ohne Ersatz vor 1.7 zu erstellen. Vielleicht können Sie eine kleine Definition einrichten, die sicherstellt, dass die beiden Werte nicht gleich sind.

Daniel
quelle
4
Es gibt vielleicht keinen guten Weg, aber einen Weg, der genauso gut ist wie np.random.choice, und das heißt np.random.permutation(A.shape[0])[:2], es ist eigentlich nicht großartig, aber np.random.choicegenau das ist es zu diesem Zeitpunkt ... oder wenn Sie Ihr Array nicht ändern möchten Platz,np.random.shuffle
seberg
1
Verwenden Sie vor numpy 1.7 zufällige .sample (xrange (10), 2)
denis
3
Warum benennst du deine Variablen A und B und so? es macht es schwieriger zu lesen.
Pinocchio
48

Dies ist ein alter Beitrag, aber das funktioniert am besten für mich:

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

Ändern Sie das Ersetzen = Falsch in Wahr, um dasselbe zu erhalten, jedoch mit Ersetzen.

Hezi Resheff
quelle
2
@SalvadorDali Ich habe Hezis Beitrag so bearbeitet, dass er nicht mit Ersatz ausgewählt wird. Sobald die Bearbeitung einer Peer-Review replace=Falseunterzogen wurde, wird der hinzugefügte Parameter angezeigt choice.
0x24a537r9
8
@ 0x24a537r9 sollten Sie dies nicht tun. Dies ist seine Antwort und Sie ändern sie. Wenn Sie möchten - fügen Sie Ihre Antwort hinzu und ändern Sie nicht die Antworten anderer Personen, die die Antwort erheblich verändern
Salvador Dali
@SalvadorDali warum nicht?
Scott
25

Eine andere Möglichkeit besteht darin, eine zufällige Maske zu erstellen, wenn Sie Ihre Daten nur um einen bestimmten Faktor reduzieren möchten. Angenommen, ich möchte auf 25% meines ursprünglichen Datensatzes, der sich derzeit im Array befindet, ein Downsampling durchführen 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])

Jetzt können Sie data_arr[mask]~ 25% der Zeilen nach dem Zufallsprinzip aufrufen und zurückgeben.

gleichschenkliges Rad
quelle
10

Dies ist eine ähnliche Antwort wie die von Hezi Rasheff, aber vereinfacht, damit neuere Python-Benutzer verstehen, was los ist (ich habe festgestellt, dass viele neue Studenten der Datenwissenschaft auf seltsamste Weise Zufallsstichproben abrufen, weil sie nicht wissen, was sie in Python tun).

Sie können eine Reihe von Zufallsindizes aus Ihrem Array abrufen, indem Sie Folgendes verwenden:

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

Sie können dann das Slicing mit Ihrem Numpy-Array verwenden, um die Samples an diesen Indizes zu erhalten:

A[indices]

Dadurch erhalten Sie die angegebene Anzahl von Zufallsstichproben aus Ihren Daten.

CB Madsen
quelle
5

Wenn Sie die gleichen Zeilen, aber nur eine Zufallsstichprobe benötigen, dann

import random
new_array = random.sample(old_array,x)

Hier muss x ein 'int' sein, das die Anzahl der Zeilen definiert, die Sie zufällig auswählen möchten.

Ankit Agrawal
quelle
3
Dies funktioniert nur, wenn old_arrayes sich um eine Sequenz oder eine Menge handelt, nicht um ein numpy-Array [link] ( docs.python.org/3/library/random.html#functions-for-sequences )
leermeester
5

Ich sehe, dass eine Permutation vorgeschlagen wurde. In der Tat kann es in einer Zeile gemacht werden:

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

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

Wenn Sie mehrere zufällige Teilmengen von Zeilen generieren möchten, z. B. wenn Sie RANSAC ausführen.

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, :]
Ben
quelle