Pandas中含NaT的datetime列执行cummax()的异常问题及需求
问题描述
我有一个名为Purchase Dates的列,仅包含NaT或有效日期。示例数据如下:
Date Last_Purchase Cummax_Purchase 2010-05-28 NaT NaT 2010-06-01 2010-06-01 2010-06-01 2010-06-02 2010-06-02 2010-06-02 2010-06-03 NaT NaT 2010-06-04 NaT NaT
我希望对该列执行cummax()操作以返回最近的采购日期,但当前代码执行时,只要对应行是NaT,结果就返回NaT而非累计最大值:
data['Purchase_Date'] = numpy.where(data['Buy Signal'] == True, data.index.astype(str), pandas.NaT) data['Cummax_Purchase'] = pandas.to_datetime(data['Purchase_Date']).cummax()
将pandas.NaT改为0能正常工作,但我希望保留原始列的NaT值,同时让累计最大值列正确显示最近的采购日期。简化后的测试代码如下:
import pandas as pd data = pd.DataFrame( {"Purchase Dates" : pd.to_datetime(['01-01-2020', '02-01-2020',None,'04-01-2020'])}, index=pd.to_datetime(['01-01-2020','02-01-2020','03-01-2020','04-01-2020'])) data['Cummax_date'] = data['Purchase Dates'].cummax()
解决方案
问题根源是cummax()遇到NaT时会保留该行的NaT,不会自动用之前的累计最大值填充。可以通过**先计算累计最大值,再向前填充NaT**的方式解决,既能保留初始的NaT,又能让后续的NaT行显示最近的采购日期。
简化测试代码修改版
import pandas as pd # 构造测试数据 data = pd.DataFrame( {"Purchase Dates" : pd.to_datetime(['01-01-2020', '02-01-2020',None,'04-01-2020'])}, index=pd.to_datetime(['01-01-2020','02-01-2020','03-01-2020','04-01-2020'])) # 计算累计最大值后向前填充NaT data['Cummax_date'] = data['Purchase Dates'].cummax().ffill()
执行后得到的结果:
| Date | Purchase Dates | Cummax_date |
|---|---|---|
| 2020-01-01 | 2020-01-01 | 2020-01-01 |
| 2020-02-01 | 2020-02-01 | 2020-02-01 |
| 2020-03-01 | NaT | 2020-02-01 |
| 2020-04-01 | 2020-04-01 | 2020-04-01 |
对应原代码的修改
将你的代码调整为:
import pandas as pd import numpy as np data['Purchase_Date'] = np.where(data['Buy Signal'] == True, data.index.astype(str), pd.NaT) # 先转换为日期类型,计算累计最大值后向前填充 purchase_dates = pd.to_datetime(data['Purchase_Date']) data['Cummax_Purchase'] = purchase_dates.cummax().ffill()
逻辑说明
cummax():从前往后计算累计最大值,仅在遇到更大的有效日期时更新结果,遇到NaT时保留该行的NaT。ffill():向前填充,将后续的NaT替换为前一个非NaT的累计最大值,而最开始未出现有效日期的NaT会被保留,完全符合需求。
内容的提问来源于stack exchange,提问作者Geo
相关产品推荐
相关产品推荐

