Pandas重新采样插值产生NaNs

14

这段内容是关于IT技术的修改版示例,原始示例可以在这里找到:

import io
import pandas as pd
import matplotlib.pyplot as plt

data = io.StringIO('''\
Values
1992-08-27 07:46:48,1
1992-08-27 08:00:48,2
1992-08-27 08:33:48,4
1992-08-27 08:43:48,3
1992-08-27 08:48:48,1
1992-08-27 08:51:48,5
1992-08-27 08:53:48,4
1992-08-27 08:56:48,2
1992-08-27 09:03:48,1
''')
s = pd.read_csv(data, squeeze=True)
s.index = pd.to_datetime(s.index)

res = s.resample('4s').interpolate('linear')
print(res)
plt.plot(res, '.-')
plt.plot(s, 'o')
plt.grid(True)

它的表现符合预期:

1992-08-27 07:46:48    1.000000
1992-08-27 07:46:52    1.004762
1992-08-27 07:46:56    1.009524
1992-08-27 07:47:00    1.014286
1992-08-27 07:47:04    1.019048
1992-08-27 07:47:08    1.023810
1992-08-27 07:47:12    1.028571
....

插值值

但如果我将重采样更改为'5s',它只会生成NaN:

1992-08-27 07:46:45   NaN
1992-08-27 07:46:50   NaN
1992-08-27 07:46:55   NaN
1992-08-27 07:47:00   NaN
1992-08-27 07:47:05   NaN
1992-08-27 07:47:10   NaN
1992-08-27 07:47:15   NaN
....

为什么?


刚刚在这里遇到了这个问题 - 如果“resample”留下了一些数据(而不是全部为NaN),情况会变得更加混乱。 - FObersteiner
2个回答

30

选项1
这是因为'4s'与您现有的索引完全吻合。 当您进行resample时,您会从旧系列中获得表示,并能够进行插值。 您想要做的是创建一个索引,它是旧索引和新索引的并集。 然后用新索引进行插值和重新索引。

oidx = s.index
nidx = pd.date_range(oidx.min(), oidx.max(), freq='5s')
res = s.reindex(oidx.union(nidx)).interpolate('index').reindex(nidx)
res.plot(style='.-')
s.plot(style='o')

选项 2A
如果您愿意放弃准确性,可以将 ffill 与限制为 1


输入图像描述

res = s.resample('5s').ffill(limit=1).interpolate()
res.plot(style='.-')
s.plot(style='o')

选项2B
使用bfill同样做法。


在此输入图片描述

res = s.resample('5s').bfill(limit=1).interpolate()
res.plot(style='.-')
s.plot(style='o')

enter image description here


选项 3
中等复杂度和准确度

nidx = pd.date_range(oidx.min(), oidx.max(), freq='5s')
res = s.reindex(nidx, method='nearest', limit=1).interpolate()
res.plot(style='.-')
s.plot(style='o')

输入图像描述


真的需要这么复杂吗?最终我想要在之后再次对其进行下采样,但我不能仅仅在原始的非均匀采样数据上运行下采样,否则它将无法计算样本之间的信号。 - endolith
2
我看不到使用当前API更简洁的方法。我可能错了,但这是我能做到的最好的。 - piRSquared
3
然而,我添加了一些你可能会喜欢的选项。 - piRSquared
1
@JamesAdams 很高兴能帮到你。 - piRSquared
哇,这真的很有帮助。我找了好久才找到这样的东西。谢谢。 - Jazz Weisman

0
对我来说,我必须添加astype()才能使其正常工作,否则它会产生NaN值:
oidx = s.index
nidx = pd.date_range(oidx.min(), oidx.max(), freq='2min')
res=s.reindex(oidx.union(nidx)).astype(float).interpolate('index').reindex(nidx)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接