(Python)具有优先级数组

时间:2018-05-07 01:11:06

标签: python numpy

给定源数组

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中的多个条目映射到dstaccording to the docs中的相同条目,则未指定哪个来源条目将写入dst

  

对于高级分配,通常不保证迭代顺序。这意味着如果一个元素被设置多次,则无法预测最终结果。

如果我们另外给出一个优先数组

p = np.random.rand(*src.shape)

我们如何使用p来消除这种情况的歧义,即根据p编写具有最高优先级的条目?

1 个答案:

答案 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]]