【问题标题】:Interpolate only short gaps in pandas dataframe with DateTimeIndex使用 DateTimeIndex 仅插入 pandas 数据帧中的短间隙
【发布时间】:2021-09-12 02:32:01
【问题描述】:

我正在寻找一种仅在具有 DateTimeIndex 的 Pandas DataFrame 中插入短间隙的方法。较长的间隙应保持原样。

df = pd.DataFrame(
    { "value": [ 1, np.nan, 3, np.nan, np.nan, 5, np.nan, 11, np.nan, 21, np.nan, 41 ] },
    index=pd.to_datetime( [ 
        "2021-01-01 00:00", "2021-01-01 00:05", "2021-01-01 00:10",
        "2021-01-01 00:11", "2021-01-01 00:13", "2021-01-01 00:14",
        "2021-01-01 00:15", "2021-01-01 01:30", "2021-01-01 03:00",
        "2021-01-01 04:00", "2021-01-01 05:45", "2021-01-01 06:45",
    ] )
)
                     value
2021-01-01 00:00:00    1.0
2021-01-01 00:05:00    NaN
2021-01-01 00:10:00    3.0
2021-01-01 00:11:00    NaN
2021-01-01 00:13:00    NaN
2021-01-01 00:14:00    5.0
2021-01-01 00:15:00    NaN
2021-01-01 01:30:00   11.0
2021-01-01 03:00:00    NaN
2021-01-01 04:00:00   21.0
2021-01-01 05:45:00    NaN
2021-01-01 06:45:00   41.0

我们的想法是保留超过特定时间(在本例中为 >5 分钟)的间隙,但在较短的间隙内插入所有缺失值。

interpolate() 有一个 limit 参数,它限制要插入的缺失值的数量,但这不考虑行之间的时间增量,只考虑行数。

我希望结果是这样的:

                         value
2021-01-01 00:00:00   1.000000
2021-01-01 00:05:00   2.000000
2021-01-01 00:10:00   3.000000
2021-01-01 00:11:00   3.500000
2021-01-01 00:13:00   4.500000
2021-01-01 00:14:00   5.000000
2021-01-01 00:15:00        NaN
2021-01-01 01:30:00  11.000000
2021-01-01 03:00:00        NaN
2021-01-01 04:00:00  21.000000
2021-01-01 05:45:00        NaN
2021-01-01 06:45:00  41.000000

【问题讨论】:

  • 不应该绕过 00:10:00 和 01:30:00(80 分钟 - 包括第 11 和 13 分钟)之间的间隔吗?尽管从这两个条目来看,在我看来,插值需要根据已经过去的时间量和时间间隔的长度进行 - 而不仅仅是条目的数量。是吗?
  • 你是对的。我编辑了示例。

标签: python pandas interpolation missing-data datetimeindex


【解决方案1】:

此解决方案填补了时间跨度小于指定值的值差距。填充值与条目在值间隙时间跨度内的位置(时间插值)成比例设置。儒略日期用于更轻松的计算。

设置最大时间跨度间隙以填充时间插值。 5 分钟。

jd_max_gap_fill = 5/(60*24)

计算价值差距:

df['ffill'] = df['value'].ffill()
df['value_gap'] = df['value'].bfill() - df['value'].ffill()

获取条目的儒略日期:

df['jd'] = df.index.to_julian_date()

计算时间间隔:

df['jd_nan'] = np.where(~df['value'].isna(), df['jd'], np.nan)
df['jd_gap'] = df['jd_nan'].bfill() - df['jd_nan'].ffill()

从时间上看,计算我们的价值差距有多远:

df['jd_start'] = df['jd_nan'].ffill() 
df['jd_prp'] = np.where(df['jd_gap'] != 0, (df['jd'] - df['jd_start'])/df['jd_gap'], 0)

计算时间插值:

df['filled_value'] = np.where(df['jd_gap'] <= jd_max_gap_fill, df['ffill'] + df['value_gap'] * df['jd_prp'], np.nan) 

df['filled_value']

2021-01-01 00:00:00     1.0
2021-01-01 00:05:00     NaN
2021-01-01 00:10:00     3.0
2021-01-01 00:11:00     3.5
2021-01-01 00:13:00     4.5
2021-01-01 00:14:00     5.0
2021-01-01 00:15:00     NaN
2021-01-01 01:30:00    11.0
2021-01-01 03:00:00     NaN
2021-01-01 04:00:00    21.0
2021-01-01 05:45:00     NaN
2021-01-01 06:45:00    41.0

请注意,我的输出与您的预期输出不同,因为第一个 NaN 间隔 10 分钟。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-08
    • 2018-06-15
    • 1970-01-01
    • 2015-11-06
    • 2015-08-12
    • 2019-10-11
    • 2020-11-29
    • 1970-01-01
    相关资源
    最近更新 更多