从具有特定值的多个阵列中删除值

问题描述:

可以说我有两个阵列:a = array([1,2,3,0,4,5,0])b = array([1,2,3,4,0,5,6])。我有兴趣去除ab0的情况。但我也想从两个列表中删除相应的实例。因此,我想要结束的是a = array([1,2,3,5])b = array([1,2,3,5])。这是因为a[3] == 0a[6] == 0,所以b[3]b[6]也被删除。同样,由于b[4] == 0a[4]也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]) 

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) 

但是这种解决方案犯规扩大,如果我有很多很多阵列(这是我做的)。什么会是一个更优雅的方式来做到这一点?

如果我尝试以下方法:

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

发生这种情况是因为当您从np.delete返回时,会得到一个存储在b和循环内部的数组。但是,存储在数组变量中的数组是副本,而不是引用。因此,当您通过删除数组来更新数组时,它会删除原始数组。第一个循环将返回数组中的更正索引0,但第二个循环将返回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阵列的numpy阵列...如果我碰巧找到解决方法,会试着回来! – Zeokav

缓慢方法涉及在整个列表操作两次,第一次建立索引的中间列表中删除,然后第二删除所有的值中的这些索引:

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

OP是否希望在每次迭代后索引都改变? – Zeokav

+0

他们说他们希望从两个列表中删除索引中至少有一个列表包含0的元素。他们使用'b [4] == 0'表示他们不需要删除在从'a'删除'b'值之前,首先从'b'得到'a'值。对我来说,这就是说,'建立一个所有指数的列表,然后删除所有的值。' –

假设两者/所有数组总是具有相同的长度,你可以使用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] 

当然你也可以这样做,也是在同一行

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

构建上克里斯托夫Terasa的回答上面,你可以使用,而不是为循环中的数组操作:

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