熊猫用切片计算CAGR

时间:2016-05-20 21:12:18

标签: python-3.x numpy pandas

给出以下数据框:

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

我测试了公式的每个部分,它返回了我需要的列,所以我很难过。

提前致谢!

3 个答案:

答案 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

解释

  1. 转置使用其他简单的pandas方法
  2. pct_change然后加回1
  3. 乘以所有
  4. 扎根。注意,这需要比观察数少1。由于回报需要2次观察。

答案 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