考虑以下玩具示例:
df = pd.DataFrame([0,1,2,3,4,5,6], columns=['Value'])
df_subset = df.loc[[3,4,5]]
df.loc[df.Value % 2 == 0, 'Value'] = df_subset.Value * 10
df分配前:
0. 0
1. 1
2. 2
3. 3
4. 4
5. 5
6. 6
df分配后:
0. NaN
1. 1
2. NaN
3. 3
4. 40
5. 5
6. NaN
发生这种情况的原因如下:
- 只有掩码/布尔索引为true的项才会被修改,即只有偶数元素
- 这就是
idx=1
未设置为NaN的原因 - 没有出现在右侧索引中的任何索引都设置为NaN
然而,我想要实现的是相同的行为,而不将丢失的索引项设置为NaN,即
- 修改掩码为true的元素
- 对于这些元素:如果特定索引是
df.index
的一部分,则用df_subset
中的值替换df
中的值
所需输出:
0. 0
1. 1
2. 2
3. 3
4. 40
5. 5
6. 6
第一个想法是通过&
为逐位AND
链接两个掩码,因为使用了测试索引Index.isin
:
df = pd.DataFrame([0,1,2,3,4,5,6], columns=['Value'])
df_subset = df.loc[[3,4,5]]
mask = (df.Value % 2 == 0) & (df.index.isin([3,4,5]))
df.loc[mask, 'Value'] = df_subset.Value * 10
print (df)
Value
0 0
1 1
2 2
3 3
4 40
5 5
6 6
或者:
df = pd.DataFrame([0,1,2,3,4,5,6], columns=['Value'])
mask = (df.Value % 2 == 0) & (df.index.isin([3,4,5]))
df.loc[mask, 'Value'] *= 10
print (df)
Value
0 0
1 1
2 2
3 3
4 40
5 5
6 6
另一个想法是通过原始掩码过滤子集,并使用DataFrame.update
:
df = pd.DataFrame([0,1,2,3,4,5,6], columns=['Value'])
df_subset = df.loc[[3,4,5]]
df.update(df_subset.loc[df.Value % 2 == 0, 'Value'] * 10)
#alternative
#df.update(df_subset.loc[df_subset.Value % 2 == 0, 'Value'] * 10)
print (df)
Value
0 0.0
1 1.0
2 2.0
3 3.0
4 40.0
5 5.0
6 6.0