如何在熊猫数据框架的列迭代运行回归

我相信这很简单,但作为一个完全的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]可能是错误的。

任何关于这样做的最佳方式的指导都将非常感激。也许我忽略了一种常见的熊猫方法。

731468 次浏览

你可以使用ix根据位置索引数据帧列。

df1.ix[:,1]

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

df1.ix[0,]

这将返回第一行。

df1.ix[:,1]

这将是第0行和第1列的交点:

df1.ix[0,1]

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

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

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

你可以使用iteritems():

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

使用列表理解,你可以得到所有的列名(标题):

[column for column in df]

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

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

这是我在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)

这个答案是遍历选择列以及DF中的所有列。

df.columns给出了一个包含DF中所有列名的列表。如果你想遍历所有列,这就没什么用了。但是当您只想迭代所选择的列时,它就会派上用场。

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

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)

基于公认的答案,如果每个列对应的指数也是想要的:

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

上面的df[column]类型是Series,它可以简单地转换为numpy ndarrays:

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

我遇到这个问题是因为我正在寻找一个只包含列的干净迭代器(Series,没有名称)。

除非我弄错了,没有这样的事情,如果这是真的,有点烦人。特别是,人们有时想要为变量分配几个单独的列(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是一个属性,返回底层的(column_name, column_series)0数组。

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

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

但没有我想的那么复杂。

假设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

大多数答案都是通过列的名字,而不是直接迭代列。如果有多个具有相同名称的列,也会出现问题。如果你想迭代,我建议:

for series in (df.iloc[:,i] for i in range(df.shape[1])):
...