如何将 pandas 数据框的列迭代到 运行 回归
How to iterate over columns of pandas dataframe to run regression
我相信这很简单,但作为 python 的新手,我无法弄清楚如何迭代 pandas
数据帧和 [=34= 中的变量] 每个回归。
这是我正在做的事情:
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 方法。
您可以使用 ix
.
按位置索引数据框列
df1.ix[:,1]
这returns以第一列为例。 (0 将是索引)
df1.ix[0,]
这returns第一行。
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]))
使用列表理解,您可以获得所有列名称 (header):
[column for column in df]
我来晚了一点,但我是这样做的。步骤:
- 创建所有列的列表
- 使用 itertools 进行 x 组合
- 将每个结果 R 平方值连同排除的列列表附加到结果数据框
- 将结果 DF 按 R 平方的降序排序,看看哪个最合适。
这是我在名为 aft_tmt
的 DataFrame 上使用的代码。随意推断您的用例..
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)
这个答案是遍历[=24=]选定的列以及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)
基于,如果每列对应的一个index也是想要的:
for i, column in enumerate(df):
print i, df[column]
上面的df[column]
类型是Series
,可以简单的转换成numpy
ndarray
s:
for i, column in enumerate(df):
print i, np.asarray(df[column])
我在寻找一个干净的列迭代器时遇到了这个问题(Series
,没有名字)。
除非我弄错了,否则没有这样的事情,如果是真的,有点烦人。特别是,有时人们希望将一些单独的列(系列)分配给变量,例如:
x, y = df[['x', 'y']] # does not work
df.items()
很接近,但它给出了一个元组迭代器 (column_name, column_series)
。有趣的是,returns df.columns
对应的 df.keys()
,即列名称为 Index
,因此 a, b = df[['x', 'y']].keys()
正确分配 a='x'
和 b='y'
。但是没有对应的 df.values()
,并且有充分的理由,因为 df.values
是一个 属性 而 returns 是底层的 numpy
数组。
一个(不优雅的)方法是:
x, y = (v for _, v in df[['x', 'y']].items())
但它没有我想要的那么 pythonic。
假设 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
我相信这很简单,但作为 python 的新手,我无法弄清楚如何迭代 pandas
数据帧和 [=34= 中的变量] 每个回归。
这是我正在做的事情:
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 方法。
您可以使用 ix
.
df1.ix[:,1]
这returns以第一列为例。 (0 将是索引)
df1.ix[0,]
这returns第一行。
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]))
使用列表理解,您可以获得所有列名称 (header):
[column for column in df]
我来晚了一点,但我是这样做的。步骤:
- 创建所有列的列表
- 使用 itertools 进行 x 组合
- 将每个结果 R 平方值连同排除的列列表附加到结果数据框
- 将结果 DF 按 R 平方的降序排序,看看哪个最合适。
这是我在名为 aft_tmt
的 DataFrame 上使用的代码。随意推断您的用例..
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)
这个答案是遍历[=24=]选定的列以及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)
基于
for i, column in enumerate(df):
print i, df[column]
上面的df[column]
类型是Series
,可以简单的转换成numpy
ndarray
s:
for i, column in enumerate(df):
print i, np.asarray(df[column])
我在寻找一个干净的列迭代器时遇到了这个问题(Series
,没有名字)。
除非我弄错了,否则没有这样的事情,如果是真的,有点烦人。特别是,有时人们希望将一些单独的列(系列)分配给变量,例如:
x, y = df[['x', 'y']] # does not work
df.items()
很接近,但它给出了一个元组迭代器 (column_name, column_series)
。有趣的是,returns df.columns
对应的 df.keys()
,即列名称为 Index
,因此 a, b = df[['x', 'y']].keys()
正确分配 a='x'
和 b='y'
。但是没有对应的 df.values()
,并且有充分的理由,因为 df.values
是一个 属性 而 returns 是底层的 numpy
数组。
一个(不优雅的)方法是:
x, y = (v for _, v in df[['x', 'y']].items())
但它没有我想要的那么 pythonic。
假设 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