【问题标题】:How to iterate over columns of pandas dataframe to run regression如何迭代熊猫数据框的列以运行回归
【发布时间】:2015-03-28 21:56:08
【问题描述】:

我确信这很简单,但作为一个完整的 python 新手,我无法弄清楚如何迭代 pandas 数据帧中的变量并对每个变量运行回归。

这就是我正在做的事情:

all_data = {}
for ticker in ['FIUIX', 'FSAIX', 'FSAVX', 'FSTMX']:
    all_data[ticker] = web.get_data_yahoo(ticker, '1/1/2010', '1/1/2015')

prices = DataFrame({tic: data['Adj Close'] for tic, data in all_data.iteritems()})  
returns = prices.pct_change()

我知道我可以像这样运行回归:

regs = sm.OLS(returns.FIUIX,returns.FSTMX).fit()

但假设我想对数据框中的每一列执行此操作。特别是,我想在 FSTMX 上回归 FIUIX,然后在 FSTMX 上回归 FSAIX,然后在 FSTMX 上回归 FSAVX。每次回归后,我都想存储残差。

我尝试了以下各种版本,但我一定是语法错误:

resids = {}
for k in returns.keys():
    reg = sm.OLS(returns[k],returns.FSTMX).fit()
    resids[k] = reg.resid

我认为问题是我不知道如何按键引用returns列,所以returns[k]可能是错误的。

任何关于最佳方式的指导将不胜感激。也许我缺少一种常见的 pandas 方法。

【问题讨论】:

  • 你可以像这样给列下标:for i in len(df): if i + 1 != len(df): # sm.OLS(returns[returns.coloumns[i]], returns[returns.columns[ i+1]]), fit()os similar

标签: python pandas statsmodels


【解决方案1】:

假设 X 因子,y 标签(多列):

columns = [c for c in _df.columns if c in ['col1', 'col2','col3']]  #or '..c not in..'
_df.set_index(columns, inplace=True)
print( _df.index)

X, y =  _df.iloc[:,:4].values, _df.index.values

【讨论】:

    【解决方案2】:

    我只是在寻找一个干净的列迭代器(Series,没有名字)时遇到了这个问题。

    除非我弄错了,否则没有这样的事情,如果是真的,那就有点烦人了。特别是,有时希望将几个单独的列(系列)分配给变量,例如:

    x, y = df[['x', 'y']]  # does not work
    

    有一个接近的df.items(),但它给出了一个元组迭代器(column_name, column_series)。有趣的是,有一个对应的df.keys() 返回df.columns,即列名称为Index,因此a, b = df[['x', 'y']].keys() 正确分配a='x'b='y'。但是没有对应的df.values(),并且有充分的理由,因为df.values 是一个属性并返回底层numpy 数组。

    一种(不优雅的)方法是:

    x, y = (v for _, v in df[['x', 'y']].items())
    

    但它不像我想要的那样pythonic。

    【讨论】:

    • 嘿@Pierre D 我遇到了你的答案并且正在寻找类似的东西。我不知道this link 是否有帮助,但它可能值得一看。
    【解决方案3】:

    你可以使用iteritems():

    for name, values in df.iteritems():
        print('{name}: {value}'.format(name=name, value=values[0]))
    

    【讨论】:

    • 很好的答案。顺便说一句,df.iteritems() 也可以写成df.items() 给出相同的结果。
    【解决方案4】:

    这个答案是迭代 选定的列 以及 DF 中的所有列。

    df.columns 给出一个包含 DF 中所有列名的列表。现在,如果您想遍历所有列,这不是很有帮助。但是当您只想迭代您选择的列时,它会派上用场。

    我们可以很容易地使用 Python 的列表切片来根据我们的需要对 df.columns 进行切片。例如,要遍历除第一列之外的所有列,我们可以这样做:

    for column in df.columns[1:]:
        print(df[column])
    

    类似地以相反的顺序遍历所有列,我们可以这样做:

    for column in df.columns[::-1]:
        print(df[column])
    

    我们可以使用这种技术以很酷的方式遍历所有列。另请记住,您可以使用以下方法轻松获取所有列的索引:

    for ind, column in enumerate(df.columns):
        print(ind, column)
    

    【讨论】:

      【解决方案5】:

      基于the accepted answer,如果每列对应的index也是desired

      for i, column in enumerate(df):
          print i, df[column]
      

      上面的df[column]类型是Series,可以简单转换成numpyndarrays:

      for i, column in enumerate(df):
          print i, np.asarray(df[column])
      

      【讨论】:

        【解决方案6】:

        我有点晚了,但我是这样做的。步骤:

        1. 创建所有列的列表
        2. 使用 itertools 取 x 个组合
        3. 将每个结果 R 平方值与排除的列列表一起附加到结果数据框
        4. 按照 R 平方的降序对结果 DF 进行排序,看看哪个最合适。

        这是我在 DataFrame 上使用的代码aft_tmt。随意推断您的用例..

        import pandas as pd
        # setting options to print without truncating output
        pd.set_option('display.max_columns', None)
        pd.set_option('display.max_colwidth', None)
        
        import statsmodels.formula.api as smf
        import itertools
        
        # This section gets the column names of the DF and removes some columns which I don't want to use as predictors.
        itercols = aft_tmt.columns.tolist()
        itercols.remove("sc97")
        itercols.remove("sc")
        itercols.remove("grc")
        itercols.remove("grc97")
        print itercols
        len(itercols)
        
        # results DF
        regression_res = pd.DataFrame(columns = ["Rsq", "predictors", "excluded"])
        
        # excluded cols
        exc = []
        
        # change 9 to the number of columns you want to combine from N columns.
        #Possibly run an outer loop from 0 to N/2?
        for x in itertools.combinations(itercols, 9):
            lmstr = "+".join(x)
            m = smf.ols(formula = "sc ~ " + lmstr, data = aft_tmt)
            f = m.fit()
            exc = [item for item in x if item not in itercols]
            regression_res = regression_res.append(pd.DataFrame([[f.rsquared, lmstr, "+".join([y for y in itercols if y not in list(x)])]], columns = ["Rsq", "predictors", "excluded"]))
        
        regression_res.sort_values(by="Rsq", ascending = False)
        

        【讨论】:

          【解决方案7】:

          使用列表推导,您可以获得所有列名(标题):

          [column for column in df]

          【讨论】:

          • 短版:list(df.columns)[c for c in df]
          【解决方案8】:
          for column in df:
              print(df[column])
          

          【讨论】:

          • 我似乎只有在使用这种方法时才能取回列标题。例如: print(df) 向我显示数据框列中的数据,但对于 df 中的 c: print(c) 仅打印标题而不是数据。
          • 好吧忽略我——我在做 print(column) 而不是 print (df[column])
          • 注意同名列!
          • 简洁明了。不过,我希望for x in df 能够遍历行。 :-/
          • for idx, row in df.iterrows() 遍历行。由于基于 col 的操作是矢量化的,因此主迭代自然是在列上 :)
          【解决方案9】:

          一种解决方法是转置DataFrame 并遍历行。

          for column_name, column in df.transpose().iterrows():
              print column_name
          

          【讨论】:

          • 换位相当昂贵:)
          • 可能很昂贵,但对于相对较小的数据帧来说,这是一个很好的解决方案。谢谢 kdauria!
          【解决方案10】:

          您可以使用 ix 按位置索引数据框列。

          df1.ix[:,1]
          

          例如,这将返回第一列。 (0 是索引)

          df1.ix[0,]
          

          这将返回第一行。

          df1.ix[:,1]
          

          这将是第 0 行和第 1 列交叉处的值:

          df1.ix[0,1]
          

          等等。所以你可以enumerate()returns.keys(): 并使用数字来索引数据框。

          【讨论】:

          • ix 已弃用,请使用 iloc
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-07-20
          • 1970-01-01
          • 2020-05-17
          • 2015-12-09
          • 2018-03-06
          • 2021-09-17
          • 2020-07-30
          相关资源
          最近更新 更多