Pandas:从另一列中填充缺失的日期时间值,但如果重复,则每次替换都要递增



很抱歉出现这个令人困惑的问题,我不知道用什么最好的方法将其总结成一个更具描述性的问题。

我有一个数据帧,它有两个日期时间列,一个只给出日期,另一个向日期列添加特定的小时和分钟值,比如"date_hour_minute"。Date_Hour_Minute列有很多缺失值,但Date列没有。

Row  |   Date   |  ID   |     Date_Hour_Minute 
==========================================
1   |   02/21  |  25   |    02/21 06:02    
2   |   02/21  |  30   |    NA    
3   |   02/21  |  30   |    NA    
4   |   02/21  |  25   |    NA    
5   |   02/21  |  25   |    02/21 07:10      
6   |   02/21  |  30   |    NA       
7   |   02/22  |  30   |    NA       

现在,我想将Date_Hour_Minute列中的所有NA值替换为相应的Date值,并在其后面添加小时/分钟值。使用fillna,我可以很容易地在Date后面添加午夜时间,并将NA替换为

df.Date_Hour_Minute = df.Date_Hour_Minute.fillna(df.Date)

导致

Row  |   Date   |  ID   |     Date_Hour_Minute 
============================================
1   |   02/21  |  25   |    02/21 06:02     
2   |   02/21  |  30   |    02/21 00:00 
3   |   02/21  |  30   |    02/21 00:00 
4   |   02/21  |  25   |    02/21 00:00 
5   |   02/21  |  25   |    02/21 07:10       
6   |   02/21  |  30   |    02/21 00:00    
7   |   02/22  |  30   |    NA       

但是,这会在Date_Hour_Minute列中创建大量重复项。是否有一种方法可以使每次替换都是唯一的,即在第二次遇到NA值时加1分钟,然后在下一个NA值上加2分钟,依此类推,以特定ID和日期?(如果看到该ID的新日期,则计数器重置(。所以结果看起来像这样-

Row  |   Date   |  ID   |     Date_Hour_Minute 
============================================ 
1   |   02/21  |  25   |    02/21 06:02    
2   |   02/21  |  30   |    02/21 00:00 
3   |   02/21  |  30   |    02/21 00:01  (add 1 minute to previous NA value with same date for ID=30) 
4   |   02/21  |  25   |    02/21 00:00  
5   |   02/21  |  25   |    02/21 07:10       
6   |   02/21  |  30   |    02/21 00:02   
7   |   02/22  |  30   |    02/22 00:00 (reset increment counter because new date for ID=30)       

这种方法使用字典来保存下一个默认的时间值,由id和日期键控

import pandas as pd
from io import StringIO 
from datetime import timedelta
# Test data
df1 = pd.read_csv(StringIO ("""
Row|Date|ID|Date_Hour_Minute
1|2018-02-21|25|2018-02-21 06:02
2|2018-02-21|30|NA
3|2018-02-21|30|NA
4|2018-02-21|25|NA
5|2018-02-21|25|2018-02-21 07:10
6|2018-02-21|30|NA
7|2018-02-22|30|NA
"""), sep= "|", parse_dates= ["Date", "Date_Hour_Minute"], infer_datetime_format = True)
# Global dictionary to cache the last assigned value by group
last_date = {}
def enhance_date(p):
""" 
Expects a triple of Date, Id, Date_Hour_Minute
Returns the modified Date_Hour_Minute
"""
# Define the cache
global last_date
#Extract the parameters
date = p[0]
id = p[1]
date_hour_minute = p[2]
# Make a key for the dictionary cache with id and date
key = str(id) + "|" + str(date) 
# Apply the rules ans save next value in cache
if pd.isnull(date_hour_minute):
if key in last_date:
r = last_date[key]
last_date[key] = r + timedelta(minutes=1)
else:
r = date
last_date[key] = r + timedelta(minutes=1)
else:   
r = date_hour_minute
return  r

# Apply to each triple and assign to a new column
df1["New_Date_Hour_Minute"] = df1[["Date", "ID", "Date_Hour_Minute"]].apply(enhance_date, axis=1)
print(df1)

结果

Row       Date  ID    Date_Hour_Minute New_Date_Hour_Minute
0    1 2018-02-21  25 2018-02-21 06:02:00  2018-02-21 06:02:00
1    2 2018-02-21  30                 NaT  2018-02-21 00:00:00
2    3 2018-02-21  30                 NaT  2018-02-21 00:01:00
3    4 2018-02-21  25                 NaT  2018-02-21 00:00:00
4    5 2018-02-21  25 2018-02-21 07:10:00  2018-02-21 07:10:00
5    6 2018-02-21  30                 NaT  2018-02-21 00:02:00
6    7 2018-02-22  30                 NaT  2018-02-22 00:00:00

最新更新