我有一个很大的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]])
我感到非常愚蠢,因为我无法做到这一点,也没有在文档中找到它。简单点!
答案 0 :(得分:7)
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
。对于任何1D阵列B
,
np.sort(B) == B[np.argsort(B)]
因此我们可以使用
更快地计算出所需的结果key=np.argsort(B)
result=key[B[key].searchsorted(A)]
答案 1 :(得分:6)
你去吧
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的代码更快或更慢,具体取决于所考虑的数组的大小和唯一值的数量。