在对每个数组进行更改时迭代数组列表

时间:2018-03-01 22:46:44

标签: python arrays python-3.x numpy for-loop

这是我之前的一个问题的后续帖子:Referring to arrays in a for-loop

我想概括那里提出的解决方案,以便能够完成更复杂的任务,例如将列附加到包含某些计算结果的每个数组:

import numpy as np
list=[one, two, three]

for arr in list:
    arr=np.column_stack([arr,5*arr[:,2]-arr[:,1])])

所有三个阵列都具有相同的尺寸。

4 个答案:

答案 0 :(得分:2)

In [59]: one=np.arange(6).reshape(2,3)
In [60]: two=np.arange(6).reshape(2,3)

暂时忘掉循环,然后尝试更改one

In [61]: arr = one
In [62]: arr=np.column_stack([arr,5*arr[:,2]-arr[:,1]])
In [63]: arr
Out[63]: 
array([[ 0,  1,  2,  9],
       [ 3,  4,  5, 21]])
In [65]: one
Out[65]: 
array([[0, 1, 2],
       [3, 4, 5]])

此操作已更改arr,但未更改one。最初arr引用了与ndarray相同的对象(one),但在新赋值之后,它引用了一个新数组。

for arr in alist:
    arr = ....

arr被分配了alist元素。但是在循环中,它会被分配另一个别的东西,而不会改变原始对象。在下一次迭代中,arr被分配列表中的下一个元素,依此类推。

你需要记住几件事。

  • Python如何为变量赋值
  • Python如何将值分配给迭代变量
  • column_stack
  • 等功能

在上一个问题中

In [69]: for arg in [one,two]:
    ...:     arg[:,1:] += 10
    ...:     
In [70]: one
Out[70]: 
array([[ 0, 11, 12],
       [ 3, 14, 15]])
In [71]: two
Out[71]: 
array([[ 0, 11, 12],
       [ 3, 14, 15]])

这是有效的,因为arg[:,1:] += 10正在修改当前分配给arg的数组。数组是mutable;元素值可以就地更改。

np.column_stack()不会就地行动。它创造了新阵列。

关于使用列表更改onetwo的唯一方法是一系列操作,例如:

In [72]: newlist=[np.column_stack([arr,5*arr[:,2]-arr[:,1]]) for arg in [one,two]]
In [73]: newlist
Out[73]: 
[array([[ 0,  1,  2,  9,  9],
        [ 3,  4,  5, 21, 21]]), array([[ 0,  1,  2,  9,  9],
        [ 3,  4,  5, 21, 21]])]
In [74]: one
Out[74]: 
array([[ 0, 11, 12],
       [ 3, 14, 15]])
In [75]: one, two = newlist
In [76]: one
Out[76]: 
array([[ 0,  1,  2,  9,  9],
       [ 3,  4,  5, 21, 21]])

In[72]使用新数组创建一个新列表。 In[75]将这些新数组分配给变量onetwo。这抹去了他们以前的参考文献。实际上,我执行了one=[np.column_stack([one,5*one[:,2]-one[:,1]]),同样适用于two

答案 1 :(得分:1)

分配给变量不会更新列表,它只是对数组中值的临时引用。

使用enumerate获取列表索引,然后您可以将其替换为结果。

for index, arr in enumerate(myList):
    myList[index] = np.column_stack([arr,5*arr[:,2]-arr[:,1])])

另外,避免使用内置类和函数的名称作为您自己的变量名。 list是标准类。

答案 2 :(得分:1)

不要忘记在Python中,变量是对值的引用。迭代变量是一个变量,因此为此变量赋值不会改变迭代。

在这种情况下,为什么不使用列表推导?

<w:pPr>
    <w:b />
    <w:sz w:val="36" />
    <w:szCs w:val="36" />
</w:pPr>

请不要影import numpy as np my_list = [one, two, three] my_list = [np.column_stack([arr,5*arr[:,2]-arr[:,1])]) for arr in list] 类型......

答案 3 :(得分:0)

我担心您引用的解决方案只能推广到数组的就地更改。任何改变大小的东西都会让AFAIK创建一个新阵列。

所以这个

>>> X,Y,Z = (np.arange(i+1, i+10, dtype=float).reshape(3, 3) for i in range(3))
>>> L = [X,Y,Z]
>>> for arr in L:
...    np.sin(arr, out=arr)

或者

>>> for arr in L:
...     arr[1] = arr[1, ::-1]

会奏效。

您甚至可以替换整个阵列,只要您就地进行:

>>> for arr in L:
...     arr[...] = 1.7

但是这个

>>> for arr in L:
...    np.append(arr, arr[-1])

不会更改原始数组但会创建新数组。分配回arr无济于事,因为它只是将名称arr重新绑定到新对象。