python - Pandas 将 NaN 从零插入到下一个有效值
问题描述
我正在寻找一种将缺失值 (NaN) 从零线性插值到下一个有效值的方法。
例如:
A B C D E
0 NaN 2.0 NaN NaN 0
1 3.0 4.0 NaN NaN 1
2 NaN NaN NaN NaN 5
3 NaN 3.0 NaN NaN 4
鉴于此表,我希望输出如下所示:
A B C D E
0 NaN 2.0 0 0 0
1 3.0 4.0 0 0.5 1
2 NaN NaN NaN NaN 5
3 NaN 3.0 0 2 4
我尝试使用fillna仅将下一个 NaN 填充为 0 的有效值,然后对整个数据帧进行线性插值。我在这里面临的问题是使用 fillna 指定值和限制不会影响连续的 NaN,但会限制要填充的列的总数。
如果可能,请仅建议解决方案,而无需手动迭代每一行,因为我正在使用大型数据框。
提前致谢。
解决方案
这是一种方法,可以将 0 替换为NaN
有效数字之后的第一个,然后按行进行插值。我在最后添加了额外的行,以说明同一行上的多个填充、仅一个值的填充或以 NaN 条纹结尾的行的行为。
样本数据
A B C D E
0 NaN 2.0 NaN NaN 0
1 3.0 4.0 NaN NaN 1
2 NaN NaN NaN NaN 5
3 NaN 3.0 NaN NaN 4
4 3 NaN 7 NaN 5
5 NaN 4 7 NaN 6
6 NaN 4 7 NaN NaN
7 5 NaN 5 NaN NaN
代码
m = (df.notnull().cummax(axis=1) & df.isnull()).astype(int).diff(axis=1).fillna(0)
update = m.where(m.eq(1) & m.loc[:, ::-1].cummin(axis=1).eq(-1)).replace(1, 0)
df.update(update) # Add in 0s
df = df.interpolate(axis=1, limit_area='inside')
A B C D E
0 NaN 2.0 0.0 0.0 0.0
1 3.0 4.0 0.0 0.5 1.0
2 NaN NaN NaN NaN 5.0
3 NaN 3.0 0.0 2.0 4.0
4 3.0 0.0 7.0 0.0 5.0
5 NaN 4.0 7.0 0.0 6.0
6 NaN 4.0 7.0 NaN NaN
7 5.0 0.0 5.0 NaN NaN
这个怎么运作:
(df.notnull().cummax(1) & df.isnull()) # True for streaks of null after non-null
# A B C D E
#0 False False True True False
#1 False False True True False
#2 False False False False False
#3 False False True True False
#4 False True False True False
#5 False False False True False
#6 False False False True True
#7 False True False True True
# Taking the diff then allows you to find only the first NaN after any non-null.
# I.e. flagged by `1`
(df.notnull().cummax(1) & df.isnull()).astype(int).diff(axis=1).fillna(0)
# A B C D E
#0 0.0 0.0 1.0 0.0 -1.0
#1 0.0 0.0 1.0 0.0 -1.0
#2 0.0 0.0 0.0 0.0 0.0
#3 0.0 0.0 1.0 0.0 -1.0
#4 0.0 1.0 -1.0 1.0 -1.0
#5 0.0 0.0 0.0 1.0 -1.0
#6 0.0 0.0 0.0 1.0 0.0
#7 0.0 1.0 -1.0 1.0 0.0
# The update DataFrame is a like-indexed DF with 0s where they get filled.
# The reversed cummin ensures fills only if there's a non-null value after the 0.
m.where(m.eq(1) & m.loc[:, ::-1].cummin(1).eq(-1)).replace(1, 0)
# A B C D E
#0 NaN NaN 0.0 NaN NaN
#1 NaN NaN 0.0 NaN NaN
#2 NaN NaN NaN NaN NaN
#3 NaN NaN 0.0 NaN NaN
#4 NaN 0.0 NaN 0.0 NaN
#5 NaN NaN NaN 0.0 NaN
#6 NaN NaN NaN NaN NaN
#7 NaN 0.0 NaN NaN NaN
推荐阅读
- spring-kafka - 如何使用密钥库中的特定密钥在 Kafka 中配置 SSL
- docker - 未在 localhost 上运行的 Docker 容器
- bash - 从参数中读取 JSON
- javascript - 希望制作检查 2 个用户输入的表单验证功能
- python - python setuptools - 你可以从特定的存储库下载吗?
- r - 通过 rJava 复制 java -jar 执行
- java - 尝试模拟静态时的 NoClassDefFoundError 或 NoSuchMethodError(不兼容的依赖项)
- c# - 创建新目录返回错误:“System.UnauthorizedAccessException:'访问路径'C:\ Users'被拒绝。'
- azureservicebus - Azure 服务总线可以与 Mailchimp API 通信吗?
- image - 图像未在 Git 中心页面上呈现