Pandas 上采样和最近插值仅给出 NaN
Pandas upsample and nearest interpolation give only NaNs
我有一个数据帧(df
,时间作为索引和 1 列 'Pt0'),我想使用“最近邻”方法对其进行上采样和插值。
我有 2 个问题:
- 当我计算
df = df.upsample('1D')
时,我得到一个对象 core.resample.DatetimeIndexResampler,它使我无法恢复我的列的值(但我可以获得索引),而我只想要一个数据框作为输出。我不明白的是,将此命令应用于其他数据框通常会给我一个数据框,而不是那个“核心”对象。
- 如果我直接应用上采样和插值:
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-10
即 1984-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)
您需要在resample
和interpolate
之间应用一个操作。在目前的情况下,取 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]
我有一个数据帧(df
,时间作为索引和 1 列 'Pt0'),我想使用“最近邻”方法对其进行上采样和插值。
我有 2 个问题:
- 当我计算
df = df.upsample('1D')
时,我得到一个对象 core.resample.DatetimeIndexResampler,它使我无法恢复我的列的值(但我可以获得索引),而我只想要一个数据框作为输出。我不明白的是,将此命令应用于其他数据框通常会给我一个数据框,而不是那个“核心”对象。 - 如果我直接应用上采样和插值:
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-10
即 1984-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)
您需要在resample
和interpolate
之间应用一个操作。在目前的情况下,取 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]