计算 pandas 数据帧中频率不一致的 numpy IRR
calcualte numpy IRR with inconsistent frequencies across pandas data frame
我的问题不是关于如何计算 IRR(return 的内部利率),而是给出类似于下面的数据集,如何最好地计算 IRR 当样本量急剧增加时,无需等待几个月的结果。
我正在使用 np.irr
function
数据示例
import pandas as pd
import numpy as np
date_list =['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04','2018-01-05', '2018-01-06', '2018-01-07', '2018-01-14','2018-01-21', '2018-01-31','2018-02-08', '2018-02-28']
ids_list = [1,1,1,1,2,2,2,2,3,3,3,3]
flows_list = [ -10, 2, 2, 10, -50, 25, 20, 20, -100, 0, 3, 150]
df = pd.DataFrame(list(zip(date_list,ids_list,flows_list)), columns=['Date','ID','Flow'])
df['Date'] = pd.to_datetime(df['Date'],format='%Y-%m-%d')
产生以下数据集
In [144]: df
Out[144]:
Date ID Flow
0 2018-01-01 1 -10
1 2018-01-02 1 2
2 2018-01-03 1 2
3 2018-01-04 1 10
4 2018-01-05 2 -50
5 2018-01-06 2 25
6 2018-01-07 2 20
7 2018-01-14 2 20
8 2018-01-21 3 -100
9 2018-01-31 3 0
10 2018-02-08 3 3
11 2018-02-28 3 150
数据说明
Date
是现金流入或流出的日期
ID
本质上是每笔投资的唯一ID。
Flow
是那笔ID
(投资)的现金流。
我需要使用每日频率作为np.irr
的输入
如果我做一个简单的pandas.groupby
In [145]: df.groupby(['ID'])['Flow'].agg(np.irr)
Out[145]:
ID
1 0.141962
2 0.150155
3 0.153450
Name: Flow, dtype: float64
所以对于 ID
1,np.irr
returned 是有意义的,因为我的频率是一致的。
但是,对于其余部分,您会看到日期不是按天等间隔的。
'Manually' 计算 ID 3 np.irr
的示例
df.loc[df.ID ==3]['Date'].apply(lambda x: (x - min(df.loc[df.ID ==3]['Date'])).days)
8 0
9 10
10 18
11 38
Name: Date, dtype: int64
从上面可以看出,每笔现金流都发生在开始、10 日、18 日和最后 38 日。
cfs = np.zeros(39)
cfs[[0,10,18,38]] = df.loc[df.ID ==3]['Flow'].values
np.irr(cfs)
这会产生 实际 np.irr
for ID
3:
Out[155]: 0.011386397119650837
所以我的问题是:
How to calculate np.irr
across a pandas.DataFrame
where the cashflow frequencies are inconsistent in an optimal manner ?
这似乎是我能找到的最最佳和最准确的方法。避免 for 循环!!
加载示例数据
import pandas as pd
import numpy as np
date_list =['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04','2018-01-05', '2018-01-06', '2018-01-07', '2018-01-14','2018-01-21', '2018-01-31','2018-02-08', '2018-02-28']
ids_list = [1,1,1,1,2,2,2,2,3,3,3,3]
flows_list = [ -10, 2, 2, 10, -50, 25, 20, 20, -100, 0, 3, 150]
df = pd.DataFrame(list(zip(date_list,ids_list,flows_list)), columns=['Date','ID','Flow'])
df['Date'] = pd.to_datetime(df['Date'],format='%Y-%m-%d')
重新索引数据框以包括 0 的现金流量
def reindex_by_date_and_fill(df,groupby_column='ID',value_column='Flow'):
dates = pd.date_range(df.index.min(), df.index.max())
return pd.concat([df.reindex(dates)[groupby_column].ffill(),df.reindex(dates,fill_value=0)[value_column]],axis=1)
df_test = df.set_index(['Date']).groupby(['ID'],as_index=False).apply(reindex_by_date_and_fill).reset_index(0,drop=True)
我从以下两个帖子中得到了这个想法:
Add missing dates to pandas dataframe
基本上它会填补缺失的天数并将现金流填充为零。这使您能够获得每项投资的每日频率,同时仍保持现金流的偿还期。
In [54]: df_test.head(10)
Out[54]:
ID Flow
2018-01-01 1.0 -10
2018-01-02 1.0 2
2018-01-03 1.0 2
2018-01-04 1.0 10
2018-01-05 2.0 -50
2018-01-06 2.0 25
2018-01-07 2.0 20
2018-01-08 2.0 0
2018-01-09 2.0 0
2018-01-10 2.0 0
This Allows you then to use groupby
In [60]: df_test.groupby(['ID'])['Flow'].agg(np.irr)
Out[60]:
ID
1.0 0.141962
2.0 0.082212
3.0 0.011386
Name: Flow, dtype: float64
我的问题不是关于如何计算 IRR(return 的内部利率),而是给出类似于下面的数据集,如何最好地计算 IRR 当样本量急剧增加时,无需等待几个月的结果。
我正在使用 np.irr
function
数据示例
import pandas as pd
import numpy as np
date_list =['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04','2018-01-05', '2018-01-06', '2018-01-07', '2018-01-14','2018-01-21', '2018-01-31','2018-02-08', '2018-02-28']
ids_list = [1,1,1,1,2,2,2,2,3,3,3,3]
flows_list = [ -10, 2, 2, 10, -50, 25, 20, 20, -100, 0, 3, 150]
df = pd.DataFrame(list(zip(date_list,ids_list,flows_list)), columns=['Date','ID','Flow'])
df['Date'] = pd.to_datetime(df['Date'],format='%Y-%m-%d')
产生以下数据集
In [144]: df
Out[144]:
Date ID Flow
0 2018-01-01 1 -10
1 2018-01-02 1 2
2 2018-01-03 1 2
3 2018-01-04 1 10
4 2018-01-05 2 -50
5 2018-01-06 2 25
6 2018-01-07 2 20
7 2018-01-14 2 20
8 2018-01-21 3 -100
9 2018-01-31 3 0
10 2018-02-08 3 3
11 2018-02-28 3 150
数据说明
Date
是现金流入或流出的日期ID
本质上是每笔投资的唯一ID。Flow
是那笔ID
(投资)的现金流。我需要使用每日频率作为
np.irr
的输入
如果我做一个简单的pandas.groupby
In [145]: df.groupby(['ID'])['Flow'].agg(np.irr)
Out[145]:
ID
1 0.141962
2 0.150155
3 0.153450
Name: Flow, dtype: float64
所以对于 ID
1,np.irr
returned 是有意义的,因为我的频率是一致的。
但是,对于其余部分,您会看到日期不是按天等间隔的。
'Manually' 计算 ID 3 np.irr
的示例
df.loc[df.ID ==3]['Date'].apply(lambda x: (x - min(df.loc[df.ID ==3]['Date'])).days)
8 0
9 10
10 18
11 38
Name: Date, dtype: int64
从上面可以看出,每笔现金流都发生在开始、10 日、18 日和最后 38 日。
cfs = np.zeros(39)
cfs[[0,10,18,38]] = df.loc[df.ID ==3]['Flow'].values
np.irr(cfs)
这会产生 实际 np.irr
for ID
3:
Out[155]: 0.011386397119650837
所以我的问题是:
How to calculate
np.irr
across apandas.DataFrame
where the cashflow frequencies are inconsistent in an optimal manner ?
这似乎是我能找到的最最佳和最准确的方法。避免 for 循环!!
加载示例数据
import pandas as pd
import numpy as np
date_list =['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04','2018-01-05', '2018-01-06', '2018-01-07', '2018-01-14','2018-01-21', '2018-01-31','2018-02-08', '2018-02-28']
ids_list = [1,1,1,1,2,2,2,2,3,3,3,3]
flows_list = [ -10, 2, 2, 10, -50, 25, 20, 20, -100, 0, 3, 150]
df = pd.DataFrame(list(zip(date_list,ids_list,flows_list)), columns=['Date','ID','Flow'])
df['Date'] = pd.to_datetime(df['Date'],format='%Y-%m-%d')
重新索引数据框以包括 0 的现金流量
def reindex_by_date_and_fill(df,groupby_column='ID',value_column='Flow'):
dates = pd.date_range(df.index.min(), df.index.max())
return pd.concat([df.reindex(dates)[groupby_column].ffill(),df.reindex(dates,fill_value=0)[value_column]],axis=1)
df_test = df.set_index(['Date']).groupby(['ID'],as_index=False).apply(reindex_by_date_and_fill).reset_index(0,drop=True)
我从以下两个帖子中得到了这个想法:
Add missing dates to pandas dataframe
基本上它会填补缺失的天数并将现金流填充为零。这使您能够获得每项投资的每日频率,同时仍保持现金流的偿还期。
In [54]: df_test.head(10)
Out[54]:
ID Flow
2018-01-01 1.0 -10
2018-01-02 1.0 2
2018-01-03 1.0 2
2018-01-04 1.0 10
2018-01-05 2.0 -50
2018-01-06 2.0 25
2018-01-07 2.0 20
2018-01-08 2.0 0
2018-01-09 2.0 0
2018-01-10 2.0 0
This Allows you then to use
groupby
In [60]: df_test.groupby(['ID'])['Flow'].agg(np.irr)
Out[60]:
ID
1.0 0.141962
2.0 0.082212
3.0 0.011386
Name: Flow, dtype: float64