用列表中的索引替换数组中的值

时间:2015-10-26 14:59:49

标签: python arrays numpy

在给定的数组中,我想在另一个数组(不包含重复项)中用该值的索引替换值。这是一个我想要做的简单例子:

import numpy as np
from copy import deepcopy

a = np.array([[0, 1, 2], [2, 1, 3], [0, 1, 3]])
chg = np.array([3, 0, 2, 1])

b = deepcopy(a)
for new, old  in enumerate(chg):
   b[a == old] = new

print b
# [[1 3 2] [2 3 0] [1 3 0]]

但我需要在大型数组上执行此操作,因此在执行时间方面无法接受显式循环。

我无法弄清楚如何使用花哨的numpy函数来做到这一点......

4 个答案:

答案 0 :(得分:2)

take是你的朋友。

a = np.array([[0, 1, 2], [2, 1, 3], [0, 1, 3]])
chg = np.array([3, 0, 2, 1])
inverse_chg=chg.take(chg)
print(inverse_chg.take(a))

给出:

[[1 3 2]
 [2 3 0]
 [1 3 0]]

或更直接使用花式索引:chg[chg][a],但inverse_chg.take(a)的速度提高了三倍。

答案 1 :(得分:2)

尽管你可以使用searchsorted

,这种类型的替换操作在使用NumPy时可能非常难以完成。
>>> s = np.argsort(chg)
>>> s[np.searchsorted(chg, a.ravel(), sorter=s).reshape(a.shape)]
array([[1, 3, 2],
       [2, 3, 0],
       [1, 3, 0]])

(注意:searchsorted不只是替换完全匹配,因此如果a中的值不在chg中,请务必小心......)

pandas有各种各样的工具可以使NumPy阵列上的这些操作更容易,并且对于更大的阵列来说可能更快/更大内存效率。对于此特定问题,可以使用pd.match

>>> pd.match(a.ravel(), chg).reshape(a.shape)
array([[1, 3, 2],
       [2, 3, 0],
       [1, 3, 0]])

此功能还允许您指定chg中缺少值时应填充的值。

答案 2 :(得分:2)

您可以通过在其末尾添加两个新轴将chg转换为3D数组,然后执行与a的匹配比较,这将带来NumPy's broadcasting给我们一个3D面具。接下来,沿着第一个轴获取掩码上的argmax以模拟"b[a == old] = new"。最后,使用a中的相应值替换沿该轴没有匹配的那些。实现看起来像这样 -

mask = a == chg[:,None,None]
out = mask.argmax(0)
invalid_pos = ~mask.max(0)
out[invalid_pos] = a[invalid_pos]

答案 3 :(得分:-2)

检查出来:

a = np.array([3,4,1,2,0])
b = np.array([[0,0],[0,1],[0,2],[0,3],[0,4]])

c = b[a]
print(c)

它让我回来了:

[[0 3]
 [0 4]
 [0 1]
 [0 2]
 [0 0]]

如果你正在使用numpy数组,你可以这样做。