
本教程探讨了在python中,如何高效地处理包含nan的数值数据,并为每个nan值智能地提取其前后指定数量的有效数值。文章将详细介绍如何结合使用pandas的ffill、numpy的sliding_window_view以及数据帧的join操作,以优雅且高效的方式实现这一复杂的数据筛选和选择逻辑,尤其适用于需要处理不规则数据缺失场景下的数据预处理任务。
在数据分析和预处理过程中,我们经常会遇到包含缺失值(NaN)的数值型数据。一个常见的需求是,当某个数据点为NaN时,我们需要从其周围提取固定数量的“有效”(非NaN)数值。这个任务的复杂性在于,有效数值可能不均匀分布在NaN点的前后,且提取过程中可能遇到其他的NaN值,需要灵活处理。传统的循环遍历方法效率低下,难以应对大规模数据集。本教程将介绍一种结合Pandas和NumPy的“巧妙”方法,以实现高效且灵活的NaN邻近有效数据筛选。
本解决方案主要依赖以下Pandas和NumPy的关键功能:
假设我们有一个包含NaN值的Pandas DataFrame,目标是为每个NaN值提取其前B个和后A个有效数值。
首先,我们创建一个示例DataFrame,其中包含一些NaN值,以便演示。
import pandas as pd
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view as swv
# 示例数据
data = {
'col': [np.nan, 0.0, 1.0, 2.0, np.nan, np.nan, 3.0, 4.0, 5.0, np.nan, 6.0, np.nan, 7.0, 8.0, 9.0, np.nan, 10.0]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)我们定义需要提取的有效数值数量:B 为NaN之前的数量,A 为NaN之后的数量。然后,从DataFrame中提取目标列,并创建一个布尔掩码来识别非NaN值。
B = 2 # NaN前需要提取的有效数值数量 A = 3 # NaN后需要提取的有效数值数量 # 提取目标列为Series,并确保索引是范围索引 s = df['col'].reset_index(drop=True) # 识别非NaN行 m = s.notna()
这是解决方案中的一个关键步骤。我们首先将Series的索引转换为Series,然后使用where(m)将NaN值对应的索引替换为NaN,接着使用ffill()将这些NaN索引填充为它们前面最近的有效数值的原始索引。这个idx Series将成为我们后续对齐滑动窗口结果的桥梁。
# 掩盖NaN的索引,并用ffill向前填充,将NaN位置与最近的有效数值索引关联起来 idx = s.index.to_series().where(m).ffill()
现在,idx Series中的每个元素(除了开头连续的NaN)都指向其自身或其前面最近的有效数值的原始索引。
我们将sliding_window_view应用于只包含有效数值的Series (s[m])。这会生成一个多维数组,其中每一行都是一个滑动窗口。
# 在有效数值上应用滑动窗口视图
# A+B 是窗口大小
# 窗口的索引需要特殊处理,以与ffill后的idx对齐
tmp = pd.DataFrame(swv(s[m], A + B),
index=idx[m].shift(-B + 1)[:m.sum() - (A + B) + 1])最后,我们将滑动窗口结果tmp重新索引到idx Series,然后将其索引设置为原始DataFrame的索引,并使用mask(m)操作来清除原始数据中非NaN行对应的邻近数据(因为我们只关心NaN位置的邻近数据),最终通过join操作合并回原始DataFrame。
# 重新索引tmp到ffill后的idx,设置回原始df的索引,并掩盖掉原始数据非NaN行对应的结果
# 这样只有原始数据中为NaN的行,其新列才会有值
out = df.join(tmp.reindex(idx).set_axis(df.index).mask(m))
print("\n处理结果:")
print(out)运行上述代码,您将得到一个扩展的DataFrame:
原始数据:
col
0 NaN
1 0.0
2 1.0
3 2.0
4 NaN
5 NaN
6 3.0
7 4.0
8 5.0
9 NaN
10 6.0
11 NaN
12 7.0
13 8.0
14 9.0
15 NaN
16 10.0
处理结果:
col 0 1 2 3 4
0 NaN NaN NaN NaN NaN NaN
1 0.0 NaN NaN NaN NaN NaN
2 1.0 NaN NaN NaN NaN NaN
3 2.0 NaN NaN NaN NaN NaN
4 NaN 1.0 2.0 3.0 4.0 5.0
5 NaN 1.0 2.0 3.0 4.0 5.0
6 3.0 NaN NaN NaN NaN NaN
7 4.0 NaN NaN NaN NaN NaN
8 5.0 NaN NaN NaN NaN NaN
9 NaN 4.0 5.0 6.0 7.0 8.0
10 6.0 NaN NaN NaN NaN NaN
11 NaN 5.0 6.0 7.0 8.0 9.0
12 7.0 NaN NaN NaN NaN NaN
13 8.0 NaN NaN NaN NaN NaN
14 9.0 NaN NaN NaN NaN NaN
15 NaN NaN NaN NaN NaN NaN
16 10.0 NaN NaN NaN NaN NaN观察输出结果:
本教程介绍了一种在Python中利用Pandas和NumPy高效处理NaN值并提取其邻近有效数据的专业方法。通过结合 pandas.Series.ffill()、numpy.lib.stride_tricks.sliding_window_view() 和 pandas.DataFrame.join(),我们能够以一种矢量化、高性能的方式解决这一常见的数据预处理挑战。这种方法不仅代码简洁,而且能够优雅地处理各种复杂的边界条件和NaN分布情况,是数据科学家和工程师在处理不规则缺失数据时的有力工具。
以上就是利用Pandas和NumPy高效筛选NaN附近有效数据的教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号