2016-06-21 9 views
0

私は複数のマスクされた配列num30を持っていますarr0, arr1, ..., arrnPythonのリストで配列をフラット化

私はそれらをリストarrs = [arr0, ..., arrn]に入れました。

これらの配列を平坦化して、それらにマスクを貼りたいと思います。 Pythonはコピーを作成するとき、それは単なるポインタであるとき、私は理解していない

for arr in arrs: 
    arr = np.ravel(arr) 
    arr[mask] = ma.masked 

:私のような何かをしました。このforループは、arr0, ..., arrnを平坦化しません(ただし、ravelはビューではなくコピーを出力します)。マスクは変更されますが、変数arrは平坦化されます。

私が理解しているように、arrはリストarrsの要素のビューですので、arrの要素を変更すると、リスト内の対応する配列の要素が変更されます。しかし、arrに新しい値を割り当てると、割り当てがこの配列のビューになっていても元の配列は変更されません。どうして ?私が持っているので、私はループ内でこれを行うにはしたいと思い

arr0 = masked_array(data=[[1,--],[--,4]], mask=[[False,True],[True,False]]) 
arr1 = masked_array(data=[[5,--],[--,8]], mask=[[False,True],[True,False]]) 

:平坦化する

配列:

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

の予想される出力の例と

編集たくさんの配列(15個以上)があり、コード内で配列名を使用したい。

arr0 = np.ravel(arr0) 
... 
arrn = np.ravel(arrn) 
+0

達成しようとしている数値例を追加できますか? –

+0

問題はリストイテレータにあります。ループ内で割り当てることはできません。 – hpaulj

+0

'arr = np.ravel(arr)'は 'arr'の新しい(平坦化された)ビューを作成し、* arr *という名前をその作成したビューを指すように再割り当てします。普通の割り当てだけで[名前を何かを指すように再割り当てする](http://stackoverflow.com/questions/2438938/python-copy-through-assignment)。あなたが 'ravel()'と書いたように、ビューを作成するので、 'arr [mask] = ma.masked'はオリジナルも変更します。 –

答えて

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がコピーとビューを作成する方法を理解する必要があります。

関連する問題