我有一个具有唯一正整数的数组/集,即
>>> unique = np.unique(np.random.choice(100, 4, replace=False))
包含从前一个数组中采样的多个元素的数组,例如
>>> A = np.random.choice(unique, 100)
我想将数组A
的值映射到这些值在unique
中出现的位置。
到目前为止,我找到的最佳解决方案是通过映射数组:
>>> table = np.zeros(unique.max()+1, unique.dtype)
>>> table[unique] = np.arange(unique.size)
上面为每个元素分配了数组上的索引,因此可以在以后通过高级索引来映射A
:
>>> table[A]
array([2, 2, 3, 3, 3, 3, 1, 1, 1, 0, 2, 0, 1, 0, 2, 1, 0, 0, 2, 3, 0, 0, 0,
0, 3, 3, 2, 1, 0, 0, 0, 2, 1, 0, 3, 0, 1, 3, 0, 1, 2, 3, 3, 3, 3, 1,
3, 0, 1, 2, 0, 0, 2, 3, 1, 0, 3, 2, 3, 3, 3, 1, 1, 2, 0, 0, 2, 0, 2,
3, 1, 1, 3, 3, 2, 1, 2, 0, 2, 1, 0, 1, 2, 0, 2, 0, 1, 3, 0, 2, 0, 1,
3, 2, 2, 1, 3, 0, 3, 3], dtype=int32)
这已经给了我正确的解决方案。但是,如果unique
中的唯一数字非常稀疏且大,则此方法意味着创建一个非常大的table
数组,只是为了存储一些数字以便以后映射。
有没有更好的解决方案?
注意:A
和unique
都是示例数组,不是实数数组。所以问题不在于如何生成位置索引,而是如何有效地将A
的元素映射到unique
中的索引,伪代码我想要的内容numpy的加速如下,
B = np.zeros_like(A)
for i in range(A.size):
B[i] = unique.index(A[i])
(假设unique
是上述伪代码中的列表。)
答案 0 :(得分:4)
如果unique
非常密集,那么问题中描述的表格方法是最佳选择,但unique.searchsorted(A)
应该产生相同的结果并且不要求unique
密集。 searchsorted
对于int是很好的,如果有人试图使用具有精度限制的浮点数做这种事情,请考虑类似this的内容。
答案 1 :(得分:2)
您可以将标准python dict
与np.vectorize
inds = {e:i for i, e in enumerate(unique)}
B = np.vectorize(inds.get)(A)
答案 2 :(得分:2)
numpy_indexed包(免责声明:我是它的作者)包含一个vector.index的向量化等价物,它不需要与max元素成比例的内存,但只与输入本身成比例:
import numpy_indexed as npi
npi.indices(unique, A)
请注意,它也适用于任意dtypes和维度。此外,被查询的阵列不需要是唯一的;遇到的第一个索引将被返回,与列表相同。