在 pandas 中进行使用时间插值时是否可以应用时间感知限制?

mga*_*gab 11 python pandas

pandas.DataFrame.interpolate允许通过插入相邻值来填充缺失数据。在它接受的论点中,其中两个似乎与这个问题相关:methodlimit

\n
    \n
  • method:除其他可能的值外,接受"linear""time"。它们之间的区别在于"linear"假设等距行并忽略索引,而"time"插值则考虑索引定义的时间间隔
  • \n
\n
>>> df = pd.DataFrame({'vals': [11, np.nan, np.nan, 12, np.nan, 22]},\n...                   index=pd.to_datetime(['2020-02-02 11:00', '2020-02-02 11:06', '2020-02-02 11:30',\n...                                         '2020-02-02 12:00', '2020-02-02 16:00', '2020-02-02 22:00']))\n>>> df.assign(interp_linear=df.interpolate(method='linear'),\n...           interp_time=df.interpolate(method='time'))\n\n\xef\xbb\xbf                     vals  interp_linear  interp_time\n2020-02-02 11:00:00  11.0      11.000000         11.0\n2020-02-02 11:06:00   NaN      11.333333         11.1\n2020-02-02 11:30:00   NaN      11.666667         11.5\n2020-02-02 12:00:00  12.0      12.000000         12.0\n2020-02-02 16:00:00   NaN      17.000000         16.0\n2020-02-02 22:00:00  22.0      22.000000         22.0\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • limit:允许您根据缺失值的数量限制要使用插值填充的间隙的长度。它需要整数值,并定义为要填充的连续 NaN 的最大数量。虽然这种行为对于本案来说是绝对合理的method="linear",但对于本案来说似乎是有限的method="time"
  • \n
\n

问题

\n

当用插值填充缺失值时,有没有办法通过指定最大时间间隙而不是缺失值的数量来限制要填充的间隙的长度?

\n

具体来说,我想要一种相当于插值的行为method='time',但仅填充距离上一个和下一个非缺失值不远于给定时间增量的缺失值。替代标准还可以填充由不远于给定时间增量的非缺失值包围的所有缺失值。略有不同的选择,但两者都很好。

\n

与此等效的东西:

\n
>>> df.interpolate(method='time', limit='2h')\n\n                     vals\n2020-02-02 11:00:00  11.0\n2020-02-02 11:06:00  11.1\n2020-02-02 11:30:00  11.5\n2020-02-02 12:00:00  12.0\n2020-02-02 16:00:00   NaN\n2020-02-02 22:00:00  22.0\n
Run Code Online (Sandbox Code Playgroud)\n

小智 1

人们可以创建并使用掩码来选取所需的值:

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"])
Run Code Online (Sandbox Code Playgroud)

给予:

                    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
Run Code Online (Sandbox Code Playgroud)