pandas.DataFrame.interpolate
允许通过插值相邻值来填充缺失的数据。在它接受的论点中,其中两个似乎与这个问题有关:method
和limit
。
method
:在其他可能的值中,接受"linear"
和"time"
。它们之间的区别在于,"linear"
假定等距行并忽略索引,而"time"
则考虑索引定义的时间间隔进行插值
>>> df = pd.DataFrame({'vals': [11, np.nan, np.nan, 12, np.nan, 22]},
... index=pd.to_datetime(['2020-02-02 11:00', '2020-02-02 11:06', '2020-02-02 11:30',
... '2020-02-02 12:00', '2020-02-02 16:00', '2020-02-02 22:00']))
>>> df.assign(interp_linear=df.interpolate(method='linear'),
... interp_time=df.interpolate(method='time'))
vals interp_linear interp_time
2020-02-02 11:00:00 11.0 11.000000 11.0
2020-02-02 11:06:00 NaN 11.333333 11.1
2020-02-02 11:30:00 NaN 11.666667 11.5
2020-02-02 12:00:00 12.0 12.000000 12.0
2020-02-02 16:00:00 NaN 17.000000 16.0
2020-02-02 22:00:00 22.0 22.000000 22.0
limit
:允许您根据缺失值的数量限制要用插值填充的间隙长度。它需要整数值,并定义为要填充的最大连续 NaN 数。虽然这种行为对于method="linear"
情况是绝对合理的,但对于method="time"
情况似乎有限。
问题
使用插值填充缺失值时,有没有办法通过指定最大时间间隙而不是缺失值的数量来限制要填充的间隙的长度?
具体来说,我想要一种等效于插值method='time'
但仅填充与最后一个和下一个非缺失值相距不超过给定时间增量的缺失值的行为。另一种标准还可以是填充所有缺失值,这些缺失值周围环绕着不远于给定时间增量的非缺失值。微妙不同的选择,但它们都很好。
等效于此:
>>> df.interpolate(method='time', limit='2h')
vals
2020-02-02 11:00:00 11.0
2020-02-02 11:06:00 11.1
2020-02-02 11:30:00 11.5
2020-02-02 12:00:00 12.0
2020-02-02 16:00:00 NaN
2020-02-02 22:00:00 22.0
可以创建和使用掩码来挑选所需的值:
df = pd.DataFrame({'vals': [11, np.nan, np.nan, 12, np.nan, 22]},
index=pd.to_datetime(['2020-02-02 11:00', '2020-02-02 11:06', '2020-02-02 11:30',
'2020-02-02 12:00', '2020-02-02 16:00', '2020-02-02 22:00']))
df['ts'] = df.index
mask = df['ts'].diff() < datetime.timedelta(hours=2)
df["masked_interp"] = df["vals"].interpolate(method='time')[mask]
df["vals"] = df["vals"].combine_first(df["masked_interp"])
给:
vals
2020-02-02 11:00:00 11.0
2020-02-02 11:06:00 11.1
2020-02-02 11:30:00 11.5
2020-02-02 12:00:00 12.0
2020-02-02 16:00:00 NaN
2020-02-02 22:00:00 22.0