İf-elif-else koşuluna göre yeni bir sütun oluşturma


100

Bir DataFrame'im var df:

    A    B
a   2    2 
b   3    1
c   1    3

Aşağıdaki kriterlere göre yeni bir sütun oluşturmak istiyorum:

satırsa A == B: 0

satırsaA > B: 1

satırsa A < B: -1

bu nedenle yukarıdaki tablo verildiğinde,

    A    B    C
a   2    2    0
b   3    1    1
c   1    3   -1 

if elseYaptığım tipik durumlar için np.where(df.A > df.B, 1, -1), pandalar sorunumu tek adımda çözmek için özel bir sözdizimi sağlıyor mu (3 yeni sütun oluşturup ardından sonucu birleştirmeye gerek kalmadan)?


Sadece bir işlev tanımlayabilir ve bunu iletebilir applyve axis=1işe yarayacaktır, size istediğinizi verecek bir işlem düşünemediğimden emin değilim
EdChum

Çözümünüz 3 sütun oluşturup bunları 1 sütun halinde birleştirmek anlamına mı geliyor yoksa aklınızda farklı bir şey mi var?
nutship

"3 sütun oluştur" deyip duruyorsun, ama neyi kastettiğinden emin değilim.
DSM

1
@DSM bu soruyu cevapladı ancak myFunc'un istediğiniz şeyi df['C']=df.apply(myFunc(row), axis=1)yaptığı yerde gibi bir şeyi kastettim , bu '3 sütun' oluşturmayı içermiyor
EdChum

Yanıtlar:


146

Yukarıda ortaya konan bazı yaklaşımları resmileştirmek için:

Veri çerçevenizin satırlarında şu şekilde çalışan bir işlev oluşturun:

def f(row):
    if row['A'] == row['B']:
        val = 0
    elif row['A'] > row['B']:
        val = 1
    else:
        val = -1
    return val

Ardından, seçenekte geçen veri çerçevenize uygulayın axis=1:

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

Elbette, bu vektörleştirilmemiştir, bu nedenle performans çok sayıda kayda ölçeklendiğinde o kadar iyi olmayabilir. Yine de çok daha okunaklı olduğunu düşünüyorum. Özellikle SAS arka planından geliyor.

Düzenle

İşte vektörleştirilmiş versiyon

df['C'] = np.where(
    df['A'] == df['B'], 0, np.where(
    df['A'] >  df['B'], 1, -1)) 

1
Teşekkür ederim, pandalarla başlıyorum ve bu çok yardımcı oldu +1
nutship

4
İşlevde satırla birlikte başka bir parametre iletmek istersem ne olur? Bunu yaparsam, satır tanımlanmadı diyor ..
prashanth manohar

3
Fonksiyonun argsparametresini kullanmalısınız .apply: pandas.pydata.org/pandas-docs/stable/generated/…
Zelazny7

1
Python öğrenen eski bir SAS kullanıcısıyım ve kesinlikle bir öğrenme eğrisi var! :-) Örneğin, yukarıdaki kod SAS'da şu şekilde yazılabilir: data df; set df; if A=B then C=0; else if A>B then C=1; else C=-1; run;Çok zarif ve basit.
RobertF

1
İyi tanımlanmış bir cevap
Sahil Nagpal

51
df.loc[df['A'] == df['B'], 'C'] = 0
df.loc[df['A'] > df['B'], 'C'] = 1
df.loc[df['A'] < df['B'], 'C'] = -1

İndekslemeyi kullanarak çözmesi kolaydır. İlk kod satırı böyle okur, eğer sütun sütuna Aeşitse, sütunu 0'a eşit Boluşturun ve ayarlayın C.


17

Bu özel ilişki için şunları kullanabilirsiniz 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

6

görüntü açıklamasını buraya girin

Yukarıdakinin orijinal veri çerçeveniz olduğunu ve yeni bir 'eski' sütun eklemek istediğinizi varsayalım

50 yaşından büyükse, daha yaşlı kabul ederiz = evet, aksi halde Yanlış

1. adım: Yaşı 50'den büyük olan satırların dizinlerini alın

row_indexes=df[df['age']>=50].index

2. adım: .loc kullanarak sütuna yeni bir değer atayabiliriz

df.loc[row_indexes,'elderly']="yes"

50 yaş altı için aynı

row_indexes=df[df['age']<50].index

df[row_indexes,'elderly']="no"

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.