给出以下数据框:
df = pd.DataFrame({'A' : ['1','2','3','7'],
'B' : [7,6,5,4],
'C' : [5,6,7,1],
'D' : [1,9,9,8]})
df=df.set_index('A')
df
B C D
A
1 7 5 1
2 6 6 9
3 5 7 9
7 4 1 8
我正在尝试计算compound annual growth rate (CAGR)。 我试图避免使用列名称。 这就是我想出的:
df['CAGR']=((df[df.columns[-1:]]/df[df.columns[:1]])**(1/len(df.columns)))-1
但是,它会抛出此错误:
ValueError: Wrong number of items passed 2, placement implies 1
我测试了公式的每个部分,它返回了我需要的列,所以我很难过。
提前致谢!
答案 0 :(得分:2)
您正在以DataFrame
DataFrame
df[df.columns[-1:]]
-1:
导致df.columns[-1:]
返回[column_name]
而不是column_name
。因此,df[df.columns[-1:]]
是DataFrame
。这意味着当你尝试进行除法时,pandas
会尝试排列索引,包括列。绕过这个。你刚刚完成了:
df[df.columns[-1]]
使用-1
代替-1:
但是,我会这样做。
df['CAGR'] = df.iloc[:, -1].div(df.iloc[:, 0]).pow(1./(len(df.columns) - 1)).sub(1)
print df
B C D CAGR
A
1 7 5 1 -0.622036
2 6 6 9 0.224745
3 5 7 9 0.341641
7 4 1 8 0.414214
答案 1 :(得分:1)
IIUC你想要每行df
df['CAGR'] = df.T.pct_change().add(1).prod().pow(1./(len(df.columns) - 1)).sub(1)
print df
B C D CAGR
A
1 7 5 1 -0.622036
2 6 6 9 0.224745
3 5 7 9 0.341641
7 4 1 8 0.414214
pandas
方法答案 2 :(得分:0)
在这些情况下,我通常将apply
方法用于Pandas数据帧,因为它使我可以在函数参数中拥有更大的灵活性。
例如以下功能:
def CAGR(x, last_col, first_col, num_periods):
""" Calculate compound growth rate on a row x of a pandas df"""
val_T = float(x[last_col])
val_t = x[first_col]
return (val_T/val_t)**(1./num_periods)-1
您都可以为列提供其位置或名称(这对您要在数据集的任意两个列上计算CAGR的情况可能很有用):
df = pd.DataFrame({
'A':['1','2','3','7'],
'B' : [7,6,5,4],
'C' : [5,6,7,1],
'D' : [1,9,9,8]
})
df=df.set_index('A')
CAGR_a = df.apply(
func=CAGR,
axis=1,
# positional arguments (i.e. order matters)
args=(df.columns[-1],df.columns[0], len(df.columns)-1)
)
CAGR_b = df.apply(
func=CAGR,
axis=1,
args=('D','B', len(df.columns)-1)
)
print(CAGR_a.equals(CAGR_b))
True
然后您将获得所需的结果:
df['CAGR'] = CAGR_a
print(df)
B C D CAGR
A
1 7 5 1 -0.622036
2 6 6 9 0.224745
3 5 7 9 0.341641
7 4 1 8 0.414214