2 votes

Créer une matrice Numpy stockant des versions mélangées d'un tableau nd en entrée.

J'ai un tableau 2d ndarray appelé weights de forme (npts, nweights). Pour chaque colonne de weights je souhaite mélanger les rangées de manière aléatoire. Je veux répéter ce processus num_shuffles et stocke la collection de mélanges dans un tableau de 3d ndarray appelé weights_matrix . Il est important de noter que pour chaque itération de brassage, les indices de brassage de chaque colonne de weights devraient être les mêmes.

Ci-dessous figure une implémentation naïve explicite de cet algorithme en double pour boucle. Est-il possible d'éviter les boucles de python et de générer weights_matrix en Numpy pur ?

import numpy as np 
npts, nweights = 5, 2
weights = np.random.rand(npts*nweights).reshape((npts, nweights))

num_shuffles = 3
weights_matrix = np.zeros((num_shuffles, npts, nweights))
for i in range(num_shuffles):
    indx = np.random.choice(np.arange(npts), npts, replace=False)
    for j in range(nweights):
        weights_matrix[i, :, j] = weights[indx, j]

1voto

jez Points 7252

Vous pouvez commencer par remplir votre tableau 3-D avec des copies des poids d'origine, puis effectuer une simple itération sur des tranches de ce tableau 3-D, en utilisant la fonction numpy.random.shuffle pour mélanger chaque tranche 2-D en place.

Pour chaque colonne de poids, je souhaite mélanger les rangées de manière aléatoire... les indices de mélange de chaque colonne de poids doivent être identiques.

n'est qu'une autre façon de dire "Je veux réorganiser de façon aléatoire les lignes d'un tableau 2D". numpy.random.shuffle est une version compatible avec les tableaux numpy de random.shuffle il réorganisera les éléments d'un conteneur sur place. Et c'est tout ce dont vous avez besoin, puisque les "éléments" d'un tableau numpy 2-D, dans ce sens, sont ses rangées.

import numpy
weights = numpy.array( [ [ 1, 2, 3 ], [ 4, 5, 6], [ 7, 8, 9 ] ] )
weights_3d = weights[ numpy.newaxis, :, : ].repeat( 10, axis=0 )

for w in weights_3d:
    numpy.random.shuffle( w )  # in-place shuffle of the rows of each slice

print( weights_3d[0, :, :] )
print( weights_3d[1, :, :] )
print( weights_3d[2, :, :] )

1voto

Divakar Points 20144

Voici une solution vectorisée dont l'idée est empruntée à this post -

weights[np.random.rand(num_shuffles,weights.shape[0]).argsort(1)]

Exemple d'exécution -

In [28]: weights
Out[28]: 
array([[ 0.22508764,  0.8527072 ],
       [ 0.31504052,  0.73272155],
       [ 0.73370203,  0.54889059],
       [ 0.87470619,  0.12394942],
       [ 0.20587307,  0.11385946]])

In [29]: num_shuffles = 3

In [30]: weights[np.random.rand(num_shuffles,weights.shape[0]).argsort(1)]
Out[30]: 
array([[[ 0.87470619,  0.12394942],
        [ 0.20587307,  0.11385946],
        [ 0.22508764,  0.8527072 ],
        [ 0.31504052,  0.73272155],
        [ 0.73370203,  0.54889059]],

       [[ 0.87470619,  0.12394942],
        [ 0.22508764,  0.8527072 ],
        [ 0.73370203,  0.54889059],
        [ 0.20587307,  0.11385946],
        [ 0.31504052,  0.73272155]],

       [[ 0.73370203,  0.54889059],
        [ 0.31504052,  0.73272155],
        [ 0.22508764,  0.8527072 ],
        [ 0.20587307,  0.11385946],
        [ 0.87470619,  0.12394942]]])

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X