【问题标题】:Add missing times in dataframe column with pandas使用熊猫在数据框列中添加缺失时间
【发布时间】:2018-03-15 13:12:51
【问题描述】:

我有一个这样的数据框:

df = pd.DataFrame({'time':['23:59:45','23:49:50','23:59:55','00:00:00','00:00:05','00:00:10','00:00:15'],
                   'X':[-5,-4,-2,5,6,10,11],
                   'Y':[3,4,5,9,20,22,23]})

如您所见,时间由小时(字符串格式)组成,并且跨越午夜。每5秒给一次时间! 然而,我的目标是添加空行(例如用 Nan 填充),以便时间是每秒。最后将列时间转换为时间戳并设置为索引。

您能否建议一种聪明而优雅的方式来实现我的目标?

下面是输出的样子:

           X     Y
time   
23:59:45  -5.0   3.0
23:59:46   NaN   NaN
23:59:47   NaN   NaN
23:59:48   NaN   NaN
...        ...   ...
00:00:10  10.0  22.0
00:00:11   NaN   NaN
00:00:12   NaN   NaN
00:00:13   NaN   NaN
00:00:14   NaN   NaN
00:00:15  11.0  23.0

注意:我不需要日期。

【问题讨论】:

    标签: python pandas datetime dataframe time


    【解决方案1】:

    to_timedeltareindex 一起使用timedelta_range

    df['time'] = pd.to_timedelta(df['time'])
    idx = pd.timedelta_range('0', '23:59:59', freq='S', name='time')
    
    df = df.set_index('time').reindex(idx).reset_index()
    print (df.head(10))
          time    X     Y
    0 00:00:00  5.0   9.0
    1 00:00:01  NaN   NaN
    2 00:00:02  NaN   NaN
    3 00:00:03  NaN   NaN
    4 00:00:04  NaN   NaN
    5 00:00:05  6.0  20.0
    6 00:00:06  NaN   NaN
    7 00:00:07  NaN   NaN
    8 00:00:08  NaN   NaN
    9 00:00:09  NaN   NaN
    

    如果需要替换NaNs:

    df = df.set_index('time').reindex(idx, fill_value=0).reset_index()
    print (df.head(10))
          time  X   Y
    0 00:00:00  5   9
    1 00:00:01  0   0
    2 00:00:02  0   0
    3 00:00:03  0   0
    4 00:00:04  0   0
    5 00:00:05  6  20
    6 00:00:06  0   0
    7 00:00:07  0   0
    8 00:00:08  0   0
    9 00:00:09  0   0
    

    resample 的另一种解决方案,但最后可能缺少某些行:

    df = df.set_index('time').resample('S').first()
    print (df.tail(10))
                X    Y
    time              
    23:59:46  NaN  NaN
    23:59:47  NaN  NaN
    23:59:48  NaN  NaN
    23:59:49  NaN  NaN
    23:59:50  NaN  NaN
    23:59:51  NaN  NaN
    23:59:52  NaN  NaN
    23:59:53  NaN  NaN
    23:59:54  NaN  NaN
    23:59:55 -2.0  5.0
    

    编辑1:

    idx1 = pd.timedelta_range('23:59:45', '23:59:59', freq='S', name='time')
    idx2 = pd.timedelta_range('0', '00:00:15', freq='S', name='time')
    idx = np.concatenate([idx1, idx2])
    
    df['time'] = pd.to_timedelta(df['time'])        
    df = df.set_index('time').reindex(idx).reset_index()
    print (df.head(10))
          time    X    Y
    0 23:59:45 -5.0  3.0
    1 23:59:46  NaN  NaN
    2 23:59:47  NaN  NaN
    3 23:59:48  NaN  NaN
    4 23:59:49  NaN  NaN
    5 23:59:50  NaN  NaN
    6 23:59:51  NaN  NaN
    7 23:59:52  NaN  NaN
    8 23:59:53  NaN  NaN
    9 23:59:54  NaN  NaN
    
    print (df.tail(10))
           time     X     Y
    21 00:00:06   NaN   NaN
    22 00:00:07   NaN   NaN
    23 00:00:08   NaN   NaN
    24 00:00:09   NaN   NaN
    25 00:00:10  10.0  22.0
    26 00:00:11   NaN   NaN
    27 00:00:12   NaN   NaN
    28 00:00:13   NaN   NaN
    29 00:00:14   NaN   NaN
    30 00:00:15  11.0  23.0
    

    编辑:

    另一种解决方案 - 将第二天更改为 1 天时间增量:

    df['time'] = pd.to_timedelta(df['time'])        
    
    a = pd.to_timedelta(df['time'].diff().dt.days.abs().cumsum().fillna(1).sub(1), unit='d')
    df['time'] = df['time'] + a
    print (df)
        X   Y            time
    0  -5   3 0 days 23:59:45
    1  -4   4 0 days 23:49:50
    2  -2   5 0 days 23:59:55
    3   5   9 1 days 00:00:00
    4   6  20 1 days 00:00:05
    5  10  22 1 days 00:00:10
    6  11  23 1 days 00:00:15
    
    idx = pd.timedelta_range(df['time'].min(), df['time'].max(), freq='S', name='time')
    
    df = df.set_index('time').reindex(idx).reset_index()
    

    print (df.head(10))
          time    X    Y
    0 23:49:50 -4.0  4.0
    1 23:49:51  NaN  NaN
    2 23:49:52  NaN  NaN
    3 23:49:53  NaN  NaN
    4 23:49:54  NaN  NaN
    5 23:49:55  NaN  NaN
    6 23:49:56  NaN  NaN
    7 23:49:57  NaN  NaN
    8 23:49:58  NaN  NaN
    9 23:49:59  NaN  NaN
    
    print (df.tail(10))
                   time     X     Y
    616 1 days 00:00:06   NaN   NaN
    617 1 days 00:00:07   NaN   NaN
    618 1 days 00:00:08   NaN   NaN
    619 1 days 00:00:09   NaN   NaN
    620 1 days 00:00:10  10.0  22.0
    621 1 days 00:00:11   NaN   NaN
    622 1 days 00:00:12   NaN   NaN
    623 1 days 00:00:13   NaN   NaN
    624 1 days 00:00:14   NaN   NaN
    625 1 days 00:00:15  11.0  23.0
    

    【讨论】:

    • 感谢您的回答,但它有一个问题,因为时间应该从“23:59:45”开始,到“00:00:15”(后一天)结束。因此我只需要在这 2 次之间填充数据框
    • 嗯,你能添加想要的输出吗?
    • 还应该有更多1午夜?
    • 午夜只是一个极端情况,所以无论我选择什么开始和结束时间,这个例子都是有效的
    • 不是那么容易 - 需要concatenate 2 个不同的范围。
    猜你喜欢
    • 2017-07-29
    • 2022-01-13
    • 1970-01-01
    • 2021-05-27
    • 2022-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多