我很好奇为什么这个在Pandas中同时执行布尔索引+赋值的玩具示例不起作用:
df = pd.DataFrame({'Source': ['A', 'B', 'C', 'A', 'B', 'C'],
'Period': ['1 hr', '1 hr', '1 hr', '24 hr', '24 hr', '24 hr'],
'CO': [1.1, 1.2, 1.3, 2.1, 2.2, 2.3],
'DPM': [11.1, 11.2, 11.3, 12.1, 12.2, 12.3],
'NOx': [21.1, 21.2, 21.3, 22.1, 22.2, 22.3]})
由此产生的玩具DataFrame在这里:
Source Period CO DPM NOx
0 A 1 hr 1.1 11.1 21.1
1 B 1 hr 1.2 11.2 21.2
2 C 1 hr 1.3 11.3 21.3
3 A 24 hr 2.1 12.1 22.1
4 B 24 hr 2.2 12.2 22.2
5 C 24 hr 2.3 12.3 22.3
现在,我希望最终的DataFrame取24 hr
值,并将其分配给源A和B的1 hr
值。最终的DataFrame应该如下所示:
Source Period CO DPM NOx
0 A 1 hr 2.1 12.1 22.1
1 B 1 hr 2.2 12.2 22.2
2 C 1 hr 1.3 11.3 21.3
3 A 24 hr 2.1 12.1 22.1
4 B 24 hr 2.2 12.2 22.2
5 C 24 hr 2.3 12.3 22.3
我尝试执行以下命令:
df.loc[df['Source'].isin(['A', 'B']) & (df['Period'] == '1 hr'), ['CO', 'DPM', 'NOx']] =
df.loc[df['Source'].isin(['A', 'B']) & (df['Period'] == '24 hr'), ['CO', 'DPM', 'NOx']]
但最后我的DataFrame被NaNs:取代了
Source Period CO DPM NOx
0 A 1 hr NaN NaN NaN
1 B 1 hr NaN NaN NaN
2 C 1 hr 1.3 11.3 21.3
3 A 24 hr 2.1 12.1 22.1
4 B 24 hr 2.2 12.2 22.2
5 C 24 hr 2.3 12.3 22.3
赋值的LHS和RHS上的筛选器表达式都用相同的行数正确地进行了筛选,似乎赋值就是它被丢弃的地方。我该如何正确地做到这一点?请注意,我只希望CO、DPM和NOx值发生变化,而不希望任何其他列发生变化。
问题是索引不匹配。您可以使用下面的numpy数组来解决这个问题:
msk = (df['Period'] == '24 hr')
cols = ['DPM', 'NOx']
df.loc[~msk & df['Source'].isin(['A','B']), cols] = df.loc[msk & df['Source'].isin(['A','B']), cols].to_numpy()
输出:
Source Period CO DPM NOx
0 A 1 hr 1.1 12.1 22.1
1 B 1 hr 1.2 12.2 22.2
2 C 1 hr 1.3 11.3 21.3
3 A 24 hr 2.1 12.1 22.1
4 B 24 hr 2.2 12.2 22.2
5 C 24 hr 2.3 12.3 22.3
注意,只有当";1小时";以及";24小时";对于每个";来源";类型
您也可以使用groupby
+last
:
cols = ['DPM', 'NOx']
filt = df['Source'].isin(['A','B'])
df.loc[filt, cols] = df[filt].groupby('Source')[cols].transform('last')