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

Pandas中使用.apply后列消失问题求助(附代码与预期结果)

Pandas合并后使用apply丢失原有列的问题分析与解决

原始数据

DataFrame 1: nopat

nopat
0 2021-12-31  3.580000e+09
1 2020-12-31  6.250000e+08
2 2019-12-31 -1.367000e+09
3 2018-12-31  2.028000e+09

DataFrame 2: capital_employed

capital_employed
0 2021-12-31      5.924000e+10
1 2020-12-31      6.062400e+10
2 2019-12-31      5.203500e+10
3 2018-12-31      5.441200e+10

你的代码

roce_by_year = pd.merge(nopat, capital_employed) \
        .rename(columns={"" : "date"}) \
        .sort_values(by='date') \
        .apply(lambda row: compute_roce(row['nopat'], row['capital_employed']), axis=1) \
        .reset_index(name='roce')

当前结果

index      roce
0      3  3.727119
1      2 -2.627078
2      1  1.030945
3      0  6.043214

期望结果

date       roce
0   2018  3.727119
1   2019 -2.627078
2   2020  1.030945
3   2021  6.043214

问题原因

  1. apply的返回值特性:当apply(axis=1)的lambda返回单个数值时,Pandas会返回一个Series而非保留原DataFrame结构,所有原有列会被直接丢弃,只剩下计算结果序列。
  2. 日期列处理错误:你试图用rename(columns={"" : "date"})将空列名改为date,但实际上原始数据中的日期是索引而非列,这一步并没有把索引转为正经的date列,后续排序后仍保留原数字索引,导致reset_index只能拿到数字索引而非日期。

解决方法

步骤1:先将索引转为日期列

合并前把两个DataFrame的索引转为名为date的列:

nopat = nopat.reset_index().rename(columns={'index': 'date'})
capital_employed = capital_employed.reset_index().rename(columns={'index': 'date'})

步骤2:新增ROCE列而非替换整个DataFrame

不要用apply直接覆盖原DataFrame,而是新增列存储计算结果:

# 合并并排序
roce_by_year = pd.merge(nopat, capital_employed, on='date') \
                .sort_values(by='date')

# 新增roce计算列
roce_by_year['roce'] = roce_by_year.apply(lambda row: compute_roce(row['nopat'], row['capital_employed']), axis=1)

# 格式化日期并保留需要的列
roce_by_year['date'] = roce_by_year['date'].dt.year
roce_by_year = roce_by_year[['date', 'roce']].reset_index(drop=True)

更高效的替代方案(跳过apply)

apply是逐行操作效率较低,建议直接用列运算(需确保compute_roce支持接收Series参数):

# 先处理索引转列
nopat = nopat.reset_index().rename(columns={'index': 'date'})
capital_employed = capital_employed.reset_index().rename(columns={'index': 'date'})

# 合并、排序、计算
roce_by_year = pd.merge(nopat, capital_employed, on='date').sort_values('date')
roce_by_year['roce'] = (roce_by_year['nopat'] / roce_by_year['capital_employed']) * 100  # 假设ROCE公式为(nopat/资本占用)*100
roce_by_year['date'] = roce_by_year['date'].dt.year
roce_by_year = roce_by_year[['date', 'roce']].reset_index(drop=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:55:17