Ich habe einen Pandas-Datenrahmen, der so aussieht (es ist ein ziemlich großer)
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
Jetzt möchte ich Zeile für Zeile iterieren. Während ich durch jede Zeile gehe, kann sich der Wert ifor
in jeder Zeile abhängig von bestimmten Bedingungen ändern, und ich muss einen anderen Datenrahmen nachschlagen.
Wie aktualisiere ich dies jetzt, während ich iteriere? Versuchte ein paar Dinge, von denen keiner funktionierte.
for i, row in df.iterrows():
if <something>:
row['ifor'] = x
else:
row['ifor'] = y
df.ix[i]['ifor'] = x
Keiner dieser Ansätze scheint zu funktionieren. Ich sehe die im Datenrahmen aktualisierten Werte nicht.
df.ix[i,'ifor']
.df.ix[i]['ifor']
ist problematisch, weil es sich um eine verkettete Indizierung handelt (was bei Pandas nicht zuverlässig ist).<something>
. Ob Ihr Code vektorisiert werden kann, hängt von diesen Dingen ab. Im Allgemeinen vermeideniterrows
. In Ihrem Fall sollten Sie dies unbedingt vermeiden, da jede Zeile einobject
D-Typ istSeries
.Antworten:
Sie können Werte in der Schleife mit df.set_value zuweisen:
Wenn Sie die Zeilenwerte nicht benötigen, können Sie einfach über die Indizes von df iterieren, aber ich habe die ursprüngliche for-Schleife beibehalten, falls Sie den Zeilenwert für etwas benötigen, das hier nicht angezeigt wird.
aktualisieren
df.set_value () ist seit Version 0.21.0 veraltet. Sie können stattdessen df.at () verwenden:
quelle
Das Pandas DataFrame-Objekt sollte als Serie von Serien betrachtet werden. Mit anderen Worten, Sie sollten es in Spalten betrachten. Der Grund, warum dies wichtig ist, liegt darin, dass Sie bei der Verwendung
pd.DataFrame.iterrows
Zeilen als Serien durchlaufen. Dies sind jedoch nicht die Serien, die im Datenrahmen gespeichert werden. Es handelt sich also um neue Serien, die für Sie erstellt werden, während Sie iterieren. Dies bedeutet, dass diese Änderungen beim Versuch, sie zuzuweisen, nicht im ursprünglichen Datenrahmen wiedergegeben werden.Ok, jetzt wo das nicht im Weg ist: Was machen wir?
Vorschläge vor diesem Beitrag umfassen:
pd.DataFrame.set_value
ist ab Pandas Version 0.21 veraltetpd.DataFrame.ix
ist veraltetpd.DataFrame.loc
ist in Ordnung, kann aber mit Array-Indexern arbeiten und Sie können es besser machenMeine Empfehlung
Verwenden
pd.DataFrame.at
Sie können dies sogar ändern in:
Antwort auf Kommentar
quelle
Eine Methode, die Sie verwenden können, besteht darin
itertuples()
, DataFrame-Zeilen als Namedtuples zu durchlaufen, wobei der Indexwert das erste Element des Tupels ist. Und es ist viel viel schneller alsiterrows()
. Dennitertuples()
jedesrow
enthält seinIndex
im DataFrame, und Sie könnenloc
den Wert festlegen.In den meisten Fällen
itertuples()
ist schneller alsiat
oderat
.Danke @SantiStSupery, die Verwendung
.at
ist viel schneller alsloc
.quelle
df.loc[row.Index, 3] = x
funktioniert aber nicht. Auf der anderen Seitedf.loc[row.Index, 'ifor'] = x
funktioniert!Sie sollten den Wert durch
df.ix[i, 'exp']=X
oderdf.loc[i, 'exp']=X
anstelle von zuweisendf.ix[i]['ifor'] = x
.Ansonsten arbeiten Sie an einer Ansicht und sollten sich erwärmen:
-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
Aber sicherlich sollte die Schleife wahrscheinlich besser durch einen vektorisierten Algorithmus ersetzt werden, um die volle Nutzung von
DataFrame
@Phillip Cloud zu nutzen.quelle
Nun, wenn Sie sowieso iterieren wollen, warum nicht die einfachste Methode von allen verwenden,
df['Column'].values[i]
Oder wenn Sie die neuen Werte mit alten oder ähnlichen Werten vergleichen möchten, speichern Sie sie in einer Liste und hängen Sie sie am Ende an.
quelle
quelle
Es ist besser,
lambda
Funktionen mitdf.apply()
- zu verwenden.quelle
Erhöhen Sie die MAX-Nummer aus einer Spalte. Zum Beispiel :
Meine Ausgabe:
Jetzt muss ich eine Spalte in df2 erstellen und die Spaltenwerte füllen, die den MAX erhöhen.
Hinweis: df2 enthält zunächst nur die Spalten 1 und 2. Wir müssen die Spalte Sortid erstellen und die MAX von df1 inkrementieren.
quelle