如何在过滤后将Direct行Total值设为对应年份QS行的两倍?
解决过滤状态下基于对应行修改DataFrame值的问题
问题场景
你需要在满足Category='WC'、Year>2022、Code=1450的条件下,将Type='Direct'行的Total值设为同年份Type='QS'行Total值的两倍,但使用.loc直接赋值时目标行出现NaN。
原代码问题分析
你的代码中,WCdf的索引是[1,4](对应2023和2024年的QS行),而需要修改的目标行索引是[0,3](对应2024和2023年的Direct行)。Pandas赋值时会按索引对齐,目标行的索引在WCdf中不存在匹配项,因此赋值结果为NaN。
解决方案
以下是三种可行的实现方式:
方法1:用字典映射年份与QS值
先提取符合条件的QS行,创建年份到Total值的映射字典,再通过年份匹配赋值:
# 提取QS行并构建Year到Total的映射 qs_year_total = df[ (df.Category == 'WC') & (df.Year > 2022) & (df.Code == 1450) & (df.Type == 'QS') ].set_index('Year')['Total'].to_dict() # 筛选需要修改的Direct行,通过年份映射获取QS值并翻倍赋值 target_rows = ( df['Code'] == 1450 & df['Category'] == 'WC' & df['Year'] > 2022 & df['Type'] == 'Direct' ) df.loc[target_rows, 'Total'] = df.loc[target_rows, 'Year'].map(qs_year_total) * 2
方法2:通过合并DataFrame关联QS值
将QS行的数据合并到原DataFrame,直接引用对应年份的QS值进行计算:
# 提取QS行数据并重命名列 qs_data = df[ (df.Category == 'WC') & (df.Year > 2022) & (df.Code == 1450) & (df.Type == 'QS') ][['Year', 'Total']].rename(columns={'Total': 'QS_Total'}) # 合并数据到原DataFrame merged_df = df.merge(qs_data, on='Year', how='left') # 筛选目标行并更新Total值 target_rows = ( merged_df['Code'] == 1450 & merged_df['Category'] == 'WC' & merged_df['Year'] > 2022 & merged_df['Type'] == 'Direct' ) merged_df.loc[target_rows, 'Total'] = merged_df.loc[target_rows, 'QS_Total'] * 2 # 移除临时列,得到最终结果 df = merged_df.drop('QS_Total', axis=1)
方法3:按年份分组处理
通过groupby按年份分组,在组内直接将Direct行的Total设为QS行的两倍:
def update_direct_total(group): # 提取组内QS行的Total值 qs_val = group[group['Type'] == 'QS']['Total'].iloc[0] if len(group[group['Type'] == 'QS']) > 0 else None # 更新组内Direct行的Total group.loc[group['Type'] == 'Direct', 'Total'] = qs_val * 2 return group # 筛选需要处理的行,按年份分组处理 processed_group = df[ (df.Category == 'WC') & (df.Year > 2022) & (df.Code == 1450) ].groupby('Year').apply(update_direct_total) # 将处理后的数据更新回原DataFrame df.update(processed_group)
验证结果
执行上述任意方法后,目标行的Total值会正确更新为对应年份QS行的两倍,符合预期结果。
内容的提问来源于stack exchange,提问作者SaicheS
相关产品推荐
相关产品推荐

