Створення нового стовпця на основі умови if-elif-else


100

У мене є DataFrame df:

    A    B
a   2    2 
b   3    1
c   1    3

Я хочу створити новий стовпець на основі таких критеріїв:

якщо рядок A == B: 0

якщо рядокA > B: 1

якщо рядок A < B: -1

так, враховуючи наведену вище таблицю, вона повинна бути:

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

Для типових if elseвипадків, які я роблю np.where(df.A > df.B, 1, -1), чи забезпечують панди спеціальний синтаксис для вирішення моєї проблеми одним кроком (без необхідності створювати 3 нові стовпці, а потім комбінувати результат)?


Ви можете просто визначити функцію і передати її applyі встановити, що axis=1буде працювати, не впевнений, що я можу придумати операцію, яка дасть вам те, що ви хочете
EdChum

Ваше рішення передбачає створення 3 стовпців та їх об’єднання в 1 стовпець, або ви маєте на увазі щось інше?
горіх

Ви продовжуєте говорити "створення 3 стовпців", але я не впевнений, на що ви маєте на увазі.
DSM

1
@DSM відповів на це запитання, але я мав на увазі щось на зразок того, df['C']=df.apply(myFunc(row), axis=1)де myFunc робить те, що ти хочеш, це не передбачає створення `` 3 стовпців ''
EdChum,

Відповіді:


146

Для формалізації деяких підходів, викладених вище:

Створіть функцію, яка працює з рядками вашого фрейму даних так:

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

Потім застосуйте його до вашого фрейму даних, передаючи 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

Звичайно, це не векторизовано, тому продуктивність може бути не такою хорошою, якщо масштабувати до великої кількості записів. І все-таки, я думаю, це набагато читабельніше. Особливо, виходячи з рівня SAS.

Редагувати

Ось векторизована версія

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

1
Дякую, я починаю з панд, і це було дуже корисно +1
горіх

4
Що робити, якщо я хочу передати інший параметр разом із рядком у функції? Якщо я це зроблю, там написано, що рядок не визначено ..
prashanth manohar

3
Вам потрібно скористатися argsпараметром .applyфункції: pandas.pydata.org/pandas-docs/stable/generated/…
Zelazny7

1
Я старий користувач SAS, який вивчає Python, і, безумовно, є крива навчання! :-) Наприклад, наведений вище код можна написати на SAS як: data df; set df; if A=B then C=0; else if A>B then C=1; else C=-1; run;Дуже елегантний та простий.
RobertF


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

Легко вирішити за допомогою індексації. Перший рядок коду читається так, якщо стовпець Aдорівнює стовпцю, Bтоді створіть і встановіть стовпець Cрівним 0.


17

Для цих конкретних стосунків ви можете використовувати 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

введіть тут опис зображення

Скажімо, над одним - ваш початковий кадр даних, і ви хочете додати новий стовпець "старий"

Якщо вік більше 50 років, тоді ми вважаємо старшим = так, інакше Неправда

Крок 1: Отримати індекси рядків, вік яких перевищує 50

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

Крок 2: За допомогою .loc ми можемо призначити нове значення стовпцю

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

однаково для віку менше 50 років

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.