所以我有一个2D数组data
,如下所示:
我想计算后两列某个条件下的行数。例如,在这个特定的数组中,我只有
1 | 2
但鉴于第三行是range(1,4)
,第四行是range(0,3)
,我可以拥有以下所有组合:
1 | 0
1 | 1
1 | 2
2 | 0
2 | 1
2 | 2
3 | 0
3 | 1
3 | 2
我想选择每个条件为真的行。但我不知道该怎么做呢?我在过去的两个小时里一直在研究这个问题,并且我已经提出了使用for循环,列表推导等等的东西。但它变得越来越复杂,并且这些方法都没有实际工作。有没有一种好方法可以在numpy,甚至只是普通的python中执行此操作?
任何帮助将不胜感激,谢谢!
答案 0 :(得分:2)
布尔屏蔽一个很好的通用工具,用于根据一个或多个条件从数组中选择行或列(或元素)。
使用[0,9)范围内的整数创建一个数组:
In [326]: arr=np.random.randint(0,10,(20,4))
In [327]: arr
Out[327]:
array([[9, 4, 1, 1],
[6, 1, 9, 6],
[5, 3, 4, 9],
[7, 4, 0, 4],
[6, 2, 3, 5],
[4, 5, 1, 8],
[0, 9, 1, 3],
[7, 7, 1, 5],
[5, 9, 6, 6],
[0, 9, 2, 1],
[4, 9, 1, 6],
[5, 1, 5, 2],
[1, 5, 2, 0],
[9, 0, 6, 5],
[1, 9, 2, 4],
[6, 7, 7, 9],
[5, 2, 5, 4],
[1, 6, 5, 9],
[0, 4, 3, 1],
[7, 7, 7, 7]])
在0到3之间的2列中查找元素.Python允许0<x<3
之类的测试,但numpy
只允许单边测试。括号对于建立运营商订单很重要。 (|
for或):
In [328]: mask=(0<arr[:,2:]) & (arr[:,2:]<3)
In [329]: mask
Out[329]:
array([[ True, True],
[False, False],
[False, False],
[False, False],
[False, False],
[ True, False],
[ True, False],
[ True, False],
[False, False],
[ True, True],
[ True, False],
[False, True],
[ True, False],
[False, False],
[ True, False],
[False, False],
[False, False],
[False, False],
[False, True],
[False, False]], dtype=bool)
现在我们可以选择任一列在正确范围内的行:
In [330]: arr[mask.any(axis=1),:]
Out[330]:
array([[9, 4, 1, 1],
[4, 5, 1, 8],
[0, 9, 1, 3],
[7, 7, 1, 5],
[0, 9, 2, 1],
[4, 9, 1, 6],
[5, 1, 5, 2],
[1, 5, 2, 0],
[1, 9, 2, 4],
[0, 4, 3, 1]])
或两者都是:
In [331]: arr[mask.all(axis=1),:]
Out[331]:
array([[9, 4, 1, 1],
[0, 9, 2, 1]])
where
通常用于将布尔数组转换为索引号:
In [332]: np.where(mask.all(axis=1))
Out[332]: (array([0, 9], dtype=int32),)
In [333]: arr[_,:]
Out[333]:
array([[[9, 4, 1, 1],
[0, 9, 2, 1]]])
答案 1 :(得分:1)
这有效:
import numpy as np
# data array
data = np.array([[4,3,1,2],[4,3,5,1],[1,2,1,0]])
# array of acceptable combinations
cond = np.array([[1,0],[1,2]])
# index of rows matching the conditions
idx=np.array([any(np.equal(cond,row).all(1)) for row in data[:,2:]])
# selected rows
data[idx]
# array([[4, 3, 1, 2],
# [1, 2, 1, 0]]