当迭代数组用作子数组
时,在 np.nditer 内部的赋值方法期间主数组不会更新值array = np.arange(20)
with np.nditer(array[np.nonzero(array)],
op_flags=['readwrite']) as it:
for x in it:
x[...] = 5
array
array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19])
在没有 np.nditer
的情况下,子数组分配出色array[np.nonzero(array)] = 5
array
array([0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5])
使用临时数组可以解决此问题。
tmp_array = array[np.nonzero(array)]
array = np.arange(20)
with np.nditer(tmp_array,
op_flags=['readwrite']) as it:
for x in it:
x[...] = 5
array[np.nonzero(array)] = tmp_array
array
array([0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5])
答案 0 :(得分:1)
In [48]: arr = np.arange(20)
...: with np.nditer(arr[np.nonzero(arr)],
...: op_flags=['readwrite']) as it:
...: for x in it:
...: x[...] = 5
...: arr
Out[48]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19])
这不会更改arr
,因为它没有在arr
上进行迭代。相反,它在做:
In [49]: arr = np.arange(20)
...: arr1 = arr[np.nonzero(arr)]
...: with np.nditer(arr1,
...: op_flags=['readwrite']) as it:
...: for x in it:
...: x[...] = 5
...: arr1
Out[49]: array([5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5])
In [50]: _.shape
Out[50]: (19,)
arr1
不是view
的{{1}},它是一个选择,一个没有共享数据缓冲区的新数组。
如果要修改arr
,则必须对其进行迭代,而不是副本。在循环内进行测试或任何其他幻想。
arr
但是为什么要使用In [51]: arr = np.arange(20)
...: with np.nditer(arr,
...: op_flags=['readwrite']) as it:
...: for x in it:
...: if x > 0:
...: x[...] = 5
...: arr
Out[51]: array([0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5])
?您已经知道如何使用非迭代方法进行这种选择性分配:
nditer
在这种情况下,分配array[np.nonzero(array)] = 5
紧随高级索引之后,Python使用=
而不是array.__setitem__
。
在切片上进行迭代,arr.__getitem__
确实会更改源:
view