You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于月周总和条件替换两个Pandas DataFrame的数值

问题描述

我有两个Pandas DataFrame:

  • 一个是按月份周数均分的DataFrame(2月分为4周,对应列Feb_1至Feb_4;3月分为5周,对应列Mar_5至Mar_9)
  • 另一个是存储实际数据的DataFrame,包含上述对应列的实际数值

需求如下:

  1. 针对2月的Feb_1至Feb_4列:若实际DataFrame中对应行的这4列数值总和为1,则用实际值替换均分DataFrame的对应数值;否则保留均分DataFrame的原有值。
  2. 针对3月的Mar_5至Mar_9列:若实际DataFrame对应行的这5列数值总和为1,同样用实际值替换均分DataFrame的对应数值;否则保留原有值。

我尝试了以下代码引入实际值,但没找到完整实现方式:

equally['Feb_1_actual'] = equally['Name'].map(actual.set_index('Name')['Feb_1'])
## then get a sum and if it's equal to 1 replace the value otherwise keep the same value
解决方案

可以通过布尔掩码+批量赋值的方式高效实现,无需单独处理每一列,步骤如下:

1. 对齐两个DataFrame(按Name列匹配)

先确保两个DataFrame通过Name列对齐,避免行不匹配的问题:

# 以均分DataFrame的Name为基准,合并实际数据到对应行
actual_aligned = actual.set_index('Name').reindex(equally['Name']).reset_index()

2. 处理2月列的替换逻辑

计算实际DataFrame中每行Feb_1至Feb_4的总和,生成布尔掩码后批量替换:

# 定义2月列名列表
feb_cols = ['Feb_1', 'Feb_2', 'Feb_3', 'Feb_4']
# 生成掩码:总和为1的行标记为True
feb_mask = actual_aligned[feb_cols].sum(axis=1) == 1
# 对符合条件的行,用实际值替换均分DataFrame的对应列
equally.loc[feb_mask, feb_cols] = actual_aligned.loc[feb_mask, feb_cols].values

3. 处理3月列的替换逻辑

和2月逻辑一致,仅调整列名列表即可:

# 定义3月列名列表
mar_cols = ['Mar_5', 'Mar_6', 'Mar_7', 'Mar_8', 'Mar_9']
# 生成3月列的掩码
mar_mask = actual_aligned[mar_cols].sum(axis=1) == 1
# 批量替换符合条件的行
equally.loc[mar_mask, mar_cols] = actual_aligned.loc[mar_mask, mar_cols].values

方案优势

  • 批量操作避免手动逐个处理列的繁琐,新增月份只需扩展列名列表即可,扩展性强
  • 利用Pandas原生的布尔掩码和.loc赋值,比循环行/列效率高很多,适配大数据量场景
  • 先对齐数据确保行匹配,避免因行顺序不一致导致的替换错误

内容的提问来源于stack exchange,提问作者rra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:50:44