2016-09-26 10 views
0

a = array([1,2,3,0,4,5,0])b = array([1,2,3,4,0,5,6])の2つの配列があります。私はab0であるインスタンスを削除することに興味があります。しかし、私は両方のリストから対応するインスタンスを削除したい。したがって私が最後にしたいのはa = array([1,2,3,5])b = array([1,2,3,5])です。これは、a[3] == 0a[6] == 0なので、b[3]b[6]の両方も削除されているためです。私は(私は)多くの多くの配列を持っている場合は、このソリューションはスケールアップdoesntの特定の値を持つ複数の配列から値を削除する

import numpy as np 
a = np.array([1,2,3,0,4,5,0]) 
b = np.array([1,2,3,4,0,5,6]) 

ix = np.where(b == 0) 
b = np.delete(b, ix) 
a = np.delete(a, ix) 

ix = np.where(a == 0) 
b = np.delete(b, ix) 
a = np.delete(a, ix) 

:同様に、a[4]b[4] == 0以降は、2つのアレイと言うためにこれを行うには、単純なdeleted.Itsされます。これを行うもっとエレガントな方法は何でしょうか?

私は次のことをしようとした場合:

import numpy as np 

a = np.array([1,2,3,0,4,5,0]) 
b = np.array([1,2,3,4,0,5,6]) 

arrays = [a,b] 

for array in arrays: 
    ix = np.where(array == 0) 
    b = np.delete(b, ix) 
    a = np.delete(a, ix) 

私は私が必要な答え、a = array([1, 2, 3, 4])b = array([1, 2, 3, 0])がない得ます。これが間違っているのはどうですか?

+0

をすべての配列は同じ長さを持っているのですか? – dnalow

+0

@dnalowはい、同じ長さです。 – deserthiker

答えて

1

これは、np.deleteから戻ったときに、bとaの中にループ内に格納されている配列が得られるためです。ただし、配列変数に格納されている配列はコピーであり、参照ではありません。したがって、配列を削除して更新する場合は、元の配列を削除します。最初のループは配列内の0の添字の添字を返しますが、2番目のループはixを4として返します(元の配列を見てください)。
各繰り返しで配列変数を表示した場合と同じように、同じままになります。

配列の処理が完了したら配列を再割り当てして、次の繰り返しを考慮に入れる必要があります。ここでやる方法 -

a = np.array([1, 2, 3, 0, 4, 5, 0]) 
b = np.array([1, 2, 3, 4, 0, 5, 6]) 
arrays = [a,b] 
for i in range(0, len(arrays)): 
    ix = np.where(arrays[i] == 0) 
    b = np.delete(b, ix) 
    a = np.delete(a, ix) 
    arrays = [a, b] 

もちろん、ループ内で何が起こるかを自動化することができます。私は何が起こっていたのか説明をしたかっただけです。

+0

再割り当てはかなり賢明ですが、これは大規模な配列セットや可変配列サイズにスケーリングするときにコピー貼り付けの問題になりませんか? –

+0

私はコピー貼り付けを含まないものを考えようとしています。多分配列のnumpy配列を作る...私は周りの方法を見つけるために起こった場合は、やってみよう! – Zeokav

0

遅い方法は、二回リスト全体にわたって動作削除するインデックスの中間リストを構築するために最初に、次いで第2のもののインデックスで値をすべて削除することを含む:

import numpy as np 

a = np.array([1,2,3,0,4,5,0]) 
b = np.array([1,2,3,4,0,5,6]) 

arrays = [a, b] 
vals = [] 

for array in arrays: 
    ix = np.where(array == 0) 
    vals.extend([y for x in ix for y in x.tolist()]) 

vals = list(set(vals)) 

new_array = [] 
for array in arrays: 
    new_array.append(np.delete(array, vals)) 
+0

オペレーションは、反復ごとにインデックスを変更したくないのですか? – Zeokav

+0

リストの少なくとも1つに0が含まれているインデックスの要素を両方のリストから削除したいとします。そして、それらの 'b [4] == 0'の使用は、必ずしも削除したくないということを示します'a'は' a'から 'b'値を削除する前に' b'から最初に値を取ります。すべての指標のリストを作成し、すべての値を削除してください。 –

3

両方/すべての仮定配列は常に同じ長さを持っている、あなたはmasksを使用することができます。

ma = a != 0 # mask elements which are not equal to zero in a 
mb = b != 0 # mask elements which are not equal to zero in b 
m = ma * mb # assign the intersection of ma and mb to m 
print a[m], b[m] # [1 2 3 5] [1 2 3 5] 

あなたはもちろん1行に

m = (a != 0) * (b != 0) 
を行うことができます

それとも

ma = a == 0 
mb = b == 0 
m = ~(ma + mb) # not the union of ma and mb 
+0

マスクに慣れていなかった@Christoph Terasa。エレガント! – deserthiker

0

はクリストフ・テラサの答えの上にアップ構築の逆を使用するには、forループの代わりに、配列演算を使用することができます。

arrays = np.vstack([a,b]) # ...long list of arrays of equal length 

zeroind = (arrays==0).max(0) 

pos_arrays = arrays[:,~zeroind] # a 2d array only containing those columns where none of the lines contained zeros 
関連する問題