我想创建一个根据某些条件标记行的函数。
它不起作用,我认为是由列的格式引起的。
函数是:
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
答案 0 :(得分:1)
一个选项,可以在进行以下object
比较之前将datetime
转换为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)
答案 1 :(得分:1)
首先,您的代码中的某些内容似乎是错误的。这个
... unit='D') <= data['latedate'] < data['m6p'] ...
链接比较绝对是错误的。
然后在您的条件中使用 AMBER or
的两个子句是相同的。这也没有道理。
除此之外,您还应该将列的数据类型转换为类型datetime
。例如。通过:
data = data.applymap(pd.to_datetime)
这取决于您从数据库中读取数据的类型。
在那之后,基本上有两个选择。您可以编写一个仅占一行,计算值并返回 color 的函数。然后逐行应用此功能。
另一个(更快更可取的)选择是并行计算“ 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)