Python 将一系列条件应用于数据帧。熊猫

Python 将一系列条件应用于数据帧。熊猫,python,pandas,Python,Pandas,我曾经在对数据帧应用多个条件时使用np.where函数,使用时感觉还可以。 我想改进我的代码,在np.where中的每一组条件中重复相同的条件,我不知道如何以最简单(清晰和简洁的方式)使用(1).loc或(2)IF“condition”do“apply other conditions” 例如: 我只需要选择“Date”处于条件(例如>20200201)下的行,并且仅对这些行计算新列,应用另一组不同的条件(例如条件1:A>20和B>20;条件2:A==30和B==10,条件3:A==20和B>=

我曾经在对数据帧应用多个条件时使用np.where函数,使用时感觉还可以。 我想改进我的代码,在np.where中的每一组条件中重复相同的条件,我不知道如何以最简单(清晰和简洁的方式)使用(1).loc或(2)IF“condition”do“apply other conditions”

例如:

我只需要选择“Date”处于条件(例如>20200201)下的行,并且仅对这些行计算新列,应用另一组不同的条件(例如条件1:A>20和B>20;条件2:A==30和B==10,条件3:A==20和B>=10等)

我的问题是,在每行中进行第一次选择(数据>20200202)以避免重复日期>2020201的最佳方法是什么,并避免:

import pandas as pd
import numpy as np

df = pd.DataFrame({"ID": [1,3,2,2,3,1,3,2],
           "Date": [20200109, 20200204, 20200307, 20200216, 20200107, 20200108, 20200214, 20200314],
           "A": [20,10,40,40,10,20, 40,30], 
           "B": [20,30,40,50,20, 30, 20, 10]})

df['new']=np.nan
df['new']=np.where((df['Date']>20200201) & (df['A']>20) & (df['B']>20), 'value', df['new'])
df['new']=np.where((df['Date']>20200201) & (df['A']==30) & (df['B']==10), 'value', df['new'])
df['new']=np.where((df['Date']>20200201) & (df['A']==20) & (df['B']>=10), 'value', df['new'])

看起来您可以使用
np。选择

s1 = df.Date <= 20200201
s2 = (df['A'] > 20) & df['B'].gt(20)
s3 = df['A'].eq(30) & df['B'].eq(10)
s4 = df['A'].eq(20) & df['B'].ge(10)

df['new'] = np.select( (s1,s2|s3|s4), (np.nan, 'value'), np.nan)

这可能不是最快的解决方案,但其优势在于 可读性易于维护(将来)

  • 使用查询和这些行的索引查找有问题的行:

    ind = df.query('Date > 20200201 and (A > 20 and B > 20 or '
        'A == 30 and B == 10 or A == 20 and B >= 10)').index
    
  • 将新值保存在指定行的新列中:

    df.loc[ind, 'new'] = 'value'; df
    
  • 此列中的其他值仍为NaN

    如果将来上述情况发生变化,这是很容易的 而且可以直观地纠正它

    因此,除非您的数据量很大,而且执行时间很短
    这个解决方案值得考虑。你的条件的具体价值观,很好的解决方案,@Quang Hoang。您建议先定义条件,然后选择适用于每种情况的条件。我仍然不确定我是否可以这样做,因为我不知道会有多少条件以及它们如何相互作用,但我喜欢这个解决方案。谢谢大家!@关键是
    s1
    与所有其他条件分离。你可以将其作为第一个条件进行检查,然后所有其他条件都包含在其否定项中。我的直觉告诉我,链接
    不带括号是一个非常糟糕的主意。至少在查询中没有任何问题。但添加括号也不会有什么坏处。尤其是如果读者不确定运算符的优先级。
    
    df.loc[ind, 'new'] = 'value'; df