Ответ 1
Гнездо if .. else
s:
lambda x: x*10 if x<2 else (x**2 if x<4 else x+10)
Я хочу применить лямбда-функцию к столбцу DataFrame, используя if... elif... else в лямбда-функции.
df и код имеют вид. как:
df=pd.DataFrame({"one":[1,2,3,4,5],"two":[6,7,8,9,10]})
df["one"].apply(lambda x: x*10 if x<2 elif x<4 x**2 else x+10)
очевидно, что он не работает. Есть ли способ применить, если.... elif.... else to lambda? Как я могу изменить один и тот же результат с помощью List Comprehension?
Спасибо за любой ответ.
Гнездо if .. else
s:
lambda x: x*10 if x<2 else (x**2 if x<4 else x+10)
Я не рекомендую использовать apply
здесь: его следует избегать, если есть лучшие альтернативы.
Например, если вы выполняете следующую операцию над серией:
if cond1:
exp1
elif cond2:
exp2
else:
exp3
Обычно это хороший вариант использования для np.where
или np.select
.
numpy.where
Приведенную выше цепочку if
else
можно записать с помощью
np.where(cond1, exp1, np.where(cond2, exp2, ...))
np.where
позволяет вкладывать. С одним уровнем вложенности ваша проблема может быть решена с помощью
df['three'] = (
np.where(
df['one'] < 2,
df['one'] * 10,
np.where(df['one'] < 4, df['one'] ** 2, df['one'] + 10))
df
one two three
0 1 6 10
1 2 7 4
2 3 8 9
3 4 9 14
4 5 10 15
numpy.select
Позволяет гибкий синтаксис и легко расширяемый. Это следует за формой,
np.select([cond1, cond2, ...], [exp1, exp2, ...])
Или, в этом случае,
np.select([cond1, cond2], [exp1, exp2], default=exp3)
df['three'] = (
np.select(
condlist=[df['one'] < 2, df['one'] < 4],
choicelist=[df['one'] * 10, df['one'] ** 2],
default=df['one'] + 10))
df
one two three
0 1 6 10
1 2 7 4
2 3 8 9
3 4 9 14
4 5 10 15
and
/or
(аналогично if
/else
)Аналогично if-else
, требует lambda
:
df['three'] = df["one"].apply(
lambda x: (x < 2 and x * 10) or (x < 4 and x ** 2) or x + 10)
df
one two three
0 1 6 10
1 2 7 4
2 3 8 9
3 4 9 14
4 5 10 15
Loopy решение, которое все еще быстрее, чем apply
.
df['three'] = [x*10 if x<2 else (x**2 if x<4 else x+10) for x in df['one']]
# df['three'] = [
# (x < 2 and x * 10) or (x < 4 and x ** 2) or x + 10) for x in df['one']
# ]
df
one two three
0 1 6 10
1 2 7 4
2 3 8 9
3 4 9 14
4 5 10 15
Для удобства чтения я предпочитаю написать функцию, особенно если вы имеете дело со многими условиями. Исходный вопрос:
def parse_values(x):
if x < 2:
return x * 10
elif x < 4:
return x ** 2
else:
return x + 10
df['one'].apply(parse_values)