Numpy 查找(地图或点)

Posted

技术标签:

【中文标题】Numpy 查找(地图或点)【英文标题】:Numpy Lookup (Map, or Point) 【发布时间】:2011-06-29 12:56:09 【问题描述】:

我有一个大的 numpy 数组:

array([[32, 32, 99,  9, 45],  # A
       [99, 45,  9, 45, 32],
       [45, 45, 99, 99, 32],
       [ 9,  9, 32, 45, 99]])

以及按特定顺序排列的大型唯一值数组:

array([ 99, 32, 45, 9])       # B

我怎样才能快速(没有python字典,没有A的副本,没有python循环)替换A中的值,以便成为B中的值的索引?:

array([[1, 1, 0, 3, 2],
       [0, 2, 3, 2, 1],
       [2, 2, 0, 0, 1],
       [3, 3, 1, 2, 0]])

我觉得实在是太愚蠢了,因为我无法在我的脑海中做到这一点,也无法在文档中找到它。轻松点!

【问题讨论】:

【参考方案1】:

给你

A = array([[32, 32, 99,  9, 45],  # A
   [99, 45,  9, 45, 32],
   [45, 45, 99, 99, 32],
   [ 9,  9, 32, 45, 99]])

B = array([ 99, 32, 45, 9])

ii = np.argsort(B)
C = np.digitize(A.reshape(-1,),np.sort(B)) - 1

原来我建议:

D = np.choose(C,ii).reshape(A.shape)

但我意识到,当您使用更大的阵列时,这会受到限制。相反,借用@unutbu 的聪明回复:

D = np.argsort(B)[C].reshape(A.shape)

或单线

np.argsort(B)[np.digitize(A.reshape(-1,),np.sort(B)) - 1].reshape(A.shape)

我发现它比 @unutbu 的代码更快或更慢,具体取决于所考虑的数组的大小和唯一值的数量。

【讨论】:

对于我的用例(B.sizeA 中的值”时,我可能只是暗示想要这种解决方案。 ..我认为没有 Cython 是可能的。谢谢你们! 我还发现 unutbu 的解决方案通常更快,除非 B.size 【参考方案2】:
import numpy as np
A=np.array([[32, 32, 99,  9, 45],  
            [99, 45,  9, 45, 32],
            [45, 45, 99, 99, 32],
            [ 9,  9, 32, 45, 99]])

B=np.array([ 99, 32, 45, 9])

cutoffs=np.sort(B)
print(cutoffs)
# [ 9 32 45 99]

index=cutoffs.searchsorted(A)
print(index)
# [[1 1 3 0 2]
#  [3 2 0 2 1]
#  [2 2 3 3 1]
#  [0 0 1 2 3]]    

index 将索引保存到与A 的每个元素关联的数组截止值中。请注意,我们必须对 B 进行排序,因为 np.searchsorted 需要一个排序后的数组。

index 几乎是我们想要的答案,除了我们要映射

1-->1
3-->0
0-->3
2-->2

np.argsort 为我们提供了这个映射:

print(np.argsort(B))
# [3 1 2 0]
print(np.argsort(B)[1])
# 1
print(np.argsort(B)[3])
# 0
print(np.argsort(B)[0])
# 3
print(np.argsort(B)[2])
# 2

print(np.argsort(B)[index])
# [[1 1 0 3 2]
#  [0 2 3 2 1]
#  [2 2 0 0 1]
#  [3 3 1 2 0]]

所以,作为一个单行,答案是:

np.argsort(B)[np.sort(B).searchsorted(A)]

同时调用np.sort(B)np.argsort(B) 效率很低,因为这两个操作都相当于对B 进行排序。对于任何一维数组B

np.sort(B) == B[np.argsort(B)]

所以我们可以更快地计算出期望的结果

key=np.argsort(B)
result=key[B[key].searchsorted(A)]

【讨论】:

以上是关于Numpy 查找(地图或点)的主要内容,如果未能解决你的问题,请参考以下文章

查找元素更改值的索引numpy

如何将 Pandas 查找表应用于 numpy 数组?

如何使用 numpy 有效地查找转换矩阵中的状态变化?

在 numpy.array 中查找唯一行

在 numpy 一维数组中查找拐点和平稳点

在 NumPy 数组中查找等于零的元素的索引