在python中的列表中展平数组

时间:2016-06-21 10:07:01

标签: python arrays numpy view flatten

我有多个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)

1 个答案:

答案 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]

但这里的动作不是一个整洁的功能

如果我改为使用ravela1是一个视图(不是副本),并且对其应用掩码也会更改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如何制作副本和视图。