【问题标题】:Filling a dataframe with elements from another dataframe and perform calculation用来自另一个数据框的元素填充数据框并执行计算
【发布时间】:2021-05-17 20:47:34
【问题描述】:

我正在尝试用 df2 的第一列填充 df1 的 ['A'] 列,并执行(5 年)滚动复合增长计算。但是当我在代码下面运行时,计算机进入了无限循环。我做错了什么?

import pandas as pd
import numpy as np

df1 = pd.DataFrame(np.random.randint(0,100,size=(15, 4)), columns=list('ABCD'))
df2 = pd.DataFrame(np.zeros((15, 4)), columns=list('ABCD'))
for ind in df1.index: 

    while len(df1.index) >(6+ind): 
        amount_start= df1.iloc[0+ind,0]
        amount_end = df1.iloc[6+ind,0]    
        df2['A'][ind] =((amount_start/amount_end)**(1/5))-1

----------更新------------------------ -----

所以只是为了解释得更好一点。我有一个多索引数据框,其中包含不同年份的不同代码,并希望为每个代码获取一个新的 CAGR 列(在本例中为 3y。Akshay 发布的代码效果很好,但由于它仅适用于一个代码,我将其更改为groupby 方法,但现在我无法将系列附加到我的 Dataframe。最好的方法是什么?我在下面附上了屏幕截图。

windows = df.groupby('Symbol').rolling(1+3) df2 = windows['Revenue'].apply(lambda x: (x.iloc[0]/x.iloc[-1])**(1/3)-1)

[CAG_3y][1]:https://i.stack.imgur.com/SgeNK.png

【问题讨论】:

  • 也许你的 while 循环中没有任何东西会改变 ind 的值,所以它永远不会退出。
  • 请提供预期的输出,谢谢!请阅读minimal reproducible example
  • 您要进行的计算究竟是什么? ind 的值永远不会改变,它始终是 1。您可能应该编辑您的问题,因为我很确定您要复制到 df2 的是 df1 中的(随机)值,而不是 df2 到 df1 中的零。
  • @norie,我对你的意思有点困惑ind never changes。有一个循环将ind 值修改为0-14 之间的值。 for ind in df1.index: 。澄清一下,谢谢!
  • 问题似乎出在while 循环内,其中ind 不会改变并且无限地保持等于0。是这个意思吗?

标签: python pandas loops


【解决方案1】:

IIUC,您正在尝试计算复合增长,超过大小为 5 的滚动窗口。

单列滚动窗口

这是您想要实现的目标吗?如果是,那么您可以使用pd.Series.rolling() 将您的 CAGR 函数应用于列/系列的滚动窗口。

windows = df1.A.rolling(5)
df2.A = windows.apply(lambda x: (x.iloc[0]/x.iloc[-1])**(1/5)-1)
df2.A
0          NaN
1          NaN
2          NaN
3          NaN
4     0.203404
5     0.100237
6     0.308324
7    -0.099169
8    -0.234710
9    -0.045973
10   -0.167447
11    0.218108
12    0.272260
13    0.043961
14   -0.234327
Name: A, dtype: float64

所有列的滚动窗口

rolling 方法的好处在于它也可用于pd.DataFrame.rolling() 的数据框,它可以一次应用于所有列。

windows = df1.rolling(5)  #df1 instead of df1['A']
windows.apply(lambda x: (x.iloc[0]/x.iloc[-1])**(1/5)-1)

注意:inf 值是因为您在数据帧中随机生成的 0 作为分母。 Nan 值是没有足够的先验窗口大小来计算 cagr 的值。但是如果你想在 rolling() 方法中使用一些参数,你可以避免这种情况。


详细功能

用滚动窗口查看列的原始、第一个、最后一个和复合值-

d = {'original A':df1.A, 
     'first': df1.A.rolling(5).apply(lambda x: x.iloc[0]),
     'last': df1.A.rolling(5).apply(lambda x: x.iloc[-1]),
     'first/last': df1.A.rolling(5).apply(lambda x: (x.iloc[0]/x.iloc[-1])),
     '(first/last)^power': df1.A.rolling(5).apply(lambda x: (x.iloc[0]/x.iloc[-1])**(1/5)),
     'CAGR': df1.A.rolling(5).apply(lambda x: (x.iloc[0]/x.iloc[-1])**(1/5)-1)
    }

pd.DataFrame(d)

【讨论】:

  • 我终于明白了你的答案,而且效果很好,但如果我的数据框不仅需要按年份排序,还需要按股票代码排序怎么办? .我可以使用 groupby 吗?股票代码年份 rev CAGR? Ticker1 2009 1000 Ticker1 2008 750 Ticker1 2007 600 Ticker1 2006 400 Ticker1 2004 440 Ticker1 2003 300 Ticker1 2002 100 Ticker1 2001 2006 22 Ticker2 2008 22 2007 42 2007 45 Ticker2 2006 56 Ticker2 2004 20 Ticker2 2003 5 Ticker2 2003 5 Ticker3 2019 400 Ticker3 2018 440 股票 3 2017 300 股票 3 2016 100 股票 3 2015 90 股​​票 3 2014 80
  • 您可以使用df.sort_values(['col1','col2'])对之后的数据框进行排序。阅读this了解更多详情。
  • 另外,很难理解在 cmets 中发布的数据。您可以将其发布到原始问题中吗?
猜你喜欢
  • 2019-08-09
  • 2018-04-20
  • 2023-04-08
  • 2022-12-09
  • 2021-05-14
  • 1970-01-01
  • 2018-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多