如果特定值存在,则从偶数列中删除行

3

我有一个形状为

numpy 数组。
(500,12) 

我想做的就是检查偶数列是否具有正值,例如:value > 0。如果是这样,我想在数组中删除整行。

a = a[a[:,1] < 0, :]

这将消除所需的行,但只查看第二列。我希望它也能检查第4列、第6列、第8列等等。
使用上述方法,有没有一种可以做到这一点的方法?

检查不应该是<=吗? - Willem Van Onsem
我不清楚您定义的列和行是什么。您说“在这种情况下,我想从我的数组中删除整行”,您是指整个列吗?您可以考虑使用pandas。 - Elmex80s
我的主数组有500行和12列。然后,我想对每一列进行检查,如果是偶数列且包含正值,则从主数组中删除该行。这样,我的主数组将变为499行和12列。 - Mati Malik
是的,NumPy数组。我不确定您缺少哪些信息。 - Mati Malik
啊,我们正在谈论numpy数组。- 你口头描述的问题含糊不清。 - Elmex80s
5个回答

2
如果您正在处理NumPy数组,则可以使用"花式索引"方法(使用整数数组序列索引一个数组)。具体如下所示:

花式索引和索引技巧

mask = (a[:, np.arange(1, a.shape[1], 2)] < 0).all(axis=1)
out = a[mask]

解释:

选择奇数列的位置,比较其值:

np.arange(1, a.shape[1], 2)         # a.shape[1] gives the number of columns
# array([ 1,  3,  5,  7,  9, 11])

接下来,我们根据这些索引对数组进行子集划分,并通过提供 axis = 1 来检查这些列下的值是否小于零,执行列方向的检查并返回一个包含删除其余行后减少行数的数组。


1

虽然可能不是最有效的方法,但您可以对所有行使用逐元素与&

a = a[<b>(a[:,1]<0)&(a[:,3]<0)&(a[:,5]<0)&(a[:,7]<0)&(a[:,9]<0)&(a[:,11]<0)</b>,:]

所以你要屏蔽所有存在正偶数列的项。 你可以更加优雅地实现它(带有轻微的性能损失),使用functools.reduce
<b>from functools import reduce</b>

a = a[<b>reduce(lambda x,y:x&y,(a[:,i]<0 for i in range(1,12,2)))</b>,:]

如果事先不完全知道 shape,可以使用 .shape[1]

from functools import reduce

a = a[reduce(lambda x,y:x&y,(a[:,i]<0 for i in range(1,<b>a.shape[1]</b>,2))),:]

我可以这样做,但问题是我会有更多的列。因此,我正在寻找一般解决方案。实际上,我已经尝试了这个,看起来它有效: for i in range (1, 12, 2):
a = a[a[:,i] < 0, :] 你能看出任何问题吗?
- Mati Malik
@MatiMalik:我认为这次编辑跨越了您的评论。语义上它是等效的。但我猜您的做法会导致更高的性能惩罚,因为您每次都要过滤数组。 - Willem Van Onsem
你更新后的解决方案可能更简化了,谢谢!另外,你有什么建议如何将所有偶数列中的负值转换为正值吗? - Mati Malik
@NickilMaveli 我不确定。第一个值应该是确切的0,但它会给出接近于0的值,例如7.76000000e-02。例如,我第一个奇数列的最小值为-12.6313(+ 12.6313)应该为0。但也许您的解决方案只取几位小数?例如:-12.6313 +12.63 - Mati Malik
我从一个numpy数组的每个奇数列中提取了绝对最小值,代码如下:b=np.zeros(6)for i in range (int(a.shape[1]/2)):b[i]=abs(min(a[:,0::2][:,i]))现在唯一需要做的就是将这些值添加到它们各自所在的整个列中。 - Mati Malik
显示剩余2条评论

1
一般的方法是使用条件构建列表推导式:
a = [row for row in a if all(row[j] <= 0 for j in range(0, len(row), 2))]

1
如果您不想使用循环(因为它会迭代地缩小数据框并带有一些相关的开销):
m = (arr > 0) # check if positive; this is what you want to keep
m = arr.ix[:,1::2] # select only the even columns
m = arr.any(axis=1) # and check if any of them is true

所以简单来说:

 arr[(arr > 0)[:,1::2].all(axis=1),:]

应该使用 all 而不是 any 吗? - Willem Van Onsem
不是完全确定,但评论似乎表明了这一点。我已经进行了更改。 - Roelant

0

如果不使用循环,就没有单个命令可以帮助您实现目标。我建议遍历所有行,然后执行此操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接