熊猫if else条件多列[重复]
Posted
技术标签:
【中文标题】熊猫if else条件多列[重复]【英文标题】:pandas if else conditions on multiple columns [duplicate] 【发布时间】:2019-12-15 23:11:16 【问题描述】:假设我有以下 df:
import pandas as pd
data_dic =
"a": [0,0,1,2],
"b": [0,3,4,5],
"c": [6,7,8,9]
df = pd.DataFrame(data_dic)
结果:
a b c
0 0 0 6
1 0 3 7
2 1 4 8
3 2 5 9
我需要根据条件从上面的列中将值传递到新列:
if df.a > 0 then value df.a
else if df.b > 0 then value df.b
else value df.c
现在我尝试:
df['value'] = [x if x > 0 else 'ww' for x in df['a']]
但不知道如何在此输入更多条件。
预期结果:
a b c value
0 0 0 6 6
1 0 3 7 3
2 1 4 8 1
3 2 5 9 2
感谢您的辛勤工作。
【问题讨论】:
【参考方案1】:使用numpy.select
:
df['value'] = np.select([df.a > 0 , df.b > 0], [df.a, df.b], default=df.c)
print (df)
a b c value
0 0 0 6 6
1 0 3 7 3
2 1 4 8 1
3 2 5 9 2
400k 行中矢量化和循环解决方案的区别:
df = pd.concat([df] * 100000, ignore_index=True)
In [158]: %timeit df['value2'] = np.select([df.a > 0 , df.b > 0], [df.a, df.b], default=df.c)
9.86 ms ± 611 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [159]: %timeit df['value1'] = [x if x > 0 else y if y>0 else z for x,y,z in zip(df['a'],df['b'],df['c'])]
399 ms ± 52.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
【讨论】:
我知道 numpy 的方式会更快,即使在一个小的 df 中也快很多很多【参考方案2】:你也可以使用列表推导:
df['value'] = [x if x > 0 else y if y>0 else z for x,y,z in zip(df['a'],df['b'],df['c'])]
【讨论】:
感谢您的出色解决方案 这很直观,但是@jezrael 的答案在性能方面要好得多,所以请接受它。【参考方案3】:您可以编写一个函数,将行作为参数,测试您想要测试的任何条件,并返回 True
或 False
结果 - 然后您可以将其用作选择工具。 (尽管重新阅读您的问题,这可能不是您想要的 - 请参阅下面的第 2 部分)
执行选择
apply
将此函数添加到您的数据框,并使用返回的一系列 True/False 答案作为索引来从实际数据框本身中选择值。
例如
def selector(row):
if row['a'] > 0 and row['b'] == 3 :
return True
elif row['c'] > 2:
return True
else:
return False
您可以构建任何您喜欢的逻辑,只要确保它在您想要匹配时返回 True,而在您不想要匹配时返回 False。
然后尝试类似
df.apply(lambda row : selector(row), axis=1)
它会返回一系列真假答案。将其插入您的 df 以仅选择那些为其计算了 True
值的行。
df[df.apply(lambda row : selector(row), axis=1)]
这应该会给你你想要的。
第 2 部分 - 执行计算
如果您想创建一个包含一些计算结果的新列 - 那么这是一个类似的操作,请创建一个执行计算的函数:
def mycalc(row):
if row['a'] > 5 :
return row['a'] + row['b']
else:
return 66
只有这一次,apply
将结果分配给一个新的列名:
df['value'] = df.apply( lambda row : mycalc(row), axis = 1)
这会给你这个结果。
【讨论】:
以上是关于熊猫if else条件多列[重复]的主要内容,如果未能解决你的问题,请参考以下文章