数据框上有日期的条件

2024-04-19 14:03:55 发布

您现在位置:Python中文网/ 问答频道 /正文

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

它不起作用,我认为这是由列的格式造成的。你知道吗

功能是:

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

Tags: andtodatareturnobjectunittolerancetimedelta
2条回答

首先,代码中的某些内容似乎有问题。这个

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

比较链肯定是错误的。你知道吗

那么在你的条件下,你的两个从句是相同的。这也毫无意义。你知道吗

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

data = data.applymap(pd.to_datetime)

这取决于从数据库读取数据时的数据类型。你知道吗

之后,基本上有两种选择。您可以编写一个函数,获取一行,计算值并返回颜色。然后逐行应用此函数。你知道吗

另一个(更快更可取的)选项是并行计算列“RAG”。你知道吗

这可以通过使用numpy.where和上面所写的条件来实现。 请注意,datafram列之间的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)

一个选项是在进行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)

相关问题 更多 >