tamaƱo que por ordenar matriz matrices hacer ejemplos como columnas columna bidimensionales arreglos arreglo array python arrays numpy shuffle

por - que es un array en python



Numpy shuffle matriz multidimensional solo por fila, mantener el orden de las columnas sin cambios (3)

Después de un pequeño experimento, encontré que la mayor parte de la memoria y la forma más eficiente en el tiempo de barajar los datos (en cuanto a la fila) de nd-array es, barajan el índice y obtienen los datos del índice barajado

rand_num2 = np.random.randint(5, size=(6000, 2000)) perm = np.arange(rand_num2.shape[0]) np.random.shuffle(perm) rand_num2 = rand_num2[perm]

en mas detalles
Aquí, estoy usando memory_profiler para encontrar el uso de la memoria y el módulo incorporado de "tiempo" de python para registrar el tiempo y comparar todas las respuestas anteriores

def main(): # shuffle data itself rand_num = np.random.randint(5, size=(6000, 2000)) start = time.time() np.random.shuffle(rand_num) print(''Time for direct shuffle: {0}''.format((time.time() - start))) # Shuffle index and get data from shuffled index rand_num2 = np.random.randint(5, size=(6000, 2000)) start = time.time() perm = np.arange(rand_num2.shape[0]) np.random.shuffle(perm) rand_num2 = rand_num2[perm] print(''Time for shuffling index: {0}''.format((time.time() - start))) # using np.take() rand_num3 = np.random.randint(5, size=(6000, 2000)) start = time.time() np.take(rand_num3, np.random.rand(rand_num3.shape[0]).argsort(), axis=0, out=rand_num3) print("Time taken by np.take, {0}".format((time.time() - start)))

Resultado para el tiempo

Time for direct shuffle: 0.03345608711242676 # 33.4msec Time for shuffling index: 0.019818782806396484 # 19.8msec Time taken by np.take, 0.06726956367492676 # 67.2msec

Perfilador de memoria Resultado

Line # Mem usage Increment Line Contents ================================================ 39 117.422 MiB 0.000 MiB @profile 40 def main(): 41 # shuffle data itself 42 208.977 MiB 91.555 MiB rand_num = np.random.randint(5, size=(6000, 2000)) 43 208.977 MiB 0.000 MiB start = time.time() 44 208.977 MiB 0.000 MiB np.random.shuffle(rand_num) 45 208.977 MiB 0.000 MiB print(''Time for direct shuffle: {0}''.format((time.time() - start))) 46 47 # Shuffle index and get data from shuffled index 48 300.531 MiB 91.555 MiB rand_num2 = np.random.randint(5, size=(6000, 2000)) 49 300.531 MiB 0.000 MiB start = time.time() 50 300.535 MiB 0.004 MiB perm = np.arange(rand_num2.shape[0]) 51 300.539 MiB 0.004 MiB np.random.shuffle(perm) 52 300.539 MiB 0.000 MiB rand_num2 = rand_num2[perm] 53 300.539 MiB 0.000 MiB print(''Time for shuffling index: {0}''.format((time.time() - start))) 54 55 # using np.take() 56 392.094 MiB 91.555 MiB rand_num3 = np.random.randint(5, size=(6000, 2000)) 57 392.094 MiB 0.000 MiB start = time.time() 58 392.242 MiB 0.148 MiB np.take(rand_num3, np.random.rand(rand_num3.shape[0]).argsort(), axis=0, out=rand_num3) 59 392.242 MiB 0.000 MiB print("Time taken by np.take, {0}".format((time.time() - start)))

¿Cómo puedo mezclar una matriz multidimensional por fila solo en Python (así que no mezcle las columnas)?

Estoy buscando la solución más eficiente, porque mi matriz es muy grande. ¿También es posible hacer esto altamente eficiente en la matriz original (para ahorrar memoria)?

Ejemplo:

import numpy as np X = np.random.random((6, 2)) print(X) Y = ???shuffle by row only not colls??? print(Y)

Lo que espero ahora es matriz original:

[[ 0.48252164 0.12013048] [ 0.77254355 0.74382174] [ 0.45174186 0.8782033 ] [ 0.75623083 0.71763107] [ 0.26809253 0.75144034] [ 0.23442518 0.39031414]]

La salida baraja las filas no cols por ejemplo:

[[ 0.45174186 0.8782033 ] [ 0.48252164 0.12013048] [ 0.77254355 0.74382174] [ 0.75623083 0.71763107] [ 0.23442518 0.39031414] [ 0.26809253 0.75144034]]


Para eso es numpy.random.shuffle() :

>>> X = np.random.random((6, 2)) >>> X array([[ 0.9818058 , 0.67513579], [ 0.82312674, 0.82768118], [ 0.29468324, 0.59305925], [ 0.25731731, 0.16676408], [ 0.27402974, 0.55215778], [ 0.44323485, 0.78779887]]) >>> np.random.shuffle(X) >>> X array([[ 0.9818058 , 0.67513579], [ 0.44323485, 0.78779887], [ 0.82312674, 0.82768118], [ 0.29468324, 0.59305925], [ 0.25731731, 0.16676408], [ 0.27402974, 0.55215778]])


También puede usar np.random.permutation para generar permutación aleatoria de índices de fila y luego indexar en las filas de X usando np.take con axis=0 . Además, np.take facilita la sobrescritura a la matriz de entrada X con out= opción out= , lo que nos ahorraría memoria. Por lo tanto, la implementación se vería así:

np.take(X,np.random.permutation(X.shape[0]),axis=0,out=X)

Ejecución de la muestra

In [23]: X Out[23]: array([[ 0.60511059, 0.75001599], [ 0.30968339, 0.09162172], [ 0.14673218, 0.09089028], [ 0.31663128, 0.10000309], [ 0.0957233 , 0.96210485], [ 0.56843186, 0.36654023]]) In [24]: np.take(X,np.random.permutation(X.shape[0]),axis=0,out=X); In [25]: X Out[25]: array([[ 0.14673218, 0.09089028], [ 0.31663128, 0.10000309], [ 0.30968339, 0.09162172], [ 0.56843186, 0.36654023], [ 0.0957233 , 0.96210485], [ 0.60511059, 0.75001599]])

Mejora adicional del rendimiento

Aquí hay un truco para acelerar np.random.permutation(X.shape[0]) con np.argsort() -

np.random.rand(X.shape[0]).argsort()

Resultados de aceleración -

In [32]: X = np.random.random((6000, 2000)) In [33]: %timeit np.random.permutation(X.shape[0]) 1000 loops, best of 3: 510 µs per loop In [34]: %timeit np.random.rand(X.shape[0]).argsort() 1000 loops, best of 3: 297 µs per loop

Por lo tanto, la solución de barajado podría ser modificada a

np.take(X,np.random.rand(X.shape[0]).argsort(),axis=0,out=X)

Pruebas de tiempo de ejecución

Estas pruebas incluyen los dos enfoques enumerados en esta publicación y uno basado en @Kasramvd''s solution .

In [40]: X = np.random.random((6000, 2000)) In [41]: %timeit np.random.shuffle(X) 10 loops, best of 3: 25.2 ms per loop In [42]: %timeit np.take(X,np.random.permutation(X.shape[0]),axis=0,out=X) 10 loops, best of 3: 53.3 ms per loop In [43]: %timeit np.take(X,np.random.rand(X.shape[0]).argsort(),axis=0,out=X) 10 loops, best of 3: 53.2 ms per loop

Por lo tanto, parece que el uso de estos np.take podría usar solo si la memoria es una preocupación o si np.random.shuffle , la solución basada en np.random.shuffle parece ser el camino a seguir.