基于条件实现两个不同DataFrame的乘法运算求助
问题描述
我有两个DataFrame:
df1:
year rate 2022 1.000 2023 1.015 2024 1.049 2025 1.084 2026 1.121 2027 1.158 2028 1.197 2029 1.237 2030 1.278 2031 1.321 2032 1.365
df2:
Name value code portion A 10 1 2 B 12 2 0
需要生成包含各年份计算列的结果,规则如下:
- 当
code为1时,年份值 =rate*(value-portion)+portion - 当
code为2时,年份值保持value不变
预期结果:
Name value code portion 2022 2023 ..... 2032 A 10 1 2 1.000*(10-2)+2 1.015*(10-2)+2 1.365*(10-2)+2 B 12 2 0 12 12 12 C 20 1 6 1.000*(20-6)+6 1.015*(20-6)+6 1.365*(20-6)+6 D 8 2 0 8 8 8
之前尝试的代码未成功:
df_multiply=df2['value'].apply(lambda x: x * df1['rate'])
解决方案
可以利用Pandas的广播运算结合条件判断实现,步骤如下:
- 转换df1的格式,让年份成为列名,便于后续批量计算:
rate_df = df1.set_index('year').T
- 分别计算两种code规则下的结果:
- 对于code=1的行,按公式
rate*(value-portion)+portion计算,通过广播实现每行与所有年份rate的运算 - 对于code=2的行,直接将value值重复对应年份的次数
- 对于code=1的行,按公式
import numpy as np # 计算code=1的结果 code1_result = rate_df * (df2['value'] - df2['portion']).values.reshape(-1,1) + df2['portion'].values.reshape(-1,1) # 计算code=2的结果 code2_result = pd.DataFrame([df2['value'].values]*len(rate_df.columns), columns=rate_df.columns, index=df2.index).T
- 用
np.where根据code值合并两种结果,再和原df2拼接得到最终数据:
year_columns = pd.DataFrame(np.where(df2['code'].values.reshape(-1,1)==1, code1_result, code2_result), columns=rate_df.columns, index=df2.index) final_df = pd.concat([df2, year_columns], axis=1)
- 如果需要加入预期结果中的C、D行,直接在df2中新增即可:
new_rows = pd.DataFrame([['C',20,1,6], ['D',8,2,0]], columns=df2.columns) df2 = pd.concat([df2, new_rows], ignore_index=True)
完整可运行代码:
import pandas as pd import numpy as np # 初始化原始数据 df1 = pd.DataFrame({ 'year': [2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032], 'rate': [1.000,1.015,1.049,1.084,1.121,1.158,1.197,1.237,1.278,1.321,1.365] }) df2 = pd.DataFrame({ 'Name': ['A','B'], 'value': [10,12], 'code': [1,2], 'portion': [2,0] }) # 新增C、D行 new_rows = pd.DataFrame([['C',20,1,6], ['D',8,2,0]], columns=df2.columns) df2 = pd.concat([df2, new_rows], ignore_index=True) # 转换rate格式 rate_df = df1.set_index('year').T # 计算两类结果 code1_result = rate_df * (df2['value'] - df2['portion']).values.reshape(-1,1) + df2['portion'].values.reshape(-1,1) code2_result = pd.DataFrame([df2['value'].values]*len(rate_df.columns), columns=rate_df.columns, index=df2.index).T # 合并条件结果并拼接原数据 year_columns = pd.DataFrame(np.where(df2['code'].values.reshape(-1,1)==1, code1_result, code2_result), columns=rate_df.columns, index=df2.index) final_df = pd.concat([df2, year_columns], axis=1) print(final_df)
内容的提问来源于stack exchange,提问作者sazaki
相关产品推荐
相关产品推荐

