Самый быстрый способ вырастить массив NumPy из другого массива NumPy, содержащего индексы выбора

#python #numpy #numpy-ndarray

#питон #numpy #numpy-ndarray

Вопрос:

Я должен создать большой массив из известного, используя набор индексов исходного массива. Индексы хранятся в виде ndarray, и для создания нового массива я делаю что-то вроде этого:

 import numpy as np

dim_1       = 200
high_index  = 1000 
dim_2       = 300

masks_array = np.random.randint( low = 0, high = high_index - 1, size=(high_index, dim_1) )
the_array   = np.random.rand( high_index, dim_2 )

new_array   = np.array( [ the_array[ masks_array[ j, : ], :  ] for j in range(high_index) ]  )
 

Это самый быстрый способ сгенерировать new_array из masks_array? Есть ли способ сделать это без цикла? И из интереса, поскольку цикл «for» находится внутри конструктора np.array, преобразуется ли это в эффективный цикл в Python (аналогично пониманию списка)?

Комментарии:

1. Подводя итог, вы хотите создать новую матрицу, the_array используя индексы, приведенные в masks_array ?

Ответ №1:

 In [198]: dim_1       = 200
     ...: high_index  = 1000
     ...: dim_2       = 300
     ...: 
     ...: masks_array = np.random.randint( low = 0, high = high_index - 1, size=
     ...: (high_index, dim_1) )
     ...: the_array   = np.random.rand( high_index, dim_2 )
     ...: 
     ...: new_array   = np.array( [ the_array[ masks_array[ j, : ], :  ] for j i
     ...: n range(high_index) ]  )
In [199]: new_array.shape
Out[199]: (1000, 200, 300)
In [200]: masks_array.shape
Out[200]: (1000, 200)
In [201]: the_array.shape
Out[201]: (1000, 300)
 

Давайте попробуем простое индексирование с помощью masks_array :

 In [205]: arr = the_array[masks_array,:]
In [206]: arr.shape
Out[206]: (1000, 200, 300)
In [207]: np.allclose(new_array, arr)
Out[207]: True
 

Сравнение времени:

 In [213]: timeit new_array = np.array([the_array[masks_array[j,:],:] for j in ra
     ...: nge(high_index)])
658 ms ± 17.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [214]: timeit arr = the_array[masks_array,:]
292 ms ± 65.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
 

Я подозреваю, что экономия времени невелика из-за большого общего размера результата.

Это python и np.array является функцией. Итак

 [the_array[masks_array[j,:],:] for j in range(high_index)] 
 

сначала вычисляется, а затем передается в `np.array.

 In [215]: timeit [the_array[masks_array[j,:],:] for j in range(high_index)]
369 ms ± 7.94 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)