我有多个numpy蒙面数组arr0, arr1, ..., arrn
。
我把它们放在arrs = [arr0, ..., arrn]
列表中。
我想展平这些阵列并在它们上面放一个面具。我做了类似的事情:
for arr in arrs:
arr = np.ravel(arr)
arr[mask] = ma.masked
我不明白Python何时制作副本以及它何时只是一个指针。这个for
循环不会展平arr0, ..., arrn
,(虽然ravel输出一个视图而不是一个副本)它只是展平变量arr
,虽然它确实改变了它们的掩码!
据我了解,arr
是列表arrs
中元素的视图,因此当我更改arr
的元素时,它会更改列表中相应数组的元素。但是,当我为arr
分配一个新值时,它不会更改原始数组,即使该分配应该是该数组的视图。为什么?
使用示例编辑:
阵容变平:
arr0 = masked_array(data=[[1,2],[3,4]], mask=False)
arr1 = masked_array(data=[[5,6],[7,8]], mask=False)
mask = [[False,True],[True,False]]
预期产出:
arr0 = masked_array(data=[[1,--],[--,4]], mask=[[False,True],[True,False]])
arr1 = masked_array(data=[[5,--],[--,8]], mask=[[False,True],[True,False]])
我想在循环中执行此操作,因为我有很多数组(15或更少),我想在代码中使用数组名称。没有其他办法可以做到:
arr0 = np.ravel(arr0)
...
arrn = np.ravel(arrn)
答案 0 :(得分:0)
In [1032]: arr0 = np.ma.masked_array(data=[[1,2],[3,4]], mask=False)
In [1033]: arr1 = np.ma.masked_array(data=[[5,6],[7,8]], mask=False)
这是迭代列表,对每个元素应用一些操作,并将结果收集到另一个列表中的基本方法:
In [1037]: ll=[arr0,arr1]
In [1038]: ll1=[]
In [1047]: for a in ll:
a1=a.flatten() # makes a copy
a1.mask=mask
ll1.append(a1)
In [1049]: ll1
Out[1049]:
[masked_array(data = [1 -- -- 4], mask = [False True True False],
fill_value = 999999),
masked_array(data = [5 -- -- 8], mask = [False True True False],
fill_value = 999999)]
通常可以写一个列表理解
[foo(a) for a in alist]
但这里的动作不是一个整洁的功能
如果我改为使用ravel
,a1
是一个视图(不是副本),并且对其应用掩码也会更改a
的掩码 - 结果是更改了掩码arr0
,但形状没有变化:
In [1051]: for a in ll:
......: a1=a.ravel()
......: a1.mask=mask
(a=a.ravel()
也是如此。a=
为a
分配了一个新值,打破了迭代值的链接。对于任何Python迭代都是如此。最好是在迭代中使用新的变量名称,如a1
,这样就不会让自己感到困惑。)
与
基本相同In [1054]: for a in ll:
......: a.mask=mask
我可以用相同的原位方式改变形状
In [1055]: for a in ll:
......: a.shape=[-1] # short hand for inplace ravel
......: a.mask=mask
In [1056]: arr0
Out[1056]:
masked_array(data = [1 -- -- 4],
mask = [False True True False],
fill_value = 999999)
这是一种使用新形状和蒙版创建新数组的功能方法,并在列表推导中使用它(并且不会更改为arr0
)
[np.ma.masked_array(a,mask=mask).ravel() for a in [arr0,arr1]]
了解这些替代方案确实需要了解Python如何分配迭代变量,以及numpy如何制作副本和视图。