Mam ramkę danych pand, która wygląda tak (jest to dość duża)
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
teraz chciałbym iterować wiersz po wierszu, a gdy przechodzę przez każdy wiersz, wartość ifor
w każdym wierszu może się zmieniać w zależności od niektórych warunków i muszę wyszukać inną ramkę danych.
Jak mogę to zaktualizować podczas iteracji? Próbowałem kilku rzeczy, ale żadna z nich nie działała.
for i, row in df.iterrows():
if <something>:
row['ifor'] = x
else:
row['ifor'] = y
df.ix[i]['ifor'] = x
Żadne z tych podejść nie działa. Nie widzę wartości zaktualizowanych w ramce danych.
df.ix[i,'ifor']
.df.ix[i]['ifor']
jest problematyczne, ponieważ jest indeksowane łańcuchowo (co nie jest niezawodne w pandach).<something>
. To, czy kod będzie wektoryzowany, będzie zależeć od tych rzeczy. Ogólnie unikajiterrows
. W twoim przypadku zdecydowanie powinieneś tego unikać, ponieważ każdy wiersz będzieobject
typemSeries
.Odpowiedzi:
Możesz przypisać wartości w pętli za pomocą df.set_value:
Jeśli nie potrzebujesz wartości wierszy, możesz po prostu iterować po indeksach df, ale zachowałem oryginalną pętlę for na wypadek, gdybyś potrzebował wartości wiersza dla czegoś, czego tutaj nie pokazano.
aktualizacja
Funkcja df.set_value () została uznana za przestarzałą od wersji 0.21.0. Zamiast tego można użyć funkcji df.at ():
źródło
Obiekt Pandas DataFrame należy traktować jako serię serii. Innymi słowy, powinieneś pomyśleć o tym w kategoriach kolumn. Powodem, dla którego jest to ważne, jest to, że podczas używania
pd.DataFrame.iterrows
iterujesz wiersze jako Serie. Ale nie są to Serie, które przechowuje ramka danych, więc są to nowe Serie, które są tworzone dla ciebie podczas iteracji. Oznacza to, że gdy spróbujesz je przypisać, te zmiany nie zostaną odzwierciedlone w oryginalnej ramce danych.Ok, teraz to już nie przeszkadza: co robimy?
Sugestie poprzedzające ten post obejmują:
pd.DataFrame.set_value
jest przestarzałe od wersji Pandy 0.21pd.DataFrame.ix
jest przestarzałepd.DataFrame.loc
jest w porządku, ale może działać na indeksatorach tablic i możesz zrobić to lepiejMoja rekomendacja
Użyj
pd.DataFrame.at
Możesz nawet zmienić to na:
Odpowiedź na komentarz
źródło
Metodą, której można użyć
itertuples()
, jest iteracja wierszy DataFrame jako nazwanych świątyń, z wartością indeksu jako pierwszym elementem krotki. I jest o wiele szybszy w porównaniu ziterrows()
. Naitertuples()
każdyrow
zawiera jegoIndex
w DataFrame, i można użyćloc
, aby ustawić wartość.W większości przypadków
itertuples()
jest szybszy niżiat
lubat
.Dzięki @SantiStSupery, korzystanie
.at
jest znacznie szybsze niżloc
.źródło
df.loc[row.Index, 3] = x
nie działa. Z drugiej stronydf.loc[row.Index, 'ifor'] = x
działa!Powinieneś przypisać wartość przez
df.ix[i, 'exp']=X
lubdf.loc[i, 'exp']=X
zamiastdf.ix[i]['ifor'] = x
.W przeciwnym razie pracujesz nad widokiem i powinieneś uzyskać ocieplenie:
-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
Ale z pewnością pętla prawdopodobnie powinna zostać zastąpiona algorytmem wektorowym, aby w pełni wykorzystać,
DataFrame
jak sugeruje @Phillip Cloud.źródło
Cóż, jeśli mimo wszystko zamierzasz iterować, dlaczego nie zastosować najprostszej ze wszystkich metod,
df['Column'].values[i]
Lub jeśli chcesz porównać nowe wartości ze starymi lub czymś podobnym, dlaczego nie zapisać go na liście, a następnie dołączyć na końcu.
źródło
źródło
Lepiej jest używać
lambda
funkcji za pomocądf.apply()
-źródło
Zwiększ liczbę MAX z kolumny. Na przykład :
Moja produkcja:
Teraz muszę utworzyć kolumnę w df2 i wypełnić wartości kolumny, które zwiększają wartość MAX.
Uwaga: df2 początkowo będzie zawierał tylko Kolumnę1 i Kolumnę2. potrzebujemy utworzyć kolumnę Sortid i przyrostową wartość MAX z df1.
źródło