Numpy: Obtenez un ensemble aléatoire de lignes à partir d'un tableau 2D


160

J'ai un très grand tableau 2D qui ressemble à ceci:

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

En utilisant numpy, existe-t-il un moyen simple d'obtenir un nouveau tableau 2D avec, par exemple, 2 lignes aléatoires du tableau initial a(sans remplacement)?

par exemple

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

8
c'est idiot d'avoir une question une pour le remplacement et une sans, vous devriez simplement permettre les deux réponses et en fait encourager les deux réponses.
Pinocchio

Réponses:


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

Mettre en place pour un cas général:

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

Pour non remplacement (numpy 1.7.0+):

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

Je ne pense pas qu'il existe un bon moyen de générer une liste aléatoire sans remplacement avant la 1.7. Vous pouvez peut-être configurer une petite définition qui garantit que les deux valeurs ne sont pas les mêmes.


4
Il n'y a peut-être pas un bon moyen, mais un moyen qui est tout aussi bon que np.random.choice, et qui est np.random.permutation(A.shape[0])[:2], en fait, ce n'est pas génial, mais c'est ce qui se passe np.random.choiceen ce moment ... ou si vous ne vous souciez pas de changer votre tableau en place,np.random.shuffle
seberg

1
Avant numpy 1.7, utilisez random .sample (xrange (10), 2)
denis

3
pourquoi nommez-vous vos variables A et B et tout? cela rend la lecture plus difficile.
Pinocchio

48

C'est un ancien article, mais c'est ce qui fonctionne le mieux pour moi:

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

changez le replace = False en True pour obtenir la même chose, mais avec remplacement.


2
@SalvadorDali J'ai édité le message de Hezi pour ne pas choisir le remplacement. Une fois la modification révisée par les pairs, vous verrez le replace=Falseparamètre ajouté à choice.
0x24a537r9

8
@ 0x24a537r9 vous ne devriez pas faire cela. C'est sa réponse et vous la changez. Si vous voulez - ajoutez votre réponse et ne changez pas les réponses d'autres personnes qui modifie considérablement la réponse
Salvador Dali

@SalvadorDali pourquoi pas?
Scott le

25

Une autre option consiste à créer un masque aléatoire si vous souhaitez simplement sous-échantillonner vos données d'un certain facteur. Dites que je veux sous-échantillonner à 25% de mon ensemble de données d'origine, qui est actuellement contenu dans le tableau 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])

Vous pouvez désormais appeler data_arr[mask]et renvoyer ~ 25% des lignes, échantillonnées au hasard.


Vous pouvez ajouter replace = Falsesi vous ne voulez pas d'échantillonnage avec remplacement.
Sarah il y a

@Sarah Replacement n'est pas un problème avec cette méthode d'échantillonnage car une valeur True / False est renvoyée pour chaque position dans data_arr. Dans mon exemple, environ 25% des positions seront aléatoires Trueet ces positions sont échantillonnées data_arr.
roue isocèle

10

C'est une réponse similaire à celle fournie par Hezi Rasheff, mais simplifiée pour que les nouveaux utilisateurs de python comprennent ce qui se passe (j'ai remarqué que de nombreux nouveaux étudiants en science des données récupèrent des échantillons aléatoires de la manière la plus étrange car ils ne savent pas ce qu'ils font en python).

Vous pouvez obtenir un certain nombre d'indices aléatoires de votre tableau en utilisant:

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

Vous pouvez ensuite utiliser le découpage avec votre tableau numpy pour obtenir les échantillons à ces indices:

A[indices]

Cela vous permettra d'obtenir le nombre spécifié d'échantillons aléatoires à partir de vos données.


5

Je vois que la permutation a été suggérée. En fait, il peut être composé d'une seule ligne:

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

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


2

Si vous souhaitez générer plusieurs sous-ensembles aléatoires de lignes, par exemple si vous faites 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, :]
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.