运行 如何在 python 中对 groupby 执行更复杂的聚合函数

How do you run more complex aggregation functions on groupby in python

python 初学者。只是将 spyder 用于一些与财务相关的工作。我可以在下面使用一些指导。我什至没有尝试过代码,因为我不知道从什么开始。

我有一个 pandas 数据框是这样组织的

Month, portfolio name, return

月份的格式为 201501,201502。 return 是一个百分比。我有几十万个观察。

我想每天早上在投资组合名称级别生成统计数据 - 总计 return、return 在特定时期内、滚动数量、整个时期内的最大回撤等。

从高层次上讲,执行此操作的最佳方法是什么?我觉得我需要做的是按投资组合名称分组,并应用不同的功能,这些功能要么存在于某些统计数据或财务包中,要么我可以自己编写,但由于某种原因在实践中找不到很好的例子。此外,对于在此期间的最大缩减之类的情况,观察的顺序很重要 - 当我们分组时我是否需要在这里做一些不同的事情,或者 pandas 只要它在日期时间就按顺序读取它?

再次寻求有关上述内容的一般性建议,以及正确方向的指示。也许当我接近时,我可以在此处使用代码进行故障排除。

提前感谢您的任何回复。这是我的第一个 post,这个网站帮助我在 6 年多的时间里一直在回答 excel 问题。

数据样本
月,PORTFOLIO_NAME,RETURN
201501,PORT1,0.014
201502,PORT1,0.0034
201503,PORT1,-0.0045
201501,PORT2,0.012
201502,PORT2,0.0054
201503,PORT2,-0.0174

编辑:我了解了 pandas 的 rolling() 和 expanding() 功能,现在对它们有了更多的了解。我也没有将 AGG() 用于自定义函数。请参阅下文,我是如何针对几个不同的指标为每个投资组合创建汇总的。我有任何具体问题,我会提出一个新的 post。谢谢

    import numpy as np
import pandas as pd

def rolled_ret(arr):
    return arr.add(1).prod() -1
def ann_vol(arr):
    return np.std(arr) * np.sqrt(12)
def max_drawdown(arr):
    return arr.add(1).cumprod().diff().min()

full_return = df_final.groupby('PORTFOLIO_NAME')['RETURN'].agg(full_period_returns=rolled_ret,annualised_vol=ann_vol,MDD=max_drawdown)

以下是我的处理方式:

# Convert Month to datetime
df["MONTH"] = pd.to_datetime(df["MONTH"], format="%Y%m")

# create a new column with your period
df["PERIOD"] = df["MONTH"].dt.to_period("m")

# Now aggregate per period:
df.groupby(["PORTFOLIO_NAME","PERIOD"]).agg([("total",sum),("min",min),("max",max)])


|                                   |   ('RETURN', 'total') |   ('RETURN', 'min') |   ('RETURN', 'max') |
|:----------------------------------|----------------------:|--------------------:|--------------------:|
| ('PORT1', Period('2015-01', 'M')) |                0.014  |              0.014  |              0.014  |
| ('PORT1', Period('2015-02', 'M')) |                0.0034 |              0.0034 |              0.0034 |
| ('PORT1', Period('2015-03', 'M')) |               -0.0045 |             -0.0045 |             -0.0045 |
| ('PORT2', Period('2015-01', 'M')) |                0.012  |              0.012  |              0.012  |
| ('PORT2', Period('2015-02', 'M')) |                0.0054 |              0.0054 |              0.0054 |
| ('PORT2', Period('2015-03', 'M')) |               -0.0174 |             -0.0174 |             -0.0174 |