繁体   English   中英

Pandas 数据框上的日期条件

[英]Condition with dates on Pandas dataframe

我想创建一个基于特定条件标记行的函数。

它不起作用,我认为这是由列的格式引起的。

功能是:

tolerance=5

def pmm_m2_rag(data):

    if  data['m2'] == data['TP_M2'] and data['m6p'] + pd.to_timedelta(tolerance,unit='D') <= data['latedate']:
        return 'GREEN'


    elif data['m2']!= data['TP_M2'] and data['m6p'] + pd.to_timedelta(tolerance,unit='D') < data['latedate']:
        return 'AMBER'


    elif data['m2']!= None and data['m6p'] + pd.to_timedelta(tolerance,unit='D') > data['latedate']:
        return 'RED'

数据框是:

                m2       TP_M2         m6p          latedate         
0       2019-11-28  2019-10-29  2020-02-21        2020-02-25       
1       2019-11-28  2019-10-29  2020-02-21        2020-02-25       
2       2019-11-28  2019-11-28  2020-02-09        2020-02-17       
3       2019-11-28  2019-11-28  2020-02-29        2020-02-17

数据类型是:

m2                  object
TP_M2               object
m6p                 object
latedate    object
dtype: object

预期输出:

                m2       TP_M2         m6p          latedate         RAG
0       2019-11-28  2019-10-29  2020-02-21        2020-02-25       AMBER
1       2019-11-28  2019-10-29  2020-02-21        2020-02-25       AMBER
2       2019-11-28  2019-11-28  2020-02-09        2020-02-17       GREEN
3       2019-11-28  2019-11-28  2020-02-29        2020-02-17         RED

一种选择是在进行datetime比较之前将object转换为datetime时间,如下所示

from datetime import datetime
tolerance=5

def pmm_m2_rag(data):
    #m2 = datetime.strptime(data['m2'],'%Y-%m-%d')
    #m6p = datetime.strptime(data['m6p'],'%Y-%m-%d')
    #latedate = datetime.strptime(data['latedate'],'%Y-%m-%d')
    #TP_M2 = datetime.strptime(data['TP_M2'],'%Y-%m-%d')
    m2 = datetime.strptime(str(data['m2']),'%Y-%m-%d')
    m6p = datetime.strptime(str(data['m6p']),'%Y-%m-%d')
    latedate = datetime.strptime(str(data['latedate']),'%Y-%m-%d')
    TP_M2 = datetime.strptime(str(data['TP_M2']),'%Y-%m-%d')
    if  m2 == TP_M2 and m6p + pd.to_timedelta(tolerance,unit='D') <= latedate:
        return 'GREEN'


    elif m2!= TP_M2 and m6p + pd.to_timedelta(tolerance,unit='D') < latedate:
        return 'AMBER'


    elif m2!= None and m6p + pd.to_timedelta(tolerance,unit='D') > latedate:
        return 'RED'
df['RAG'] = df.apply(pmm_m2_rag, axis=1)

首先,您的代码中的某些内容似乎是错误的。 这个

... unit='D') <= data['latedate'] < data['m6p'] ...

链式比较肯定是错误的。

然后在您的AMBER条件中,您的两个子句or是相同的。 这也没有任何意义。

除此之外,您应该将列的数据类型转换为datetime类型。 例如通过:

data = data.applymap(pd.to_datetime)

这取决于您从数据库中读取数据时的数据类型。

之后,基本上有两种选择。 您可以编写一个接受单行的函数,计算值并返回color 然后逐行应用此函数。

另一个(更快且更可取)选项是并行计算“RAG”列。

这可以通过使用numpy.where和你上面写的条件来完成。 请注意,数据帧列之间的and必须写为& ; or作为| .

这样的事情应该工作:

import numpy as np
def pmm_m2_rag(data):
    green_filter = (data.m2 == data.TP_M2) & \
        (data.m6p + pd.to_timedelta(tolerance,unit='D') <= data.latedate)

    amber_filter = (data.m2 != data.TP_M2) & \
        (data.m6p + pd.to_timedelta(tolerance,unit='D') < data.latedate) | \
        (data.latedate > data.m6p + pd.to_timedelta(tolerance,unit='D'))

    red_filter = (data.m2 != pd.NaT) & \
        (data.m6p + pd.to_timedelta(tolerance,unit='D') > data.latedate)

    data['RAG'] = np.where(green_filter, 'GREEN', np.where(amber_filter, 'AMBER', np.where(red_filter, 'RED', '')))

np.where的语法是

np.where(<CONDITION>, true-clause, false-clause)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM