Pandas 上采样和最近插值仅给出 NaN

Pandas upsample and nearest interpolation give only NaNs

我有一个数据帧(df,时间作为索引和 1 列 'Pt0'),我想使用“最近邻”方法对其进行上采样和插值。 我有 2 个问题:

  1. 当我计算 df = df.upsample('1D') 时,我得到一个对象 core.resample.DatetimeIndexResampler,它使我无法恢复我的列的值(但我可以获得索引),而我只想要一个数据框作为输出。我不明白的是,将此命令应用于其他数据框通常会给我一个数据框,而不是那个“核心”对象。
  2. 如果我直接应用上采样和插值:df = df.resample('1D').interpolate(method='nearest')我只获得 NaN,而在我有 NaN 和值之前。

我不明白我做错了什么,我无法理解为什么在其他情况下使用相同的方法 (df.resample('1D')) 为我提供数据帧时会创建“核心”对象。 我该如何解决这个问题?

Ps: df 在索引中没有重复项,因为它是专门计算来避免任何 ().

这是数据框:

df
Out[174]: 
                                 Pt0
1984-06-10 00:00:00.096000064  -42.0
1984-07-20 00:00:00.176000000    NaN
1984-07-28 00:00:00.192000000  -26.0
1984-10-08 00:00:00.336000064  -12.0
1984-10-16 00:00:00.352000000   -5.0
                             ...
2021-04-05 08:48:28.559141120 -248.0
2021-04-05 08:48:29.059141120 -318.0
2021-04-19 20:36:46.060141056 -311.0
2021-05-04 03:02:44.279659008 -254.0
2021-05-29 02:55:17.930625024 -286.0

[529 rows x 1 columns]

重现我的问题的代码:

    df = pd.DataFrame({'Pt0': [np.nan, -42.0, np.nan, np.nan, -26.0, np.nan, np.nan, np.nan, 0.0, -10.0]}, 
                 index=['1984-06-10 00:00:00.096000064', '1984-06-10 00:00:00.096000064',
                        '1984-07-20 00:00:00.176000000', '1984-07-20 00:00:00.176000000',
                        '1984-07-28 00:00:00.192000000', '1984-07-28 00:00:00.192000000',
                        '1984-09-06 00:00:00.080000000', '1984-09-06 00:00:00.080000000',
                        '1984-09-06 00:00:00.271999936', '1984-09-06 00:00:00.271999936'])
    df.index = pd.to_datetime(df.index)
    df = df.groupby(level=0)['Pt0'].transform(np.nanmean).drop_duplicates().to_frame()
    df2 = df.resample('1D')
    df3 = df.resample('1D').interpolate('nearest')

你没有做错任何事,但你之前错过了一步。您需要将源索引与目标索引(天)对齐:1984-06-10 00:00:00.096000064 不等于 1984-06-101984-06-10 00:00:00.000000000。这就是为什么您可以在 Resampler 对象中看到原始值但在最终结果中看不到的原因:

>>> list(df.resample('D'))[0]
(Timestamp('1984-06-10 00:00:00', freq='D'),
                                 Pt0
 1984-06-10 00:00:00.096000064 -42.0)

您需要在resampleinterpolate之间应用一个操作。在目前的情况下,取 first 值就足够了,但想象一下您在同一天有多个值,Pandas 如何猜出要选择哪个值?。 事实上,在上采样以获得额外的天数之前,您需要对日内值进行下采样。

第一步:

>>> df.resample('D').first()  # or mean() or whatever you want
             Pt0
1984-06-10 -42.0  # <- now the index and values are aligned
1984-06-11   NaN
1984-06-12   NaN
1984-06-13   NaN
1984-06-14   NaN
...          ...
1984-09-02   NaN
1984-09-03   NaN
1984-09-04   NaN
1984-09-05   NaN
1984-09-06  -5.0

[89 rows x 1 columns]

第 2 步:

>>> df.resample('D').first().interpolate('time')  # or nearest or ...
                  Pt0
1984-06-10 -42.000000
1984-06-11 -41.666667
1984-06-12 -41.333333
1984-06-13 -41.000000
1984-06-14 -40.666667
...               ...
1984-09-02  -7.100000
1984-09-03  -6.575000
1984-09-04  -6.050000
1984-09-05  -5.525000
1984-09-06  -5.000000

[89 rows x 1 columns]

你可以用 groupby 做同样的事情,因为它更自然,所以更直观: 我想每天对我的值进行分组,然后计算平均值,最后填充缺失值通过使用 X 方法进行插值

>>> df.groupby(pd.Grouper(freq='D')).mean().interpolate('time')
                  Pt0
1984-06-10 -42.000000
1984-06-11 -41.666667
1984-06-12 -41.333333
1984-06-13 -41.000000
1984-06-14 -40.666667
...               ...
1984-09-02  -7.100000
1984-09-03  -6.575000
1984-09-04  -6.050000
1984-09-05  -5.525000
1984-09-06  -5.000000

[89 rows x 1 columns]