给定源数组
src = np.random.rand(320,240)
和索引数组
idx = np.indices(src.shape).reshape(2, -1)
np.random.shuffle(idx.T)
我们可以通过
将i
中的线性索引src
映射到目标数组idx[:,i]
中的二维索引dst
dst = np.empty_like(src)
dst[tuple(idx)] = src.ravel()
这在Python: Mapping between two arrays with an index array
中讨论但是,如果此映射不是1对1,即src
中的多个条目映射到dst
,according to the docs中的相同条目,则未指定哪个来源条目将写入dst
:
对于高级分配,通常不保证迭代顺序。这意味着如果一个元素被设置多次,则无法预测最终结果。
如果我们另外给出一个优先数组
p = np.random.rand(*src.shape)
我们如何使用p
来消除这种情况的歧义,即根据p
编写具有最高优先级的条目?
答案 0 :(得分:2)
这是一种使用稀疏矩阵进行排序的方法(它具有较大的开销,但比argsort更好地扩展,可能是因为它使用了一些像方法(?)那样的基数排序)。没有优先级的重复索引显式设置为-1。我们使目标数组一个单元格太大,剩余单元格作为垃圾桶。
import numpy as np
from scipy import sparse
N = 2
idx = np.random.randint(0, N, (2, N, N))
prec = np.random.random((N, N))
src = np.arange(N*N).reshape(N, N)
def f_sparse(idx, prec, src):
idx = np.ravel_multi_index(idx, src.shape).ravel()
sp = sparse.csr_matrix((prec.ravel(), idx, np.arange(idx.size+1)),
(idx.size, idx.size)).tocsc()
top = sp.indptr.argmax()
mx = np.repeat(np.maximum.reduceat(sp.data, sp.indptr[:top]),
np.diff(sp.indptr[:top+1]))
res = idx.copy()
res[sp.indices[sp.data != mx]] = -1
dst = np.full((idx.size + 1,), np.nan)
dst[res] = src.ravel()
return dst[:-1].reshape(src.shape)
print(idx)
print(prec)
print(src)
print(f_sparse(idx, prec, src))
示例运行:
[[[1 0]
[1 0]]
[[0 1]
[0 0]]]
[[0.90995366 0.92095225]
[0.60997092 0.84092015]]
[[0 1]
[2 3]]
[[ 3. 1.]
[ 0. nan]]