非常相似于 Bitwise 的回答:
def fn(a):
return lambda b: np.all(a==b, axis=1)
matches = np.apply_along_axis(fn(M), 1, L[:,:2])
result = L[np.any(matches, axis=1)]
发生在幕后的事情大致如下(我将使用Bitwise的示例来更容易地演示):
>>> M
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11]])
>>> M.shape+=(1,)
>>> M
array([[[ 0],
[ 1]],
[[ 2],
[ 3]],
[[ 4],
[ 5]],
[[ 6],
[ 7]],
[[ 8],
[ 9]],
[[10],
[11]]])
在这里,我们给M数组添加了另一个维度,现在变成了(6,2,1)。
>>> L2 = L[:,:-1].T
我们需要去掉2的最后一列,并将数组转置,以便维度为(2,4)。
现在,这里有一个魔术,M和L2可以广播到(6,2,4)维数组。
正如numpy文档所述:
A set of arrays is called “broadcastable” to the same shape if the
above rules produce a valid result, i.e., one of the following is
true:
The arrays all have exactly the same shape.
The arrays all have the same number of dimensions and the length of each dimensions is either a common length or 1.
The arrays that have too few dimensions can have their shapes prepended with a dimension of length 1 to satisfy property 2.
Example
If a.shape is (5,1), b.shape is (1,6), c.shape is (6,) and d.shape is
() so that d is a scalar, then a, b, c, and d are all broadcastable to
dimension (5,6); and
a acts like a (5,6) array where a[:,0] is broadcast to the other columns,
b acts like a (5,6) array where b[0,:] is broadcast to the other rows,
c acts like a (1,6) array and therefore like a (5,6) array where c[:] is broadcast to every row, and finally,
d acts like a (5,6) array where the single value is repeated.
M[:,:,0]将重复4次以填充3维数组,并且L2将添加一个新的维度并重复6次以填充它。
>>> B = np.broadcast_arrays(L2,M)
>>> B
[array([[[ 0, 3, 6, 9],
[ 1, 4, 7, 10]],
[[ 0, 3, 6, 9],
[ 1, 4, 7, 10]],
[[ 0, 3, 6, 9],
[ 1, 4, 7, 10]],
[[ 0, 3, 6, 9],
[ 1, 4, 7, 10]],
[[ 0, 3, 6, 9],
[ 1, 4, 7, 10]],
[[ 0, 3, 6, 9],
[ 1, 4, 7, 10]]]),
array([[[ 0, 0, 0, 0],
[ 1, 1, 1, 1]],
[[ 2, 2, 2, 2],
[ 3, 3, 3, 3]],
[[ 4, 4, 4, 4],
[ 5, 5, 5, 5]],
[[ 6, 6, 6, 6],
[ 7, 7, 7, 7]],
[[ 8, 8, 8, 8],
[ 9, 9, 9, 9]],
[[10, 10, 10, 10],
[11, 11, 11, 11]]])]
现在我们可以逐个元素进行比较:
>>> np.equal(*B)
array([[[ True, False, False, False],
[ True, False, False, False]],
[[False, False, False, False],
[False, False, False, False]],
[[False, False, False, False],
[False, False, False, False]],
[[False, False, True, False],
[False, False, True, False]],
[[False, False, False, False],
[False, False, False, False]],
[[False, False, False, False],
[False, False, False, False]]], dtype=bool)
按行操作(轴=1):
>>> np.all(np.equal(*B), axis=1)
array([[ True, False, False, False],
[False, False, False, False],
[False, False, False, False],
[False, False, True, False],
[False, False, False, False],
[False, False, False, False]], dtype=bool)
按L的聚合:
>>> C = np.any(np.all(np.equal(*B), axis=1), axis=0)
>>> C
array([ True, False, True, False], dtype=bool)
这将为您提供适用于L的布尔掩码。
>>> L[C]
array([[0, 1, 2],
[6, 7, 8]])
apply_along_axis
将利用相同的功能,但减少L的维数而不是增加M的维数(从而添加隐式循环)。
L
中行的最后一个元素是基于某些额外计算添加的维度。 - inspectorG4dgetsort
和in1d
调用来解决一些问题。但是现在这个想法还很模糊。 - user2357112