Eu tenho um quadro de dados de pandas que se parece com isso (é bem grande)
date exer exp ifor mat
1092 2014-03-17 American M 528.205 2014-04-19
1093 2014-03-17 American M 528.205 2014-04-19
1094 2014-03-17 American M 528.205 2014-04-19
1095 2014-03-17 American M 528.205 2014-04-19
1096 2014-03-17 American M 528.205 2014-05-17
agora eu gostaria de iterar linha por linha e, à medida que ifor
passo cada linha, o valor de cada linha pode mudar dependendo de algumas condições e preciso procurar outro quadro de dados.
Agora, como atualizo isso à medida que itero. Tentei algumas coisas que nenhum deles funcionou.
for i, row in df.iterrows():
if <something>:
row['ifor'] = x
else:
row['ifor'] = y
df.ix[i]['ifor'] = x
Nenhuma dessas abordagens parece funcionar. Não vejo os valores atualizados no quadro de dados.
df.ix[i,'ifor']
.df.ix[i]['ifor']
é problemático porque é indexado em cadeia (o que não é confiável em pandas).<something>
. Se o seu código pode ser vetorizado dependerá dessas coisas. Em geral, eviteiterrows
. No seu caso, você deve definitivamente evitá-lo, pois cada linha será umobject
tipoSeries
.Respostas:
Você pode atribuir valores no loop usando df.set_value:
Se você não precisar dos valores da linha, basta iterar sobre os índices de df, mas mantive o loop for original, caso você precise do valor da linha para algo não mostrado aqui.
atualizar
O df.set_value () está obsoleto desde a versão 0.21.0, você pode usar o df.at ():
fonte
O objeto DataFrame do Pandas deve ser considerado como uma série de séries. Em outras palavras, você deve pensar nisso em termos de colunas. A razão pela qual isso é importante é porque, quando você usa,
pd.DataFrame.iterrows
está iterando pelas linhas como Série. Mas essas não são as séries que o quadro de dados está armazenando e, portanto, são novas séries criadas para você enquanto você itera. Isso implica que, quando você tentar atribuir a eles, essas edições não serão refletidas no quadro de dados original.Ok, agora que está fora do caminho: o que fazemos?
As sugestões anteriores a esta postagem incluem:
pd.DataFrame.set_value
foi descontinuado a partir da versão 0.21 do Pandaspd.DataFrame.ix
está obsoletopd.DataFrame.loc
é bom, mas pode funcionar em indexadores de matriz e você pode fazer melhorMinha recomendação
Use
pd.DataFrame.at
Você pode até mudar isso para:
Resposta ao comentário
fonte
Um método que você pode usar é
itertuples()
: ele itera sobre as linhas do DataFrame como nomeduplos, com o valor do índice como primeiro elemento da tupla. E é muito, muito mais rápido em comparação comiterrows()
. Paraitertuples()
, cada umrow
contém seuIndex
no DataFrame, e você pode usarloc
para definir o valor.Na maioria dos casos,
itertuples()
é mais rápido queiat
ouat
.Obrigado @SantiStSupery, o uso
.at
é muito mais rápido queloc
.fonte
df.loc[row.Index, 3] = x
não funciona. Por outro lado,df.loc[row.Index, 'ifor'] = x
funciona!Você deve atribuir valor por
df.ix[i, 'exp']=X
ou emdf.loc[i, 'exp']=X
vez dedf.ix[i]['ifor'] = x
.Caso contrário, você está trabalhando em uma exibição e deve receber um aquecimento:
-c:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead
Mas, certamente, o loop provavelmente deveria ser melhor substituído por algum algoritmo vetorizado para fazer o uso completo
DataFrame
como o @Phillip Cloud sugeriu.fonte
Bem, se você deseja iterar de qualquer maneira, por que não usar o método mais simples de todos,
df['Column'].values[i]
Ou se você deseja comparar os novos valores com os antigos ou algo assim, por que não armazená-los em uma lista e depois anexá-los ao final.
fonte
fonte
É melhor usar
lambda
funções usandodf.apply()
-fonte
Incremente o número MAX de uma coluna. Por exemplo :
Minha saída:
Agora, preciso criar uma coluna no df2 e preencher os valores da coluna que incrementam o MAX.
Nota: o df2 conterá inicialmente apenas a Coluna1 e a Coluna2. precisamos que a coluna Sortid seja criada e incremental do MAX do df1.
fonte