Pandas中时间序列缺失如何处理?

补齐时间序列

Table of Contents

处理数据时我们总会遇到令人头疼的时间序列,一方面我们遇到看着是时间又不是时间格式的数据需要我们将其转化为时间格式。另一方面就是这次讨论的时间序列缺失的问题。

👉处理时间格式

  • 准备我们的数据:

数据地址

import numpy as np
import pandas as pd

时间索引缺失如何补齐?

# 数据可以自行下载
file = r'timeseries.csv'
df = pd.read_csv(file, index_col=0)
df
ABCD
2019/10/11 0:0028142515
2019/10/11 1:0011111426
2019/10/11 3:0015121417
2019/10/11 4:0016101412
2019/10/11 6:0024111326
2019/10/11 8:0021292922
2019/10/11 9:0018181725

明显时间索引有缺失的情况,我们可以使用reindex()来处理:

  1. 确保索引是时间格式
  2. 得到完整的时间序列
  3. reindex补齐

为什么要确保时间格式?我们生成的序列要保证时间完整只能使用时间格式,除非自己手动实现复杂的算法。reindex要求两者数据一致,否则你会得到全NAN数据。

df.index
Index(['2019/10/11 0:00', '2019/10/11 1:00', '2019/10/11 3:00',
       '2019/10/11 4:00', '2019/10/11 6:00', '2019/10/11 8:00',
       '2019/10/11 9:00'],
      dtype='object')
# 创建完整的时间格式
t_index = pd.date_range('2019-10-11 00:00:00', '2019-10-11 09:00:00', freq='H')
df.reindex(t_index)
ABCD
2019-10-11 00:00:00NaNNaNNaNNaN
2019-10-11 01:00:00NaNNaNNaNNaN
2019-10-11 02:00:00NaNNaNNaNNaN
2019-10-11 03:00:00NaNNaNNaNNaN
2019-10-11 04:00:00NaNNaNNaNNaN
2019-10-11 05:00:00NaNNaNNaNNaN
2019-10-11 06:00:00NaNNaNNaNNaN
2019-10-11 07:00:00NaNNaNNaNNaN
2019-10-11 08:00:00NaNNaNNaNNaN
2019-10-11 09:00:00NaNNaNNaNNaN

由于CSV文本文件,我们也看到数据类型不对的情况下,全NaN的结果。

  • 重新获取数据,并实现时间格式解析
df = pd.read_csv(file, parse_dates=[0], index_col=0)
df
ABCD
2019-10-11 00:00:0028142515
2019-10-11 01:00:0011111426
2019-10-11 03:00:0015121417
2019-10-11 04:00:0016101412
2019-10-11 06:00:0024111326
2019-10-11 08:00:0021292922
2019-10-11 09:00:0018181725
df.index # 解析成时间格式了
DatetimeIndex(['2019-10-11 00:00:00', '2019-10-11 01:00:00',
               '2019-10-11 03:00:00', '2019-10-11 04:00:00',
               '2019-10-11 06:00:00', '2019-10-11 08:00:00',
               '2019-10-11 09:00:00'],
              dtype='datetime64[ns]', freq=None)
  • 使用完整的时间reindex
df.reindex(t_index)
ABCD
2019-10-11 00:00:0028.014.025.015.0
2019-10-11 01:00:0011.011.014.026.0
2019-10-11 02:00:00NaNNaNNaNNaN
2019-10-11 03:00:0015.012.014.017.0
2019-10-11 04:00:0016.010.014.012.0
2019-10-11 05:00:00NaNNaNNaNNaN
2019-10-11 06:00:0024.011.013.026.0
2019-10-11 07:00:00NaNNaNNaNNaN
2019-10-11 08:00:0021.029.029.022.0
2019-10-11 09:00:0018.018.017.025.0
df.reindex(t_index, fill_value=0) # 使用0填充缺失值
ABCD
2019-10-11 00:00:0028142515
2019-10-11 01:00:0011111426
2019-10-11 02:00:000000
2019-10-11 03:00:0015121417
2019-10-11 04:00:0016101412
2019-10-11 05:00:000000
2019-10-11 06:00:0024111326
2019-10-11 07:00:000000
2019-10-11 08:00:0021292922
2019-10-11 09:00:0018181725

需要补齐的时间序列不是索引?

我们无法保证所有的情况都是使用时间格式作为索引的,那么在这样的情况下我们应该怎么办?

df = pd.read_csv(file, parse_dates=[0], names=list('TABCD'), skiprows=[0])
df
TABCD
02019-10-11 00:00:0028142515
12019-10-11 01:00:0011111426
22019-10-11 03:00:0015121417
32019-10-11 04:00:0016101412
42019-10-11 06:00:0024111326
52019-10-11 08:00:0021292922
62019-10-11 09:00:0018181725

我们手动将时间列命名成"T"

我们可以使用merge()实现:

# 创建一个待混合的数据帧
T_df = pd.DataFrame(t_index, columns=['T'])
T_df
T
02019-10-11 00:00:00
12019-10-11 01:00:00
22019-10-11 02:00:00
32019-10-11 03:00:00
42019-10-11 04:00:00
52019-10-11 05:00:00
62019-10-11 06:00:00
72019-10-11 07:00:00
82019-10-11 08:00:00
92019-10-11 09:00:00
df.merge(T_df, how='right', sort=True)
TABCD
02019-10-11 00:00:0028.014.025.015.0
12019-10-11 01:00:0011.011.014.026.0
22019-10-11 02:00:00NaNNaNNaNNaN
32019-10-11 03:00:0015.012.014.017.0
42019-10-11 04:00:0016.010.014.012.0
52019-10-11 05:00:00NaNNaNNaNNaN
62019-10-11 06:00:0024.011.013.026.0
72019-10-11 07:00:00NaNNaNNaNNaN
82019-10-11 08:00:0021.029.029.022.0
92019-10-11 09:00:0018.018.017.025.0

使用merge的注意点:

  • merge(right), 中right:T_df必须是数据帧(DataFrame),而且列名保持一致
  • sort=True: 保证时间序列的正确
  • 这是实现vlookup的翻版,属于讨巧的办法,如果您有更优雅的方式实现请留言,不甚感激!!!
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值