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

时间:2017-05-02 16:34:54

标签: python pandas multidimensional-array logic date-arithmetic

嗨我有一个庞大的数据框,其结构如下:

    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      .....
..

我想要的是每个股票代码:在每个行的上一个日历日期(t-1)和上一个日历日期(t-2)的资产和Ebitda中创建%更改的新列。

但问题出现了:

1)正如您所看到的,日历日期(通过自动收录器)并不总是唯一值,因为对于同一日历日期可能有更多的最后更新,但我总是希望自上次日历日期以来的更改而不是最后一次日期更新最后更新。

2)在这种情况下,存在具有0值的行我想使用最后观察到的值来计算%变化。如果我只有一个容易的股票,我只会填写价值,但由于我有很多代码,我无法安全地执行此操作,因为我可以将值从代码'a'填充到代码'b',这不是我想要的是什么

我想这可以解决创建一个if语句处理数据异常的函数,或者有一个很好的方法来处理这个内部pandas ...也许是多索引?事实是,我不知道如何处理这项任务,任何人都可以提供帮助?

由于

1 个答案:

答案 0 :(得分:5)

第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

注意: 'Ebitda'的第一个'b'NaN,因为没有任何内容可以转发。

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

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

第4步
再次 groupby,这一次只有'ticker'的{​​{1}}索引,并取d2

pct_change

第5步
d3 = d2.groupby(level='ticker').pct_change() 返回join

df