熊猫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】:

您可以编写一个函数,将行作为参数,测试您想要测试的任何条件,并返回 TrueFalse 结果 - 然后您可以将其用作选择工具。 (尽管重新阅读您的问题,这可能不是您想要的 - 请参阅下面的第 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条件多列[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在熊猫折线图中绘制多列[重复]

从熊猫列中的列表创建多列[重复]

没有 else 子句的单行 If 条件 [重复]

sql中的if else条件[重复]

CSS if else 条件,移动纵向或横向[重复]

带有布尔条件的 if else 语句中的代码[重复]