numpy 会在现有重复索引时保持分配顺序吗?



我想按索引数组为数组赋值,但有重复的索引。

例如:

a = np.arange(5)
index = np.array([1,2,3,1,2,3,1,2,3])
b = np.arange(9)
a[index] = b

两个问题:

  1. 对于重复的索引,最新的分配是否始终有效?

    a[1] == 6适用于任何情况,例如对于非常大的数组a?可以a[1] == 0还是3

    更具体地说,我使用了用MKL(由Anaconda提供)编译的numpy,一些数组操作是并行的。

    相关文章: 处理 NumPy 赋值中的重复索引

  2. 如果上面的答案是否定的,有什么可以确保作业始终保持有序吗?

这里有一种方法可以保证从相同的索引组中分配到最后一个索引 -

# Get sorting indices for index keeping the order with 'mergesort' option
sidx = index.argsort(kind='mergesort')
# Get sorted index array
sindex = index[sidx]
# Get the last indices from each group of identical indices in sorted version
idx = sidx[np.r_[np.flatnonzero(sindex[1:] != sindex[:-1]), index.size-1]]
# Use those last group indices to select indices off index and b to assign
a[index[idx]] = b[idx]

示例运行 -

In [141]: a
Out[141]: array([0, 1, 2, 3, 4])
In [142]: index
Out[142]: array([1, 2, 3, 1, 2, 1, 2, 3, 4, 2])
In [143]: b
Out[143]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [144]: sidx = index.argsort(kind='mergesort')
...: sindex = index[sidx]
...: idx = sidx[np.r_[np.flatnonzero(sindex[1:] != sindex[:-1]), index.size-1]]
...: a[index[idx]] = b[idx]
...: 
In [145]: a
Out[145]: array([0, 5, 9, 7, 8])

一个更简单的等价物,类似于Divakar的解决方案。

def assign_last(a, index, b):
"""a[index] = b
"""
index = index[::-1]
b = b[::-1]
ix_unique, ix_first = np.unique(index, return_index=True)
# np.unique: return index of first occurrence.
# ix_unique = index[ix_first]
a[ix_unique] = b[ix_first]
return a
a =  array([0, 1, 2, 3, 4])
index = array([1, 2, 3, 1, 2, 1, 2, 3, 4, 2])
b = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
assign_last(a, index, b)

输出

array([0, 5, 9, 7, 8])

最新更新