【问题标题】:Ranking across rows跨行排名
【发布时间】:2018-12-06 18:28:33
【问题描述】:

我的数据框如下所示:

      Date       AAPL      NFLX       INTC    AAPL_Ret   NFLX_Ret   INTC_Ret
0 2008-01-31  27.834286  3.764286  25.350000       
1 2008-02-29  27.847143  3.724286  24.670000   -0.07     0.25       -0.05     
2 2008-03-31  25.721428  3.515714  22.670000    0.15     0.10       0.06  
3 2008-04-30  25.377142  3.554286  22.879999    etc
4 2008-05-31  24.464285  3.328571  22.260000

我想计算 df 中各行的股票收益的分位数。因此,例如,分位数(假设我们使用 3 个组)会将第一行回报排名为分位数 3 中的 AAPL 和 INTC,以及分位数 1 中的 NFLX(因为它是最高回报)。预期的输出将是(下方,向右滚动):

      Date       AAPL       NFLX       INTC    AAPL_Ret   NFLX_Ret   INTC_Ret   AAPL_Ret Q   NFLX_Ret Q   INTC Ret Q
0 2008-01-31  27.834286  3.764286  25.350000       
1 2008-02-29  27.847143  3.724286  24.670000   -0.07     0.25       -0.05        3              1            3
2 2008-03-31  25.721428  3.515714  22.670000    0.15     0.10       0.06         1              2            2
3 2008-04-30  25.377142  3.554286  22.879999    etc
4 2008-05-31  24.464285  3.328571  22.260000

我尝试过的:我最初想在公式中使用 pd.qcut 和 axis=1 之类的东西,但该方法不接受这样的参数。所以我想我可以做一些类似 for 循环的事情(因为我最终会将文件扩展到许多股票)

for col in df.columns:
    if '_Ret' in col:
        df[col+'_Rank'] = df.apply(pd.qcut(df[col], 5, labels=np.arange(5, 0, -1), axis=1)

但我被困在这里了。

非常感谢您的帮助,我是 python 初学者。谢谢!

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    一种方法是使用filter 仅选择带有“_Ret”和stack 的列,使其成为一个能够在之后使用qcut 的系列。

    # I only copy the two rows with values in _Ret columns
    print (df.filter(like = '_Ret').stack())
    
    1  AAPL_Ret   -0.07
       NFLX_Ret    0.25
       INTC_Ret   -0.05
    2  AAPL_Ret    0.15
       NFLX_Ret    0.10
       INTC_Ret    0.06
    

    现在您可以在此系列上使用qcut,然后使用unstackadd_suffix 重命名:

    df_Q = (pd.qcut(df.filter(like = '_Ret').stack(), 3, labels=np.arange(3, 0, -1))
               .unstack().add_suffix(' Q'))
    
    print (df_Q)
      AAPL_Ret Q NFLX_Ret Q INTC_Ret Q
    1          3          1          3
    2          1          2          2
    

    只需join 与原始数据框,因为行数与原始数据相同。

    df = df.join(df_Q)
    

    给出预期的输出

    【讨论】:

    • 非常感谢本,精彩而优雅的回答,正是我们所需要的。
    猜你喜欢
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 2018-12-22
    • 2022-06-14
    • 1970-01-01
    • 2015-01-08
    • 2019-01-30
    • 1970-01-01
    相关资源
    最近更新 更多