从具有特定值的多个阵列中删除值
可以说我有两个阵列:a = array([1,2,3,0,4,5,0])
和b = array([1,2,3,4,0,5,6])
。我有兴趣去除a
和b
为0
的情况。但我也想从两个列表中删除相应的实例。因此,我想要结束的是a = array([1,2,3,5])
和b = array([1,2,3,5])
。这是因为a[3] == 0
和a[6] == 0
,所以b[3]
和b[6]
也被删除。同样,由于b[4] == 0
,a[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])
,不是我需要的答案。任何想法,这是错的?
发生这种情况是因为当您从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]
当然,你可以自动化循环内发生的事情。我只是想解释发生了什么。
重新分配是非常聪明的,但是当缩放到更大的数组集合或可变数组大小时,这不属于复制粘贴问题吗? –
我试图想到一些不涉及复制粘贴的事情。也许做一个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))
OP是否希望在每次迭代后索引都改变? – Zeokav
他们说他们希望从两个列表中删除索引中至少有一个列表包含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
@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
做所有阵列具有相同的长度? – dnalow
@dnalow是的,它们的长度相同。 – deserthiker