Какая потребность в многоточии [] при изменении значений массива в numpy?

import numpy as np                
a = np.arange(0,60,5)            
a = a.reshape(3,4)                                    

for x in np.nditer(a, op_flags = ['readwrite']):          
   x[...] = 2*x              
print 'Modified array is:'              
print a

Почему в приведенном выше коде мы не можем просто написать x=2*x вместо x[...]=2*x?


person Kushagra Sharma    schedule 02.09.2018    source источник
comment
Если вы напишите x = 2*x внутри этого цикла, вы просто создадите новую переменную x (отличную от той, которая получена в результате итерации) и присвоите ей результат. С x[...] = 2*x вы изменяете x напрямую. Вы можете проверить этот пост.   -  person ayhan    schedule 02.09.2018
comment
@ user2285236: x = 2*x не создает новую переменную. Просто переменная — это не то, что нам нужно изменить. Присвоение переменной нам не помогает.   -  person user2357112 supports Monica    schedule 02.09.2018
comment
Что не так с этим вопросом, что кто-то проголосовал за него?   -  person Wojciech Kaczmarek    schedule 02.09.2018
comment
Если вы новичок, не тратьте много времени на nditer. Сосредоточьтесь на операциях с целым массивом, например b=2*a. Даже когда вы должны использовать итерацию, это не самый быстрый или простой способ.   -  person hpaulj    schedule 02.09.2018
comment
Основное руководство nditer, docs.scipy.org/doc/numpy/reference /arrays.nditer.html будет наиболее полезен, если вы прочитаете его до конца и поэкспериментируете с портом cython. В противном случае вы получите ложное представление о его полезности.   -  person hpaulj    schedule 02.09.2018
comment
См. также stackoverflow.com/q/42190783.   -  person hpaulj    schedule 04.09.2018


Ответы (1)


Независимо от того, какой тип объекта мы перебирали или как этот объект был реализован, для x = 2*x было бы почти невозможно сделать что-либо полезное для этого объекта. x = 2*x — это присвоение переменной x; даже если предыдущее содержимое переменной x было получено путем итерации по некоторому объекту, новое присвоение x не повлияет на объект, который мы итерируем.

В этом конкретном случае при переборе массива NumPy с np.nditer(a, op_flags = ['readwrite']) каждая итерация цикла устанавливает x в нульмерный массив, который является доступным для записи представлением ячейки a. x[...] = 2*x записывает в содержимое нульмерного массива, а не перепривязывает переменную x. Поскольку массив представляет собой представление ячейки a, это присваивание записывается в соответствующую ячейку a.

Это очень похоже на разницу между l = [] и l[:] = [] с обычными списками, где l[:] = [] очистит существующий список, а l = [] заменит список новым, пустым списком без изменения исходного. Однако списки не поддерживают представления или нульмерные списки.

person user2357112 supports Monica    schedule 02.09.2018
comment
Тот факт, что x равен 0d и требует x[..,] вместо x[:], является частью того, почему nditer не подходит для новичков. - person hpaulj; 02.09.2018