Получение одинакового значения для всей строки с помощью numpy add.at - PullRequest
0 голосов
/ 07 мая 2020

Мой вопрос заключается в следующем: для 2-мерного массива длиной в пару миллионов np.add.at будет быстрее, чем простая итерация над for?

R будет 2- d массив значений, что-то вроде [[17 1], [23, 10] ...], а nArray - это матрица 25x25, которая инициализируется с помощью np.zeros, поэтому она содержит только нули (все значения в R находятся между 0 и 24, поэтому ошибок нет)

for point in R:
    nArray[tuple(point)] += 1

Проблема, с которой я столкнулся с np.add.at, заключается в том, что вместо получения тех же результатов у меня одинаковое значение для всех ячеек строки. Строка 0 -> 35525 35525 ... 35525

Строка 1 -> 2078 2078 ... 2078

И это значение не то же самое, что в первом столбце соответствующей строки в первой реализации

np.add.at(nArray, R, 1)

Ответы [ 2 ]

0 голосов
/ 07 мая 2020
In [182]: R = np.random.randint(0,25,(100,2)) 

In [197]: A0=np.zeros((25,25),int)                                                                     
In [198]: for point in R: A0[tuple(point)] += 1                                                        
In [199]: A1=np.zeros((25,25),int)                                                                     
In [200]: np.add.at(A1,(R[:,0],R[:,1]),1)                                                              
In [201]: np.allclose(A0,A1)                                                                           
Out[201]: True

Я использовал (R[:,0],R[:,1]) вместо R, потому что в документах говорится:

Если первый операнд имеет несколько измерений, индексы могут быть кортежем массива, как объекты индекса или объекты среза .

По поводу вашего tolist исправления:

In [216]: A2=np.zeros((25,25),int)                                                                     
In [217]: np.add.at(A2,R.T.tolist(),1)                                                                 
/usr/local/bin/ipython3:1: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
  #!/usr/bin/python3
In [218]: np.allclose(A0,A2)                                                                           
Out[218]: True
In [219]: A2=np.zeros((25,25),int)                                                                     
In [220]: np.add.at(A2,tuple(R.T.tolist()),1)                                                          
In [221]: np.allclose(A0,A2)                                                                           
Out[221]: True

In [208]: np.__version__                                                                               
Out[208]: '1.18.2'
0 голосов
/ 07 мая 2020

По-видимому, это происходит только в том случае, если R является массивом numpy, если он сначала преобразован в список (например, с помощью .tolist ()), он работает так, как должен

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...