我有一个浮动值的Numpy ndarray矩阵,我需要选择特定行,其中某些列的值满足某些条件。例如,假设我有以下numpy矩阵:
matrix = np.ndarray([4, 5])
matrix[0,:] = range(1,6)
matrix[1,:] = range(6,11)
matrix[2,:] = range(11,16)
matrix[3,:] = range(16,21)
假设我想从矩阵中选择第一列的值介于1和6之间的行,第二列的值介于2-7之间。
如何获得满足这些条件的矩阵的行索引?如果我想删除满足条件标准的行呢?
答案 0 :(得分:9)
对于基于numpy的解决方案,您可以使用numpy.where
然后从中获取行索引,然后使用它来索引矩阵。示例 -
matrix[np.where((1 <= matrix[:,0]) & (matrix[:,0] <= 6)
& (2 <= matrix[:,1]) & (matrix[:,1] <= 7))]
演示 -
In [169]: matrix
Out[169]:
array([[ 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10.],
[ 11., 12., 13., 14., 15.],
[ 16., 17., 18., 19., 20.]])
In [170]: matrix[np.where((1 <= matrix[:,0]) & (matrix[:,0] <= 6)
.....: & (2 <= matrix[:,1]) & (matrix[:,1] <= 7))]
Out[170]:
array([[ 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10.]])
另一种方法,如注释中所示,将使用布尔掩码,示例 -
mask = ((1 <= matrix[:,0]) & (matrix[:,0] <= 6)
& (2 <= matrix[:,1]) & (matrix[:,1] <= 7))
matrix[mask,:]
演示 -
In [41]: matrix
Out[41]:
array([[ 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10.],
[ 11., 12., 13., 14., 15.],
[ 16., 17., 18., 19., 20.]])
In [42]: mask = ((1 <= matrix[:,0]) & (matrix[:,0] <= 6)
....: & (2 <= matrix[:,1]) & (matrix[:,1] <= 7))
In [43]:
In [43]: matrix[mask,:]
Out[43]:
array([[ 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10.]])
答案 1 :(得分:1)
您可以使用以下内容获取索引:
rows = np.logical_and(0 < matrix[:, 0], < matrix[:, 0] < 6 ) * np.logical_and(1 < matrix[:, 1], matrix[:, 1] < 7)
然后newMatrix = np.delete(matrix, rows, axis = 0)
答案 2 :(得分:1)
你提到过MATLAB。这相当于使用Octave接受的答案
octave:17> ma=reshape(1:20,5,4)
ma =
1 6 11 16
2 7 12 17
3 8 13 18
4 9 14 19
5 10 15 20
octave:18> mask=(1<=ma(1,:))&(ma(1,:)<=6)&(2<=ma(2,:))&(ma(2,:)<=7)
mask =
1 1 0 0
octave:19> ma(:,mask)
ans =
1 6
2 7
3 8
4 9
5 10
没有where
的已接受答案是:
In [592]: mask=(1 <= matrix[:,0]) & (matrix[:,0] <= 6) &(2 <= matrix[:,1]) & (matrix[:,1] <= 7)
In [593]: matrix[mask,:]
Out[593]:
array([[ 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10.]])
我在Octave版本中切换了行和列,因为这是生成相同数字的自然方式(MATLAB / Octave使用相当于numpy
s'F'的顺序 - 见下文。)
其他变化是0 v 1起始索引和()v []。否则这两个符号是相似的。
在numpy中生成matrix
的更简单方法:
In [594]: np.arange(1,21).reshape(4,5)
Out[594]:
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]])
或者使用MATLAB布局:
In [595]: np.arange(1,21).reshape(5,4,order='F')
Out[595]:
array([[ 1, 6, 11, 16],
[ 2, 7, 12, 17],
[ 3, 8, 13, 18],
[ 4, 9, 14, 19],
[ 5, 10, 15, 20]])
答案 3 :(得分:0)
获取行索引:
row_indices = [x for x in range(4) if matrix[x][0] in range(1,7) and matrix[x][1] in range(2,8)]
删除行:
indices = [x for x in range(4) if not( matrix[x][0] in range(1,7) and matrix[x][1] in range(2,8))]
new_matrix = matrix[indices]