如何用另一布尔pandas Series替换目标Series的指定子集?
问题:用布尔型Series
t替换Series s的指定子集 给定两个布尔型pandas Series s和t,需要用t的值替换s中值为False的元素。示例如下:
>>> s = pd.Series([True, False, False, True, True, False]) >>> t = pd.Series([True, True, False]) >>> s 0 True 1 False 2 False 3 True 4 True 5 False dtype: bool >>> t 0 True 1 True 2 False dtype: bool
预期替换后输出:
>>> s 0 True 1 True 2 True 3 True 4 True 5 False dtype: bool
即s中值为False的索引[1,2,5]需要替换为t的[True,True,False]。
尝试用布尔掩码替换时出现异常:
>>> s[~s] = t >>> s 0 True 1 True 2 False 3 True 4 True 5 NaN dtype: object
使用s.mask(~s, t)也得到类似结果,索引5出现NaN,想知道原因,同时希望找到更简洁的实现方式(目前用iloc的方式比较迂回):
>>> s.iloc[s[~s].index] = t >>> s 0 True 1 True 2 True 3 True 4 True 5 False dtype: bool
为什么布尔掩码替换会失效?
pandas赋值时遵循索引对齐规则:s[~s]对应的索引是[1,2,5],而t的索引是[0,1,2],两者索引不匹配:
t的索引0对应s的索引1,所以s[1]被替换为t[0](True)t的索引1对应s的索引2,所以s[2]被替换为t[1](True)t没有索引5对应的值,因此s[5]无法匹配,被赋值为NaN
同时,NaN的引入会让Series的 dtype 从bool自动转为object,进一步偏离预期。
更简洁的实现方法
方法1:直接使用t的数值数组
跳过索引对齐,直接取t的底层数值按顺序填充:
s[~s] = t.values
测试结果:
>>> s = pd.Series([True, False, False, True, True, False]) >>> t = pd.Series([True, True, False]) >>> s[~s] = t.values >>> s 0 True 1 True 2 True 3 True 4 True 5 False dtype: bool
方法2:重置t的索引后赋值
将t的索引设置为s中需要替换的目标索引,实现精准匹配:
s[~s] = t.set_index(s[~s].index)
这种方式同样能得到预期结果,适合需要保留索引关联的场景。
内容的提问来源于stack exchange,提问作者hwhap
相关产品推荐
相关产品推荐

