Python:交叉索引numpy数组
如何获取两个numpy数组之间交点的索引?我可以通过Python:交叉索引numpy数组,python,arrays,numpy,Python,Arrays,Numpy,如何获取两个numpy数组之间交点的索引?我可以通过intersect1d获得相交值: import numpy as np a = np.array(xrange(11)) b = np.array([2, 7, 10]) inter = np.intersect1d(a, b) # inter == array([ 2, 7, 10]) 但是如何将索引放入inter中值的a?您可以使用in1d生成的布尔数组来索引arange。反转a,使索引与值不同: >>> a[::
intersect1d
获得相交值:
import numpy as np
a = np.array(xrange(11))
b = np.array([2, 7, 10])
inter = np.intersect1d(a, b)
# inter == array([ 2, 7, 10])
但是如何将索引放入
inter
中值的a
?您可以使用in1d
生成的布尔数组来索引arange
。反转a
,使索引与值不同:
>>> a[::-1]
array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
>>> a = a[::-1]
intersect1d
仍然返回相同的值
>>> numpy.intersect1d(a, b)
array([ 2, 7, 10])
但INAD中的返回一个布尔数组:
>>> numpy.in1d(a, b)
array([ True, False, False, True, False, False, False, False, True,
False, False], dtype=bool)
可用于索引范围的:
>>> numpy.arange(a.shape[0])[numpy.in1d(a, b)]
array([0, 3, 8])
>>> indices = numpy.arange(a.shape[0])[numpy.in1d(a, b)]
>>> a[indices]
array([10, 7, 2])
不过,为了简化上述内容,您可以使用--这可能是最正确的方法,因为它返回一组统一的X
,Y
。。。坐标:
>>> numpy.nonzero(numpy.in1d(a, b))
(array([0, 3, 8]),)
或者,相当于:
>>> numpy.in1d(a, b).nonzero()
(array([0, 3, 8]),)
结果可以用作与a
形状相同的数组的索引,没有问题
>>> a[numpy.nonzero(numpy.in1d(a, b))]
array([10, 7, 2])
但请注意,在许多情况下,只使用布尔数组本身是有意义的,而不是将其转换为一组非布尔索引
最后,您还可以将布尔数组传递给,这将生成形状稍有不同的结果,该结果不太适合索引,但可能用于其他目的
>>> numpy.argwhere(numpy.in1d(a, b))
array([[0],
[3],
[8]])
如果需要获得intersect1d给定的唯一值:
import numpy as np
a = np.array([range(11,21), range(11,21)]).reshape(20)
b = np.array([12, 17, 20])
print(np.intersect1d(a,b))
#unique values
inter = np.in1d(a, b)
print(a[inter])
#you can see these values are not unique
indices=np.array(range(len(a)))[inter]
#These are the non-unique indices
_,unique=np.unique(a[inter], return_index=True)
uniqueIndices=indices[unique]
#this grabs the unique indices
print(uniqueIndices)
print(a[uniqueIndices])
#now they are unique as you would get from np.intersect1d()
输出:
[12 17 20]
[12 17 20 12 17 20]
[1 6 9]
[12 17 20]
对于Python>=3.5
,还有另一种解决方案
其他解决方案
让我们一步一步地看一遍
基于问题的原始代码
import numpy as np
a = np.array(range(11))
b = np.array([2, 7, 10])
inter = np.intersect1d(a, b)
首先,我们创建一个带有零的numpy数组
c = np.zeros(len(a))
print (c)
输出
>>> [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
>>>[ 0. 0. 1. 0. 0. 0. 0. 1. 0. 0. 1.]
array([ 2, 7, 10])
其次,使用intersect索引更改c的数组值。因此,我们有
c[inter] = 1
print (c)
输出
>>> [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
>>>[ 0. 0. 1. 0. 0. 0. 0. 1. 0. 0. 1.]
array([ 2, 7, 10])
最后一步,使用np.nonzero()
inter_with_idx = np.nonzero(c)
print (inter_with_idx)
最终输出
>>> [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
>>>[ 0. 0. 1. 0. 0. 0. 0. 1. 0. 0. 1.]
array([ 2, 7, 10])
参考文献
[1] 很粗糙,但它很有效:)八度音阶更容易:[inter indexA indexB]=intersect(A,b)非常感谢您的回答!in1d和1d是不一样的。intersect1d给出唯一的值,INAD给出所有的交集,所以这个答案并不总是有效。@Rik,我想我不同意。的确,一维中的不会删除重复项,但它不应该这样做。它返回的是索引,如果从一组重复项中只返回一个索引,那将是一种令人困惑的行为。这个问题没有指定哪种行为,所以这个答案完全符合它的要求:“获取两个numpy数组之间交点的索引。”如果你想没有重复项,你必须事先剔除它们,这是合理和预期的。我明白你的意思,您可以使用np.unique first或after以及return_index=true来给出索引,然后使用intersect1d。我解释说,由于他发布的代码,他想要唯一的值,但不确定。如果有什么需要改进的地方,请告诉我,有人能解释一下否决票吗?我将不胜感激:)