Skip to main content
 首页 » 编程设计

python之Pandas 数据框将逻辑应用于列计算

2025年05月04日24zfyouxi

您好,我有一个具有以下结构的巨大数据框:

    ticker  calendar-date     last-update   Assets    Ebitda  ..... 
0   a       2001-06-30        2001-09-14    110       1000    ..... 
1   a       2001-09-30        2002-01-22    0         -8      ..... 
2   a       2001-09-30        2002-02-01    0         800     ..... 
3   a       2001-12-30        2002-03-06    120       0       ..... 
4   b       2001-06-30        2001-09-18    110       0       ..... 
5   b       2001-06-30        2001-09-27    110       30      ..... 
6   b       2001-09-30        2002-01-08    140       35      ..... 
7   b       2001-12-30        2002-03-08    120       40      ..... 
.. 

我想要的是每个代码:创建新列,其中每一行的 Assets 和 Ebitda 从最后一个日历日期 (t-1) 和最后一个日历日期 (t-2) 开始变化。

但是问题来了:

1) 如您所见,日历日期(按代码)并不总是唯一值,因为同一日历日期可以有更多的最后更新,但我总是希望自上一个日历日期以来发生变化,而不是从上一个发生变化最后更新。

2) 在这种情况下,有些行的值为 0,我想使用最后观察到的值来计算变化百分比。如果我只有一只很容易的股票,我只会填充这些值,但由于我有很多代码,我无法安全地执行此操作,因为我可以将代码“a”的值填充到代码“b”,但事实并非如此我想要什么

我想这可以通过创建一个带有 if 语句的函数来处理数据异常来解决,或者也许有一种在 pandas 中处理这个问题的好方法......也许是多索引?事实是我不知道如何完成这项任务,有人可以帮忙吗?

谢谢

请您参考如下方法:

第 1 步
sort_values 以确保为以后的操作正确排序

icols = ['ticker', 'calendar-date', 'last-update'] 
df.sort_values(icols, inplace=True) 

第 2 步
groupby 'ticker' 和replace 零和正向填充

vcols = ['Assets', 'Ebitda'] 
temp = df.groupby('ticker')[vcols].apply(lambda x: x.replace(0, np.nan).ffill()) 
d1 = df.assign(**temp.to_dict('list')) 
d1 
 
  ticker calendar-date last-update  Assets  Ebitda 
0      a    2001-06-30  2001-09-14   110.0  1000.0 
1      a    2001-09-30  2002-01-22   110.0    -8.0 
2      a    2001-09-30  2002-02-01   110.0   800.0 
3      a    2001-12-30  2002-03-06   120.0   800.0 
4      b    2001-06-30  2001-09-18   110.0     NaN 
5      b    2001-06-30  2001-09-27   110.0    30.0 
6      b    2001-09-30  2002-01-08   140.0    35.0 
7      b    2001-12-30  2002-03-08   120.0    40.0 

注意 'b' 的第一个 'Ebitda' 是 NaN 因为没有要转发的内容填写自。

第 3 步
groupby ['ticker', 'calendar-date'] 并获取最后一列。因为我们在上面排序,所以最后一行将是最近更新的行。

d2 = d1.groupby(icols[:2])[vcols].last() 

第 4 步
再次 groupby,这次只是 d2 索引中的 'ticker',并采用 pct_change

d3 = d2.groupby(level='ticker').pct_change() 

第 5 步
加入 df

df.join(d3, on=icols[:2], rsuffix='_pct') 
 
  ticker calendar-date last-update  Assets  Ebitda  Assets_pct  Ebitda_pct 
0      a    2001-06-30  2001-09-14     110    1000         NaN         NaN 
1      a    2001-09-30  2002-01-22       0      -8    0.000000   -0.200000 
2      a    2001-09-30  2002-02-01       0     800    0.000000   -0.200000 
3      a    2001-12-30  2002-03-06     120       0    0.090909    0.000000 
4      b    2001-06-30  2001-09-18     110       0         NaN         NaN 
5      b    2001-06-30  2001-09-27     110      30         NaN         NaN 
6      b    2001-09-30  2002-01-08     140      35    0.272727    0.166667 
7      b    2001-12-30  2002-03-08     120      40   -0.142857    0.142857