Como iterar sobre colunas do quadro de dados do pandas para executar a regressão

187

Tenho certeza de que isso é simples, mas como um novato em python, estou tendo problemas para descobrir como iterar sobre variáveis ​​em um pandasdataframe e executar uma regressão com cada uma.

Aqui está o que estou fazendo:

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()

Eu sei que posso executar uma regressão como esta:

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

mas suponha que eu queira fazer isso para cada coluna no quadro de dados. Em particular, quero regredir o FIUIX no FSTMX e, em seguida, o FSAIX no FSTMX e o FSAVX no FSTMX. Após cada regressão, quero armazenar os resíduos.

Eu tentei várias versões do seguinte, mas devo estar com a sintaxe errada:

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

Acho que o problema é que não sei como me referir à coluna de retornos por chave, então returns[k]provavelmente está errado.

Qualquer orientação sobre a melhor maneira de fazer isso seria muito apreciada. Talvez esteja faltando uma abordagem comum dos pandas.

itzy
fonte
1
Você pode subscrito as cols assim: for i in len(df): if i + 1 != len(df): # sm.OLS(returns[returns.coloumns[i]], returns[returns.columns[ i+1]]), fit()OS semelhante
EdChum

Respostas:

343
for column in df:
    print(df[column])
The Unfun Cat
fonte
1
Parece que só recebo de volta o cabeçalho da coluna quando uso esse método. Por exemplo: print (df) mostra os dados nas colunas do quadro de dados, mas para c em df: print (c) apenas imprime o cabeçalho e não os dados.
user1761806
5
Ok, me ignore - eu estava fazendo a impressão (coluna), não a impressão (df [coluna]) #
user1761806 20/17
14
Cuidado com as colunas com o mesmo nome!
freethebees
4
É agradável e conciso. Eu esperaria for x in dfrepetir as linhas, no entanto. : - /
Eric Duminil
7
for idx, row in df.iterrows()itera sobre linhas. Como as operações baseadas em colas são vetorizadas, é natural que a iteração principal seja sobre colunas :) #
485 The Unfun Cat
69

Você pode usar iteritems():

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

Esta resposta é para percorrer as colunas selecionadas , bem como todas as colunas em um DF.

df.columnsfornece uma lista contendo todos os nomes das colunas no DF. Agora isso não é muito útil se você deseja percorrer todas as colunas. Mas é útil quando você deseja iterar apenas as colunas de sua escolha.

Podemos usar a lista do Python fatiando facilmente para dividir o df.columns de acordo com nossas necessidades. Por exemplo, para iterar sobre todas as colunas, exceto a primeira, podemos fazer:

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

De maneira semelhante à iteração sobre todas as colunas na ordem inversa, podemos fazer:

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

Podemos iterar todas as colunas de várias maneiras interessantes usando essa técnica. Lembre-se também de que você pode obter os índices de todas as colunas facilmente usando:

for ind, column in enumerate(df.columns):
    print(ind, column)
Abhinav Gupta
fonte
21

Você pode indexar colunas do quadro de dados pela posição usando ix.

df1.ix[:,1]

Isso retorna a primeira coluna, por exemplo. (0 seria o índice)

df1.ix[0,]

Isso retorna a primeira linha.

df1.ix[:,1]

Esse seria o valor na interseção da linha 0 e da coluna 1:

df1.ix[0,1]

e assim por diante. Assim, você pode enumerate() returns.keys():usar o número para indexar o quadro de dados.

JAB
fonte
8
ixé preterido, usariloc
Yohan Obadia
8

Uma solução alternativa é transpor DataFramee iterar sobre as linhas.

for column_name, column in df.transpose().iterrows():
    print column_name
kdauria
fonte
4
A transposição é bastante caro :)
The Cat Unfun
Pode ser caro, mas esta é uma ótima solução para quadros de dados relativamente pequenos. Obrigado kdauria!
elPastor 11/02
5

Usando a compreensão da lista, você pode obter todos os nomes das colunas (cabeçalho):

[column for column in df]

MEhsan
fonte
2
Versão mais curta: list(df.columns)ou[c for c in df]
The Unfun Cat
4

Com base na resposta aceita , se um índice correspondente a cada coluna também for desejado :

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

O df[column]tipo acima é Series, que pode ser simplesmente convertido em numpy ndarrays:

for i, column in enumerate(df):
    print i, np.asarray(df[column])
Engenheiro Livre de Herpes
fonte
3

Estou um pouco atrasado, mas aqui está como eu fiz isso. Os passos:

  1. Crie uma lista de todas as colunas
  2. Use as ferramentas para fazer x combinações
  3. Anexe cada valor ao quadrado R do resultado a um quadro de dados do resultado, juntamente com a lista de colunas excluídas
  4. Classifique o resultado DF em ordem decrescente de R ao quadrado para ver qual é o melhor ajuste.

Esse é o código que eu usei no DataFrame chamado aft_tmt. Sinta-se à vontade para extrapolar para o seu caso de uso.

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)
Gaurav
fonte