news 2026/10/27 21:40:45

如何:处理时间序列的缺失数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何:处理时间序列的缺失数据

原文:towardsdatascience.com/how-to-handle-missing-data-for-time-series-680810f648ed

如何:处理时间序列的缺失数据

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d30ad994a36a0c060c199b5a946fb618.png

图片由 Mika Baumeister 在 Unsplash 上提供

没有完美无缺的数据集。每个数据科学家都知道在数据探索过程中,当他们调用:

df.info()

并看到如下内容时那种感觉:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/389cb7a077cffb932261cc18a03fd758.png

UCI 机器学习仓库空气质量数据集 信息 (CC BY 4.0)。图片由作者提供

大多数机器学习模型无法处理 NaN 或空值,因此如果您的特征或目标包含它们,在尝试将模型拟合到数据之前,它们必须得到适当的处理。

在这篇文章中,我将探讨处理时间序列数据集中空值/缺失数据的 3 种简单方法。

1. 删除空值

这可能是处理缺失数据最简单、最直接的方法:就是将其删除。

# Drop any and all nulls across all columnsdf.dropna(inplace=True)

默认情况下,pandas 的 dropna 函数会在所有列中搜索空值,并删除任何列中存在空值的行。然而,这可以通过各种参数进行修改。

在这个数据集的情况下,注意列 NMHC(GT) 只有 914 个非空值。因此,如果我们删除所有空值,我们的模型最终最多只有 914 行(可能更少)数据。这与原始的 9,357 行相比是一个巨大的减少!

通过指定subset的列,pandas 将只删除数据框中那些特定列存在空值的行。

df.dropna(subset=['CO(GT)','PT08.S1(CO)'],inplace=True)

这样我们就可以混合匹配方法,在一些列中删除空值,而在其他列中采取不同的处理方式。

您也可以指定是否只想删除所有列都为空的行,通过设置参数how为 “all”。默认的 how 值为 “any”。

2. 插值处理空值

另一种填充空值简单的方法是通过插值。Pandas 的 interpolate 方法默认使用线性插值。

线性插值基本上取空值前后两个值,并在它们之间创建一条线。然后它使用这条线来估计缺失数据点的值。Pandas 的 interpolate 方法假设每个数据点都是等间距的。如果你没有每个可能时间戳的行,只要你有 datetime 索引,你可以将插值方法设置为"time"。这样,如果你有两个连续的行,它们之间间隔大于 1 个区间(例如大于 1 天或 1 小时),插值将考虑这个距离。

如果这是第一个索引,由于没有值在空值之前,它将不会进行插值。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/5db600e1977266da37366d0ce61b59bf.png

图片由作者提供

在这个例子中,由于有一个空值正好位于两个已知值中间,插值很简单。所有值都均匀分布在 1 小时内。索引为 10 的空值将简单地是前后值的平均值(0.65)。

如果有 2 个或更多连续的 NaNs,它们将考虑它们与已知值之间的距离进行插值。

更多关于线性插值工作原理的详细信息,请参阅这里。

你可以通过limit关键字参数设置连续 NaNs 的最大插值数量。如果有很多连续的 NaNs,你可能想在插值到一定点后直接删除这些值,因为每次插值都会给算法引入不确定性。更多的插值意味着更大的不确定性,尤其是在时间序列的情况下。

3. 填充空值

我要介绍的最后一个方法是填充。填充本质上意味着你用数据的平均值或中位数来填补空值。

做这件事最简单的方法是使用 pandas 的 fillna 函数,并取整个列的中位数。

df.fillna(df['CO(GT)'].median())

但是,当涉及到时间序列时,整个数据集的中位数往往不准确。时间序列数据通常具有季节性模式,其中使用量根据一天中的小时、一周中的日子、月份等而变化。

在这个例子中,我决定使用该小时的中位数来填充 CO(GT)列。

为了能够使用中位数进行填充,我提出了自己的解决方案,因为没有直接的方法或库来做这件事(据我所知)。我首先创建了一个包含所有相应小时中位数的 dataframe。

# Create dataframe which contains the median for each column grouped by# hourhour_df=pd.DataFrame(df.groupby([df.index.hour]).median())hour_df.reset_index(inplace=True)

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/7ff4d7b0ae9a4afcda3e8a0732f2c153.png

结果的分组中位数按小时显示的数据框。仅显示前 5 小时和 3 列。图片由作者提供

接下来,我创建了一个名为 get_hour_median 的函数。虽然我只展示了 CO(GT)列,但我使这个函数足够灵活,可以处理任何列名。

defget_hour_median(hour,col_name):median=hour_df[hour_df['Datetime']==hour][col_name].values[0]returnmedian

然后我使用 apply 和另一个自定义函数将此函数应用于 CO(GT)列。

# Reset datetime index for easier processing in functions belowdf.reset_index(inplace=True)# Takes in a dataframe row and returns a median value if row# is null, otherwise return original value.deffill_with_hourly_median(row,col_name):ifpd.isnull(row[col_name]):returnget_hour_median(row['Datetime'].hour,col_name)else:returnrow[col_name]# Apply fill_with_hourly_median to CO(GT) columndf['CO(GT)']=df.apply(fill_with_hourly_median,axis=1,col_name='CO(GT)')

CO(GT)列现在应该填充了对应小时的中间值,而不是 NaNs。

应该选择哪一个?

很多次,你会为不同的列使用不同方法的组合。例如,由于线性插值无法填充列中的第一个值,如果数据框开头有 null 行,这些行可以在数据框中间的行被插值后删除。

如果你有很多数据,但 null 值不多,删除几行不会造成很大差异。在这种情况下,删除通常是我的首选方法,因为我要输入模型的所有数据都是实际数据。

对于数据集中偶尔出现的小间隔(1-2 个缺失行),我通常会使用插值。然而,如果间隔较大,且有大量连续的 null 值,我会考虑使用中间值直到某个阈值(>6-10,但可能取决于数据的粒度和模式的一致性),之后我会开始删除行。

如你所见,尽管处理缺失数据是常见的情况,但处理它需要考虑很多因素。我提到的方法绝对不是唯一的,但仅使用这三种选项,你就能做很多事情。

我建议彻底探索你的时间序列数据,通过绘制图表并确定 null 值的位置,无论间隔大小,以及存在的季节性模式。随着时间的推移和实践,你会对如何最好地处理数据中的间隔形成更好的直觉。

参考文献

  1. Vito, Saverio. (2016). Air Quality. UCI Machine Learning Repository.doi.org/10.24432/C59K5F.
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/26 8:03:08

RS485和RS232在STM32上的应用实战案例

从调试到组网:STM32上的RS232与RS485实战全解析 在工业现场,你是否遇到过这样的场景?设备之间距离几十米,信号干扰严重,数据时断时续;或者调试阶段串口输出乱码,换根线就好了——背后往往就是通…

作者头像 李华
网站建设 2026/10/27 8:51:45

从零实现:通过元件对照表添加自定义IC模型(Proteus 8.9)

手把手教你用元件对照表在 Proteus 8.9 中添加自定义 IC 模型你有没有遇到过这种情况:手头正在设计一款基于新型传感器的嵌入式系统,原理图画得差不多了,准备仿真验证功能时却发现——Proteus 根本找不到这个芯片?别慌。这不是你的…

作者头像 李华
网站建设 2026/10/27 3:07:17

GPT-SoVITS在虚拟偶像领域的应用前景分析

GPT-SoVITS在虚拟偶像领域的应用前景分析 在一场虚拟演唱会的直播中,观众几乎无法分辨舞台上那位“歌姬”是真人还是AI——她不仅拥有细腻动人的声线,还能实时回应弹幕提问,语调自然、情感充沛。这背后,正是以GPT-SoVITS为代表的少…

作者头像 李华
网站建设 2026/10/26 8:52:45

用GPT-SoVITS打造专属语音助手,仅需少量音频数据即可完成

用GPT-SoVITS打造专属语音助手,仅需少量音频数据即可完成 在智能语音产品日益普及的今天,你是否曾想过——只需一段一分钟的录音,就能训练出一个“声音分身”,让它替你朗读文章、播报消息,甚至扮演你的虚拟形象与人对话…

作者头像 李华
网站建设 2026/10/27 3:52:15

语音克隆还能这么玩?GPT-SoVITS带你体验AI声线定制

语音克隆还能这么玩?GPT-SoVITS带你体验AI声线定制 在短视频、虚拟偶像和个性化内容爆发的今天,一个让人“耳熟”的声音可能比一张脸更具辨识度。你有没有想过,只需一段几十秒的录音,就能让AI完美复刻你的声线,替你说出…

作者头像 李华
网站建设 2026/10/22 7:43:51

Proteus8.9下载安装教程:从零实现仿真环境搭建全流程

从零搭建Proteus仿真环境:一次搞定8.9版本安装与实战配置 你是不是也遇到过这样的情况?想做个单片机实验,却发现手头没有开发板;或者电路刚焊好,通电就冒烟……别急,在动手之前,完全可以用仿真…

作者头像 李华