numpy - 在两个数组中选择列相等的行

Ber*_*iel 2 python arrays numpy

我有两个数组:

a = 
[[ 461.  0.  ]
 [ 480.  15. ]
 [ 463.  28. ]]
Run Code Online (Sandbox Code Playgroud)

b = 
[[ 463.  0.  ]
 [ 462.  8.  ]
 [ 466.  15. ]
 [ 469.  22. ]
 [ 470.  28. ]
 [ 473.  34. ]]
Run Code Online (Sandbox Code Playgroud)

我需要一个由a减号组成的结果数组,b如果第二列a => [0 15 28] 在第二列中b => [0 8 15 22 28 34].第二列的所有元素a都将在第二列中b,我只想丢弃那些b不存在的那些元素a.预期的结果是:

result =
[[  -2.  0.  ]
 [  14.  15. ]
 [  -7.  28. ]]
Run Code Online (Sandbox Code Playgroud)

首先,我想到了"子阵列" b,其中只包含我感兴趣的行.在许多其他事情中,我认为可行的(并没有)的是:

result = b[b[:, 1] in a[:, 1]] # not working
Run Code Online (Sandbox Code Playgroud)

欢迎任何帮助.

ray*_*ica 5

该算法在以下假设下工作:

  1. 第二列a是第二列的子集b.这意味着我们保证在第二列中b给定值的第二列中找到一个值a.
  2. 第二列ab排序.
  3. a和之间共享的第二列中没有重复值b.

使用numpy.in1d找出是否在第二列中的对应的值b中可以找到a.然后,您可以使用此布尔数组切入b并使用a切片结果的第一列和第一列进行减法b.这有效的原因是因为排序顺序的性质b.当与此数组一起切入此数组时numpy.in1d,您可以保证此切片结果的第二列与第一列的值完全匹配a.完成此对齐后,可以使用第一列减去此切片结果的第一列a.为了完成,您可以复制切片值的第二列b 并将这两者叠加在一起:

In [119]: import numpy as np

In [120]: a = np.array([[461,0],[480,15],[463,28]], dtype=np.float)

In [121]: b = np.array([[463,0], [462,8], [466,15], [469,22], [470,28], [473,34]], dtype=np.float)

In [122]: ind = np.in1d(b[:,1], a[:,1])

In [123]: np.column_stack([a[:,0]-b[ind,0], b[ind,1]])
Out[123]: 
array([[ -2.,   0.],
       [ 14.,  15.],
       [ -7.,  28.]])
Run Code Online (Sandbox Code Playgroud)

返回的numpy.in1d是一个布尔数组,它告诉您第一个输入中的第i个值是否numpy.in1d可以在第二个输入中的任何位置找到numpy.in1d.为了看看这是什么,给定您的数据,我们得到:

In [124]: ind
Out[124]: array([ True, False,  True, False,  True, False], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

如您所见,b可以在中找到第一个,第三个和第五个值a.我们只需切入b并提取正确的行,切片结果的这些行将使第二列值与第二列值完全对齐a.然后我们一起减去两者的第一列a和中间结果.


一个更干净的方法是切入b并提取整个矩阵而不是第一列,然后用a这个中间结果减去第一列:

In [125]: out = b[ind]

In [126]: out[:,0] = a[:,0] - out[:,0]

In [127]: out
Out[127]: 
array([[  -2.,   0.],
       [  14.,  15.],
       [  -7.,  28.]])
Run Code Online (Sandbox Code Playgroud)