极坐标上采样/下采样并仅插入小间隙

问题描述 投票:0回答:1

我有一个时间序列数据集,需要进行插值,以便任何超过 3 分钟的间隙都保留为空值。

我面临的问题是,即使有接近该时间段的数据,Polars 上采样也会导致大量空值。这是数据框的片段。

                     utc       gnd_p   gnd_t    app_sza     azimuth         xh2o      xair        xco2      xch4  xco  xch4_s5p
0    2022-06-04 04:49:31  955.081699  293.84  77.009159 -109.292040  4118.807354  0.996515  421.510185  1.878339  0.0       0.0
1    2022-06-04 04:49:46  955.081655  293.84  76.971435 -109.250593  4119.081639  0.996508  421.543444  1.878761  0.0       0.0

这是相同操作的 Pandas 代码

    output = sensor_dataframe.sort_values(by=['utc']) # sort according to time
    output['utc'] = pd.to_datetime(output['utc'])
    # Apply smoothing function for all data columns.
    for column in output.columns[1::]:
        output[column] = scipy.signal.savgol_filter(pd.to_numeric(output[column]), 31, 3)
    print(output)
    output = output.set_index('utc')
    output.index = pd.to_datetime(output.index)
    output = output.resample(sampling_rate).mean()

    sampling_delta = pd.to_timedelta(sampling_rate)
    # The interpolating limit is dependant on the sampling rate.
    interpolating_limit = int(MAX_DELTA_FOR_INTERPOLATION / sampling_delta)

    if interpolating_limit != 0:
        output.interpolate(
            limit=interpolating_limit,
            inplace=True,
            limit_direction='both',
            limit_area='inside',
        )

这是 10 秒采样率的输出。

                          gnd_p   gnd_t    app_sza     azimuth         xh2o      xair        xco2      xch4  xco  xch4_s5p
utc                                                                                                                       
2022-06-04 04:49:30  955.081699  293.84  77.009159 -109.292040  4118.807354  0.996515  421.510185  1.878339  0.0       0.0
2022-06-04 04:49:40  955.081655  293.84  76.971435 -109.250593  4119.081639  0.996508  421.543444  1.878761  0.0       0.0

这是对 Polars 版本的相同尝试。

    df = pl.from_pandas(sensor_dataframe)
    q = df.lazy().with_column(pl.col('utc').str.strptime(pl.Datetime, fmt='%F %T').cast(pl.Datetime)).select([pl.col('utc'),
                    pl.exclude('utc').map(lambda x: savgol_filter(x.to_numpy(), 31, 3)).explode()])
    df = q.collect()
    df = df.upsample(time_column="utc", every="10s")

这是上述截图的输出

│ 2022-06-04 04:49:31 ┆ 955.081699 ┆ 293.84 ┆ 77.009159 ┆ ... ┆ 421.510185 ┆ 1.878339 ┆ 0.0  ┆ 0.0      │
│ 2022-06-04 04:49:41 ┆ null       ┆ null   ┆ null      ┆ ... ┆ null       ┆ null     ┆ null ┆ null     │
│ 2022-06-04 04:49:51 ┆ null       ┆ null   ┆ null      ┆ ... ┆ null       ┆ null     ┆ null ┆ null     │

Polars 只是吐出一个带有大量 null 的 df 。我必须进行插值来填充值,但这意味着我要对整个数据集进行插值。不幸的是,Polars 没有在 interpolate() 上提供参数或参数,这导致所有系列都被插值,这不是所需的操作。

我认为解决方案应该与口罩有关。有人有使用极坐标和插值的经验吗?

可重现代码:https://pastebin.com/gQ1WU4zp 示例 csv 数据:https://0bin.net/paste/3fX2AOM2#uQmEv2KvBK5Xk-2vuWxx2z0QgXlttdnaa78eFt8ra62

python pandas time-series interpolation python-polars
1个回答
1
投票

我不会下载您的整个数据集,所以让我们以此为例:

np.random.seed(0)
df = pl.DataFrame(
    {
        "time": pl.datetime_range(
            datetime(2023, 2, 1),
            datetime(2023, 2, 2),
            interval="1m",
            eager=True),
        'data':list(np.random.choice([None, 1,2,3,4], size=1441))
    }).filter(~pl.col('data').is_null())
  1. upsample,根据定义,不会插值,它(正如您所发现的)只是插入一堆空值来匹配您想要的周期。

  2. 如果您只想在预上采样间隙为 3m 或更小时进行插值,请在上采样之前创建一个辅助列。

  3. 使用

    when
    then
    查看辅助列来插值或不插值。

    df \
        .with_columns(
             (pl.col('time')-pl.col('time').shift()<pl.duration(minutes=3)).alias('small_gap')) \
        .upsample(time_column="time", every="10s") \
        .with_columns(pl.col('small_gap').backward_fill()) \
        .with_columns(
            pl.when(pl.col('small_gap')) \
                .then(pl.exclude('small_gap').interpolate()) \
                .otherwise(pl.exclude('small_gap'))) \
        .drop('small_gap')
    
© www.soinside.com 2019 - 2024. All rights reserved.