【问题标题】:Numpy Lookup (Map, or Point)Numpy 查找(地图或点)
【发布时间】: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]])

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

【问题讨论】:

    标签: python indexing numpy


    【解决方案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)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 2015-06-30
      • 1970-01-01
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      相关资源
      最近更新 更多