一、问题背景
以二氧化碳浓度数据集为例,该时间序列在某些时间点上会有缺失值。
# 读取数据集
df = pd.read_csv('二氧化碳浓度.csv')
# 将字段Datetime数据类型转换为日期类型
df['datetime'] = pd.to_datetime(df['datetime'], format="%Y-%m-%d %H:%M:%S")
df
value | datetime | |
---|---|---|
0 | 370 | 2022-04-13 00:11:00 |
1 | 375 | 2022-04-13 00:42:00 |
2 | 383 | 2022-04-13 01:11:00 |
3 | 391 | 2022-04-13 01:41:00 |
4 | 397 | 2022-04-13 02:11:00 |
... | ... | ... |
583 | 369 | 2022-04-23 22:12:00 |
584 | 376 | 2022-04-23 22:41:00 |
585 | 379 | 2022-04-23 23:11:00 |
586 | 379 | 2022-04-23 23:12:00 |
587 | 378 | 2022-04-23 23:41:00 |
588 rows × 2 columns
该数据集是没个半小时一条数据,若想要填充成10分钟一条数据,就需要进行线性插值。
二、pandas解决方案
下面我们需要生成一个辅助dataframe,命名为helper, 包含所有日期。
# pd.date_range时间序列
# 间隔十分钟
helper = pd.DataFrame({'datetime': pd.date_range(start=df['datetime'].min(), end=df['datetime'].max(),freq='600s')})
# helper = pd.DataFrame(helper).set_index('datetime')#将时间列变为索引
helper:
datetime | |
---|---|
0 | 2022-04-13 00:11:00 |
1 | 2022-04-13 00:21:00 |
2 | 2022-04-13 00:31:00 |
3 | 2022-04-13 00:41:00 |
4 | 2022-04-13 00:51:00 |
... | ... |
1577 | 2022-04-23 23:01:00 |
1578 | 2022-04-23 23:11:00 |
1579 | 2022-04-23 23:21:00 |
1580 | 2022-04-23 23:31:00 |
1581 | 2022-04-23 23:41:00 |
1582 rows × 1 columns
然后再将helper和d join起来
d = pd.merge(df, helper, on='datetime', how='outer').sort_values('datetime')
最后一步就是插值了,直接用interpolate方法,method选择linear,线性插值。
d['value'] = d['value'].interpolate(method='linear')
value | datetime | |
---|---|---|
0 | 370.0 | 2022-04-13 00:11:00 |
588 | NaN | 2022-04-13 00:21:00 |
589 | NaN | 2022-04-13 00:31:00 |
590 | NaN | 2022-04-13 00:41:00 |
1 | 375.0 | 2022-04-13 00:42:00 |
... | ... | ... |
585 | 379.0 | 2022-04-23 23:11:00 |
586 | 379.0 | 2022-04-23 23:12:00 |
1658 | NaN | 2022-04-23 23:21:00 |
1659 | NaN | 2022-04-23 23:31:00 |
587 | 378.0 | 2022-04-23 23:41:00 |
1660 rows × 2 columns
插值选择方法不止有线性,还可以是
- nearest:最邻近插值法
- zero:阶梯插值
- slinear、linear:线性插值
- quadratic、cubic:2、3阶B样条曲线插值(详情请参考官方文档)