【问题标题】:DataFrame calculating by group for log return of each stockDataFrame 按组计算每只股票的对数回报
【发布时间】:2018-09-12 17:39:51
【问题描述】:

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

         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

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

我当前的代码是:

df["logret"] = df.groupby("ticker").apply(np.log(df.price) - np.log(df.price.shift(1)))

但它向我抛出了一个错误消息,即 Series 对象是可变的,因此它们不能被散列。

有人可以向我解释一下这个错误指向什么吗?以及如何解决它以便能够通过每只股票的股票代码名称计算日志回报?

【问题讨论】:

  • 以下解决方案之一有帮助吗?如果是这样,请考虑接受(左侧的绿色勾号),以便其他用户知道。

标签: python python-3.x pandas dataframe


【解决方案1】:

我认为需要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

【讨论】:

  • 我也不知道,已经赞成这个答案,所以我会尝试帮助另一个人至少让你的观点回来:-)
  • 这个答案很有用,我也不懂投反对票。
【解决方案2】:

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

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

res.loc[res['ticker'] == res['ticker'].shift(), 'logret'] = \
np.log(df['price']) - np.log(df['price'].shift())

结果

         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

说明

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

【讨论】:

  • 谢谢你,太好了。请问我是否有一个预定义的列表,比如按 ["CAT","AI","BOC"] 顺序排列的前 3 只股票,如何创建一个 res 来按顺序对股票行列进行排序上面的预定义列表显示了吗?谢谢
  • @cqstack,我建议您提出一个单独的问题,以便其他用户受益。
【解决方案3】:

我会做pct_change 导致 log(a)-log(b)=log(a/b)

np.log(df.groupby('ticker').price.pct_change().add(1))
Out[729]: 
0         NaN
1    0.142093
2   -0.377978
3         NaN
4    0.018780
5    0.267717
6         NaN
7   -0.043036
8    0.002006
Name: price, dtype: float64

【讨论】:

    【解决方案4】:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 2011-03-15
      相关资源
      最近更新 更多