使用掩码和其他数组替换数组中的值

Han*_*ter 4 python arrays indexing numpy pandas

我有一个一维“from”数组(称为frm),其中包含具有关联布尔掩码数组的值:mask ” (与frm形状相同)。然后我有第三个“替换”数组:repl,也是一维的,但长度比其他两个短。

有了这些,我想生成一个新数组(" to "),其中包含frm值,但mask==True除外,在这种情况下,它应该按顺序获取 repl中的值。(请注意, mask中True元素的数量等于repl的长度)。

我一直在寻找一种“聪明的”numpy 方式来实现这个?我查看了np.wherenp.takenp.selectnp.choose等方法,但似乎没有一个“符合要求”?

“切入代码”,这就是我到目前为止所拥有的。它工作正常,但看起来不像“Numpythonic”?(甚至是Pythonic)

frm  = [1, 2, 3, 4, 5]
mask = [False, True, False, True, True]
repl = [200, 400, 500]
i = 0; to = []
for f,m in zip(frm,mask):
    if m:
        to.append(repl[i])
        i += 1
    else:
        to.append(f)
print(to)
Run Code Online (Sandbox Code Playgroud)

产量:[1, 200, 3, 400, 500]

背景:我需要这样做的原因是因为我是 Pandas pd.Dataframe类的子类,并且需要列/索引的“setter”。由于pd.Index不能“切片索引”,我需要首先复制索引/column 数组,根据掩码替换副本中的一些元素,然后让setter设置完整的新值。如果有人知道更优雅的解决方案,请告诉我)。

sac*_*cuL 5

numpy解决方案:

它非常简单,如下所示:

# convert frm to a numpy array:
frm = np.array(frm)
# create a copy of frm so you don't modify original array:
to = frm.copy()

# mask to, and insert your replacement values:
to[mask] = repl
Run Code Online (Sandbox Code Playgroud)

然后to返回:

>>> to
array([  1, 200,   3, 400, 500])
Run Code Online (Sandbox Code Playgroud)

pandas解决方案:

如果你的数据框看起来像:

>>> df
   column
0       1
1       2
2       3
3       4
4       5
Run Code Online (Sandbox Code Playgroud)

然后你可以使用loc

df.loc[mask,'column'] = repl
Run Code Online (Sandbox Code Playgroud)

那么你的数据框看起来像:

>>> df
   column
0       1
1     200
2       3
3     400
4     500
Run Code Online (Sandbox Code Playgroud)