我有一个稀疏的对称数组,如果给定行(和列)的所有单个条目都不满足某个阈值条件,我试图删除该数组的行和列。例如,如果
min_value = 2
a = np.array([[2, 2, 1, 0, 0],
[2, 0, 1, 4, 0],
[1, 1, 0, 0, 1],
[0, 4, 0, 1, 0],
[0, 0, 1, 0, 0]])
我想将行(和列)保留在至少为2或更大值的位置,以便通过上面的示例生成
a_new = np.array([2, 2, 0],
[2, 0, 4],
[0, 4, 1]]
所以我会丢失第3行和第5行(以及第3列和第5列),因为每个条目都少于2个。我已经看过了 How could I remove the rows of an array if one of the elements of the row does not satisfy a condition?,Delete columns based on repeat value in one row in numpy array和Delete a column in a multi-dimensional array if all elements in that column satisfy a condition,但标记的解决方案并不适合我尝试完成的任务。
我在考虑做类似的事情:
a_new = []
min_count = 2
for row in a:
for i in row:
if i >= min_count:
a_new.append(row)
print(items)
print(temp)
但这不起作用,因为它没有删除坏列,如果有两个(或更多)实例的值大于阈值,它会多次追加一行。
答案 0 :(得分:1)
您可以使用矢量化解决方案来解决它 - 如下所示 -
# Get valid mask
mask = a >= min_value
# As per requirements, look for ANY match along rows and cols and
# use those masks to index into row and col dim of input array with
# 1D open meshes from np.ix_ and thus select a 2D slice out of it
out = a[np.ix_(mask.any(1),mask.any(0))]
表达它的一种更简单的方法是选择行,然后选择列,如下所示 -
a[mask.any(1)][:,mask.any(0)]
滥用输入数组的对称性,它会简化为 -
mask0 = (a>=min_value).any(0)
out = a[np.ix_(mask0,mask0)]
示例运行 -
In [488]: a
Out[488]:
array([[2, 2, 1, 0, 0],
[2, 0, 1, 4, 0],
[1, 1, 0, 0, 1],
[0, 4, 0, 1, 0],
[0, 0, 1, 0, 0]])
In [489]: min_value
Out[489]: 2
In [490]: mask0 = (a>=min_value).any(0)
In [491]: a[np.ix_(mask0,mask0)]
Out[491]:
array([[2, 2, 0],
[2, 0, 4],
[0, 4, 1]])
或者,我们可以使用有效掩码的行索引和列索引,如此 -
r,c = np.where(a>=min_value)
out = a[np.unique(r)[:,None],np.unique(c)]
再次滥用对称性质,简化版本将是 -
r = np.unique(np.where(a>=min_value)[0])
out = a[np.ix_(r,r)]
r
也可以通过混合布尔运算获得 -
r = np.flatnonzero((a>=min_value).any(0))