Mam DataFrame df
:
A B
a 2 2
b 3 1
c 1 3
Chcę utworzyć nową kolumnę na podstawie następujących kryteriów:
jeśli wiersz A == B: 0
jeśli wierszA > B: 1
jeśli wiersz A < B: -1
więc biorąc pod uwagę powyższą tabelę, powinno być:
A B C
a 2 2 0
b 3 1 1
c 1 3 -1
W typowych if else
przypadkach, które robię np.where(df.A > df.B, 1, -1)
, czy pandy zapewniają specjalną składnię do rozwiązania mojego problemu w jednym kroku (bez konieczności tworzenia 3 nowych kolumn, a następnie łączenia wyniku)?
python
pandas
conditional
orzechówka
źródło
źródło
apply
i zestawaxis=1
będzie działać, nie wiem, mogę myśleć o operacji, która da ci to, co chceszdf['C']=df.apply(myFunc(row), axis=1)
gdzie myFunc robi to, co chcesz, nie obejmuje to tworzeniaOdpowiedzi:
Aby sformalizować niektóre z podejść przedstawionych powyżej:
Utwórz funkcję, która działa na wierszach ramki danych, w następujący sposób:
def f(row): if row['A'] == row['B']: val = 0 elif row['A'] > row['B']: val = 1 else: val = -1 return val
Następnie zastosuj go do swojej ramki danych przekazując
axis=1
opcję:In [1]: df['C'] = df.apply(f, axis=1) In [2]: df Out[2]: A B C a 2 2 0 b 3 1 1 c 1 3 -1
Oczywiście nie jest to wektoryzowane, więc wydajność może nie być tak dobra po skalowaniu do dużej liczby rekordów. Mimo to uważam, że jest znacznie bardziej czytelny. Zwłaszcza z przeszłością SAS.
Edytować
Oto wersja zwektoryzowana
df['C'] = np.where( df['A'] == df['B'], 0, np.where( df['A'] > df['B'], 1, -1))
źródło
args
parametru.apply
funkcji: pandas.pydata.org/pandas-docs/stable/generated/…data df; set df; if A=B then C=0; else if A>B then C=1; else C=-1; run;
Bardzo elegancki i prosty.df.loc[df['A'] == df['B'], 'C'] = 0 df.loc[df['A'] > df['B'], 'C'] = 1 df.loc[df['A'] < df['B'], 'C'] = -1
Łatwe do rozwiązania za pomocą indeksowania. Pierwsza linia kodu brzmi tak, jeśli kolumna
A
jest równa kolumnie,B
a następnie utwórz i ustaw kolumnęC
równą 0.źródło
W przypadku tej konkretnej relacji możesz użyć
np.sign
:>>> df["C"] = np.sign(df.A - df.B) >>> df A B C a 2 2 0 b 3 1 1 c 1 3 -1
źródło
Powiedzmy, że powyżej jest oryginalna ramka danych i chcesz dodać nową kolumnę „stara”
Jeśli wiek przekracza 50 lat, uważamy, że jest starszy = tak, w przeciwnym razie Fałsz
krok 1: pobierz indeksy wierszy, których wiek jest większy niż 50
row_indexes=df[df['age']>=50].index
krok 2: za pomocą .loc możemy przypisać nową wartość do kolumny
df.loc[row_indexes,'elderly']="yes"
to samo dla wieku poniżej 50 lat
row_indexes=df[df['age']<50].index
df[row_indexes,'elderly']="no"
źródło
Kiedy masz wiele
if
warunków,numpy.select
jest najlepszy sposób:In [4102]: import numpy as np In [4098]: conditions = [df.A.eq(df.B), df.A.gt(df.B), df.A.lt(df.B)] In [4096]: choices = [0, 1, -1] In [4100]: df['C'] = np.select(conditions, choices) In [4101]: df Out[4101]: A B C a 2 2 0 b 3 1 1 c 1 3 -1
źródło