【问题标题】:Iterating over columns in a dataframe to run/append calculation迭代数据框中的列以运行/追加计算
【发布时间】:2018-06-23 09:24:47
【问题描述】:

我的数据框类型:

        Date       AAPL      NFLX       INTC  
0 2008-01-02  27.834286  3.764286  25.350000    
1 2008-01-03  27.847143  3.724286  24.670000    
2 2008-01-04  25.721428  3.515714  22.670000   
3 2008-01-07  25.377142  3.554286  22.879999    
4 2008-01-08  24.464285  3.328571  22.260000    

我想对每列中的每只股票运行 .pct_change(1),并将 3 列附加到 df 的末尾。

当我已经知道列的名称时,我知道该怎么做,比如 AAPL。有了这些先验知识,我可以做 df['AAPL_Ret'] = df.AAPL.pct_change(1)

但最终,我将在文件中包含 100 支股票,目标是自动计算,而无需在代码中单独键入每个股票代码。所以我必须遍历所有列,然后以某种方式运行 .pct_change 。

有什么想法吗?非常感谢。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    请注意,pct_changeperiod 参数默认为 1,可以省略。

    drop'Date' 专栏

    df.join(df.drop('Date', 1).pct_change().add_suffix('_Ret'))
    
            Date       AAPL      NFLX       INTC  AAPL_Ret  NFLX_Ret  INTC_Ret
    0 2008-01-02  27.834286  3.764286  25.350000       NaN       NaN       NaN
    1 2008-01-03  27.847143  3.724286  24.670000  0.000462 -0.010626 -0.026824
    2 2008-01-04  25.721428  3.515714  22.670000 -0.076335 -0.056003 -0.081070
    3 2008-01-07  25.377142  3.554286  22.879999 -0.013385  0.010971  0.009263
    4 2008-01-08  24.464285  3.328571  22.260000 -0.035972 -0.063505 -0.027098
    

    set_index

    df.join(df.set_index('Date').pct_change().add_suffix('_Ret'), on='Date')
    
            Date       AAPL      NFLX       INTC  AAPL_Ret  NFLX_Ret  INTC_Ret
    0 2008-01-02  27.834286  3.764286  25.350000       NaN       NaN       NaN
    1 2008-01-03  27.847143  3.724286  24.670000  0.000462 -0.010626 -0.026824
    2 2008-01-04  25.721428  3.515714  22.670000 -0.076335 -0.056003 -0.081070
    3 2008-01-07  25.377142  3.554286  22.879999 -0.013385  0.010971  0.009263
    4 2008-01-08  24.464285  3.328571  22.260000 -0.035972 -0.063505 -0.027098
    

    【讨论】:

      【解决方案2】:

      DataFrame 上调用pct_change,然后使用concat 将结果添加回来变得很简单。

      df = df.set_index('Date')
      pd.concat([df, df.pct_change(1).add_suffix('_Ret')], axis=1)
      
                       AAPL      NFLX       INTC  AAPL_Ret  NFLX_Ret  INTC_Ret
      Date                                                                    
      2008-01-02  27.834286  3.764286  25.350000       NaN       NaN       NaN
      2008-01-03  27.847143  3.724286  24.670000  0.000462 -0.010626 -0.026824
      2008-01-04  25.721428  3.515714  22.670000 -0.076335 -0.056003 -0.081070
      2008-01-07  25.377142  3.554286  22.879999 -0.013385  0.010971  0.009263
      2008-01-08  24.464285  3.328571  22.260000 -0.035972 -0.063505 -0.027098
      

      唯一需要注意的(你可能已经知道了)是pct_change 如果你有非数字列将不起作用。

      因此,另一个(更好的)替代方案是

      pd.concat([df, df.select_dtypes(exclude=[object]).pct_change(1)], 1)
      
               Date       AAPL      NFLX       INTC      AAPL      NFLX      INTC
      0  2008-01-02  27.834286  3.764286  25.350000       NaN       NaN       NaN
      1  2008-01-03  27.847143  3.724286  24.670000  0.000462 -0.010626 -0.026824
      2  2008-01-04  25.721428  3.515714  22.670000 -0.076335 -0.056003 -0.081070
      3  2008-01-07  25.377142  3.554286  22.879999 -0.013385  0.010971  0.009263
      4  2008-01-08  24.464285  3.328571  22.260000 -0.035972 -0.063505 -0.027098
      

      当你有很多非数字列时,它会优雅地处理它们。

      OTOH,我建议提前将日期设置为索引(并使用选项 1),因为这通常是您在处理股票数据时会做的事情。但并非总是如此。

      【讨论】:

      • 我喜欢选择 dtypes ...df.select_dtypes(include=[np.number])
      • @piRSquared 是的,也是!
      • 好吧伙计们,问题是我没有把整个故事讲给我的 df。在股票代码之后,我还有一些列,例如“日”和“月末”,它们标识了当月的最后一个交易日。我的意图是仅在每个月的最后一个交易日运行 pct_change。当我尝试添加上面的代码时,它无法添加列
      • @EksanaStasis 你不能不讲完整个故事,然后指望一个章节来解释整个情节。对不起,但这不好。请使用您的详细信息打开一个新问题,并希望有人有耐心在那里回答您。
      • 请注意,pd.concat([df, df.pct_change(1).add_suffix('_Ret')], axis=1) 只是 返回 更改后的数据帧。要真正将数据框设置为新版本,您必须执行df =pd.concat([df, df.pct_change(1).add_suffix('_Ret')], axis=1)
      【解决方案3】:

      你可以做的一件事是

      for col in df.columns:
          if not isstock(col):
              continue
          df["{}_Ret".format(col)] = df[col].pct_change(1)
      

      我已经包含了isstock() 部分,因为您将日期作为列而不是索引,并且您不想获取日期的百分比变化(我想)。您可以在别处定义isstock(),也可以在我的代码中将其替换为您想要的任何条件。

      【讨论】:

      • 你能帮我定义 isstock 吗?不知道如何处理,例如代码长度不同
      • @EksanaStasis 您可以有包容性标准(所有代码都有共同点,例如,如果所有代码都是大写,则执行col == col.upper())或排除标准(代码没有任何东西,例如col!='Date' )。或者,如果 Date 是唯一的非股票行列,您可以将其移动到索引中。
      • 好的,我可以试试。但是,是否有可能遍历列,比如第 3 到第 6 列?那么对于 df.columns 等中的 col [3:6] 呢?
      • @EksanaStasis 你可以做df.columns[3:6],但你必须确保列的顺序是你期望的。
      • 成功了,非常感谢积累。感谢您对像我这样的初学者的耐心!
      猜你喜欢
      • 2017-07-07
      • 2020-06-12
      • 2018-11-26
      • 1970-01-01
      • 2016-05-22
      • 2020-07-09
      • 2015-03-28
      • 2019-09-06
      • 2019-12-14
      相关资源
      最近更新 更多