Python - 在特定条件下选择数组行?

时间:2016-12-01 03:50:15

标签: python arrays numpy multidimensional-array list-comprehension

所以我有一个2D数组data,如下所示:

enter image description here

我想计算后两列某个条件下的行数。例如,在这个特定的数组中,我只有

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中执行此操作?

任何帮助将不胜感激,谢谢!

2 个答案:

答案 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]]