DataFrame按组计算每个股票的日志退货

cqs*_*ack 10 python dataframe python-3.x pandas

作为一个例子,我创建了一个如下所示的数据框:

         date  price ticker  volume
0  2018-01-01  1.323     AI    2000
1  2018-01-02  1.525     AI    1500
2  2018-01-03  1.045     AI     500
3  2018-01-01  2.110    BOC    3201
4  2018-01-02  2.150    BOC    5200
5  2018-01-03  2.810    BOC    1980
6  2018-01-01  5.199    CAT    2000
7  2018-01-02  4.980    CAT     450
8  2018-01-03  4.990    CAT    3000
Run Code Online (Sandbox Code Playgroud)

所以有3只股票,跨越三天.我想计算2018-01-01和2018-01-03之间每只股票的每日日志回报.

我目前的代码是:

df["logret"] = df.groupby("ticker").apply(np.log(df.price) - np.log(df.price.shift(1)))
Run Code Online (Sandbox Code Playgroud)

但它给我一个错误信息,即Series对象是可变的,因此它们不能被散列.

有人可以向我解释这个错误指向的是什么?如何解决它能够通过每个股票的股票名称来计算日志回报?

piR*_*red 8

np.log然后groupbydiff

df.assign(logret=np.log(df.price).groupby(df.ticker).diff())

         date  price ticker  volume    logret
0  2018-01-01  1.323     AI    2000       NaN
1  2018-01-02  1.525     AI    1500  0.142093
2  2018-01-03  1.045     AI     500 -0.377978
3  2018-01-01  2.110    BOC    3201       NaN
4  2018-01-02  2.150    BOC    5200  0.018780
5  2018-01-03  2.810    BOC    1980  0.267717
6  2018-01-01  5.199    CAT    2000       NaN
7  2018-01-02  4.980    CAT     450 -0.043036
8  2018-01-03  4.990    CAT    3000  0.002006
Run Code Online (Sandbox Code Playgroud)


jez*_*ael 6

我认为需要lambda功能:

df["logret"] = df.groupby("ticker")['price'].apply(lambda x: np.log(x) - np.log(x.shift()))
print (df)
         date  price ticker  volume    logret
0  2018-01-01  1.323     AI    2000       NaN
1  2018-01-02  1.525     AI    1500  0.142093
2  2018-01-03  1.045     AI     500 -0.377978
3  2018-01-01  2.110    BOC    3201       NaN
4  2018-01-02  2.150    BOC    5200  0.018780
5  2018-01-03  2.810    BOC    1980  0.267717
6  2018-01-01  5.199    CAT    2000       NaN
7  2018-01-02  4.980    CAT     450 -0.043036
8  2018-01-03  4.990    CAT    3000  0.002006
Run Code Online (Sandbox Code Playgroud)


jpp*_*jpp 5

您可以通过矢量化方法执行此计算:

res = df.sort_values(['ticker', 'date'])

res.loc[res['ticker'] == res['ticker'].shift(), 'logret'] = \
np.log(df['price']) - np.log(df['price'].shift())
Run Code Online (Sandbox Code Playgroud)

结果

         date  price ticker  volume    logret
0  2018-01-01  1.323     AI    2000       NaN
1  2018-01-02  1.525     AI    1500  0.142093
2  2018-01-03  1.045     AI     500 -0.377978
3  2018-01-01  2.110    BOC    3201       NaN
4  2018-01-02  2.150    BOC    5200  0.018780
5  2018-01-03  2.810    BOC    1980  0.267717
6  2018-01-01  5.199    CAT    2000       NaN
7  2018-01-02  4.980    CAT     450 -0.043036
8  2018-01-03  4.990    CAT    3000  0.002006
Run Code Online (Sandbox Code Playgroud)

解释

  • 首先按ticker和对数据框进行排序date
  • 然后在连续行具有相同的ticker.
  • 矢量化比通过 一次计算一个结果更有效lambda