运行 如何在 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 |
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 |