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

4
我有一个1D的“from”数组(称之为“frm”),其中包含具有关联布尔掩码数组的值:“mask”(与“frm”形状相同)。然后我有第三个“replace”数组:“repl”,也是1D,但长度比其他两个数组都要短。
基于这些,我想生成一个新数组(“to”),其中包含“frm”值,除非在这种情况下“mask == True”,否则应该按顺序从“repl”中取值。 (请注意,“mask”中的“True”元素数等于“repl”的长度)。
我正在寻找一种“聪明”的numpy实现方式? 我看过像np.where,np.take,np.select,np.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)

产生结果:[1、200、3、400、500]

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

1个回答

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

然后to返回:

>>> to
array([  1, 200,   3, 400, 500])

pandas解决方案:

如果您的数据框如下所示:

>>> df
   column
0       1
1       2
2       3
3       4
4       5

然后您可以使用loc:
df.loc[mask,'column'] = repl

那么你的数据框看起来像这样:
>>> df
   column
0       1
1     200
2       3
3     400
4     500

关于numpy的解决方案:太棒了!我完全忽视了可以使用掩码进行索引并将其赋值给变量这一事实,而一直在寻找“特殊方法”!:-) - Hans Bouwmeester
关于Pandas解决方案:我知道可以使用“loc”来获取DataFrame的内容。据我所知,没有相应的方法来获取Axes(即“index”和“column”名称,而不是数据帧内部的实际值)。例如:df.columns[3]可以工作。但是df.columns[3] = "new-name"会出现TypeError: "Index does not support mutable operations"(这促使我将其带入numpy进行解决)。 - Hans Bouwmeester
哦,我猜我误解了你的意图......是的,最好还是用numpy来做,并将结果数组用作索引(如果我理解正确的话)。 - sacuL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接