J'ai un cadre de données pandas qui ressemble à ceci (c'est un assez gros)
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
maintenant, je voudrais itérer ligne par ligne et au fur et à mesure que je parcours chaque ligne, la valeur de ifor
dans chaque ligne peut changer en fonction de certaines conditions et je dois rechercher une autre trame de données.
Maintenant, comment puis-je mettre à jour cela pendant que j'itère. J'ai essayé quelques choses, aucune d'entre elles n'a fonctionné.
for i, row in df.iterrows():
if <something>:
row['ifor'] = x
else:
row['ifor'] = y
df.ix[i]['ifor'] = x
Aucune de ces approches ne semble fonctionner. Je ne vois pas les valeurs mises à jour dans la trame de données.
df.ix[i,'ifor']
.df.ix[i]['ifor']
est problématique car il s'agit d'une indexation chaînée (ce qui n'est pas fiable chez les pandas).<something>
. La possibilité de vectoriser votre code dépendra de ces éléments. En général, éviteziterrows
. Dans votre cas, vous devez absolument l' éviter car chaque ligne sera unobject
dtypeSeries
.Réponses:
Vous pouvez affecter des valeurs dans la boucle à l'aide de df.set_value:
Si vous n'avez pas besoin des valeurs de ligne, vous pouvez simplement itérer sur les indices de df, mais j'ai conservé la boucle for d'origine au cas où vous auriez besoin de la valeur de ligne pour quelque chose qui n'est pas affiché ici.
mettre à jour
df.set_value () est obsolète depuis la version 0.21.0, vous pouvez utiliser df.at () à la place:
la source
L'objet Pandas DataFrame doit être considéré comme une série de séries. En d'autres termes, vous devriez y penser en termes de colonnes. La raison pour laquelle cela est important est que lorsque vous utilisez,
pd.DataFrame.iterrows
vous parcourez les lignes en tant que série. Mais ce ne sont pas les séries que la trame de données stocke et ce sont donc de nouvelles séries qui sont créées pour vous pendant que vous itérez. Cela implique que lorsque vous tentez de les affecter, ces modifications ne se retrouveront pas reflétées dans le bloc de données d'origine.Ok, maintenant que c'est à l'écart: que faisons-nous?
Les suggestions avant ce post incluent:
pd.DataFrame.set_value
est obsolète à partir de la version 0.21 de Pandaspd.DataFrame.ix
est obsolètepd.DataFrame.loc
est bien, mais peut fonctionner sur les indexeurs de tableau et vous pouvez faire mieuxMa recommandation
Utilisation
pd.DataFrame.at
Vous pouvez même changer cela en:
Réponse au commentaire
la source
Une méthode que vous pouvez utiliser consiste
itertuples()
à itérer sur les lignes DataFrame en tant que couples nommés, avec la valeur d'index comme premier élément du tuple. Et c'est beaucoup plus rapide par rapport àiterrows()
. Pouritertuples()
, chacunrow
contient sonIndex
dans le DataFrame, et vous pouvez utiliserloc
pour définir la valeur.Dans la plupart des cas,
itertuples()
est plus rapide queiat
ouat
.Merci @SantiStSupery, l' utilisation
.at
est beaucoup plus rapide queloc
.la source
df.loc[row.Index, 3] = x
ne fonctionne pas. D'un autre côté,df.loc[row.Index, 'ifor'] = x
ça marche!Vous devez attribuer une valeur par
df.ix[i, 'exp']=X
oudf.loc[i, 'exp']=X
au lieu dedf.ix[i]['ifor'] = x
.Sinon, vous travaillez sur une vue et vous devriez obtenir un réchauffement:
-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
Mais certainement, la boucle devrait probablement être remplacée par un algorithme vectorisé pour utiliser pleinement
DataFrame
comme l'a suggéré @Phillip Cloud.la source
Eh bien, si vous voulez répéter de toute façon, pourquoi ne pas utiliser la méthode la plus simple de toutes,
df['Column'].values[i]
Ou si vous voulez comparer les nouvelles valeurs avec des anciennes ou quelque chose comme ça, pourquoi ne pas les stocker dans une liste, puis les ajouter à la fin.
la source
la source
Il vaut mieux utiliser des
lambda
fonctions en utilisantdf.apply()
-la source
Incrémentez le nombre MAX d'une colonne. Par exemple :
Ma sortie:
Maintenant, je dois créer une colonne dans df2 et remplir les valeurs de colonne qui incrémentent le MAX.
Remarque: df2 ne contiendra initialement que les colonnes Colonne1 et Colonne2. nous avons besoin que la colonne Sortid soit créée et incrémentielle du MAX de df1.
la source