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

多DataFrame按ID/TOD加权求和优化及取最大结果方案咨询

问题描述

我有多个包含ID、TIME_OF_DAY(简称TOD)和数值列的DataFrame,需要为每个DataFrame的数值列赋予对应权重后,按ID与TOD维度做加权求和,示例如下:

权重0.2的DataFrame:

ID   TOD         M 
0    10   morning    1  
1    13   afternoon  3  
2    32   evening    2
3    10   evening    2

权重0.4的DataFrame:

ID   TOD         W 
0    10   morning    1  
1    13   morning    3  
2    32   afternoon  2
3    10   evening    3

加权求和结果:

ID   TOD         weighed_sum_mw
0    10   morning    (0.2*1 + 0.4*1)
1    10   evening    (0.2*2 + 0.4*3)
2    13   morning    (0.4*3)
3    13   afternoon  (0.2*3)
4    32   evening    (0.2*2)
5    32   afternoon  (0.4*2)

目前用多次合并的方法可行,但内存消耗极高,想找无需合并的实现方案;另外最终只需要保留每个ID对应加权和最大的TOD行,若加权和相同,优先级为Afternoon>Evening>Morning。当前处理4个各约1000万行的DataFrame,后续可能增加数量,现有代码如下:

merged_oc= pd.merge(dfs[0], dfs[3], on=['ID', 'TIME_OF_DAY'], suffixes=('_O', '_C'), how='outer')
merged_s = pd.merge(dfs[1], dfs[2], on=['ID', 'TIME_OF_DAY'], suffixes=('_W', 'M'), how='outer')

# merge and weighted sum of O and C
merged_oc['COUNTS_O_weighted_02']= merged_oc['COUNTS_O'].fillna(0).multiply(0.2)
merged_oc['COUNTS_C_weighted_04'] = merged_oc['COUNTS_C'].fillna(0).multiply(0.4)
merged_oc['COUNTS'] = merged_oc['COUNTS_O_weighted_02'] + merged_oc['COUNTS_C_weighted_04']
result_oc = merged_oc[['ID', 'TIME_OF_DAY', 'COUNTS', 'COUNTS_O_weighted_02', 'COUNTS_C_weighted_04']]

merged_s['COUNTS_W_weighted_04'] = merged_s['COUNTS_W'].fillna(0).multiply(0.4)
merged_s['COUNTS_M_weighted_04'] = merged_s['COUNTS_M'].fillna(0).multiply(0.4)
merged_s['COUNTS'] = merged_s['COUNTS_W_weighted_04'] + merged_s['COUNTS_M_weighted_04']
result_s = merged_s[['ID', 'TIME_OF_DAY', 'COUNTS', 'COUNTS_W_weighted_04', 'COUNTS_M_weighted_04']]

merged_final = pd.merge(result_oc, result_s, on=['ID', 'TIME_OF_DAY'], suffixes=('_OC', '_S'), how='outer')

merged_final['COUNTS_OC']= merged_final['COUNTS_OC'].fillna(0)
merged_final['COUNTS_S'] = merged_final['COUNTS_S'].fillna(0)
merged_final['WEIGHTED_SUM'] = merged_final['COUNTS_OC'] + merged_final['COUNTS_SESSION']
merged_final = merged_final[['ID', 'TIME_OF_DAY', 'WEIGHTED_SUM', 'COUNTS_O_weighted_02', 'COUNTS_C_weighted_04', 'COUNTS_W_weighted_04', 'COUNTS_M_weighted_04']].fillna(0)
解决方案

1. 低内存加权求和方案(避免多次合并)

核心思路是先对单个DataFrame做加权计算,再纵向合并所有处理后的结果,最后按ID和TIME_OF_DAY聚合求和,避免横向合并产生大量空值,大幅降低内存占用:

假设你有一个权重与DataFrame的映射列表,按实际情况调整权重和数值列名:

import pandas as pd

# 定义每个DataFrame对应的权重和数值列名
df_weight_map = [
    {'df': dfs[0], 'weight': 0.2, 'value_col': 'COUNTS_O'},
    {'df': dfs[1], 'weight': 0.4, 'value_col': 'COUNTS_W'},
    {'df': dfs[2], 'weight': 0.4, 'value_col': 'COUNTS_M'},
    {'df': dfs[3], 'weight': 0.4, 'value_col': 'COUNTS_C'},
]

processed_dfs = []
for item in df_weight_map:
    # 复制必要列,避免修改原DataFrame
    temp_df = item['df'][['ID', 'TIME_OF_DAY', item['value_col']]].copy()
    # 计算加权值,空值填0
    temp_df['weighted_value'] = temp_df[item['value_col']].fillna(0) * item['weight']
    # 重命名原数值列,保留加权明细
    temp_df.rename(columns={item['value_col']: f"{item['value_col']}_weighted_{str(item['weight']).replace('.', '')}"}, inplace=True)
    processed_dfs.append(temp_df)

# 纵向合并所有处理后的DataFrame
combined_df = pd.concat(processed_dfs, ignore_index=True)

# 按ID和TIME_OF_DAY聚合,求和加权值及各明细项
final_sum_df = combined_df.groupby(['ID', 'TIME_OF_DAY'], as_index=False).sum()
# 提取总加权和
final_sum_df['WEIGHTED_SUM'] = final_sum_df['weighted_value']

2. 筛选每个ID的最优TOD行

按规则筛选每个ID的最优行:优先按WEIGHTED_SUM降序,加权和相同时按TOD优先级排序:

# 定义TOD优先级映射,数值越小优先级越高
tod_priority = {'afternoon': 0, 'evening': 1, 'morning': 2}
# 添加优先级列
final_sum_df['tod_rank'] = final_sum_df['TIME_OF_DAY'].map(tod_priority)

# 排序:先按ID升序,再按WEIGHTED_SUM降序,最后按tod_rank升序
final_sum_df.sort_values(by=['ID', 'WEIGHTED_SUM', 'tod_rank'], ascending=[True, False, True], inplace=True)

# 每个ID只保留第一行(即最优行)
result = final_sum_df.groupby('ID').first().reset_index()

# 按需移除辅助列
result.drop('tod_rank', axis=1, inplace=True)

方案优势

  • 内存效率高:纵向合并+分组求和的方式,避免了横向合并产生的大量空值,内存占用仅为原合并方案的几分之一
  • 扩展性强:后续新增DataFrame时,只需在df_weight_map中添加对应配置即可,无需修改核心逻辑
  • 计算速度快:分组求和的运算效率远高于多次合并操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:49:56