如何正确地对时间序列数据进行重采样?

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

我在 PostgreSQL 数据库上有时间序列数据。目前,我将其导入 pandas 进行一些分析,我的第一步通常是将 5 分钟频率数据重新采样为 1 小时平均数据。我这样做是为了首先对数据进行旋转以使其呈现宽格式,然后将其重新采样到 1 小时,然后将其融化以再次使其呈现长格式。

现在我想对数据库进行重采样,以便我可以立即导入 1 小时平均值。

这就是数据库中数据的样子。我有两种不同的类型,有 3 个不同的名称。

    datetime                    value   type   name
0    2018-01-01 13:35:00+01:00   0.22    HLN    NO2
1    2018-01-01 13:35:00+01:00   0.31    HLN    CO
2    2018-01-01 13:35:00+01:00   1.15    HLN    NO
3    2018-01-01 13:40:00+01:00   1.80    AIS    NO2
4    2018-01-01 13:40:00+01:00   2.60    AIS    CO
5    2018-01-01 13:40:00+01:00   2.30    AIS    NO
6    2018-01-01 13:45:00+01:00   2.25    HLN    NO2
7    2018-01-01 13:45:00+01:00   2.14    HLN    CO
8    2018-01-01 13:45:00+01:00   2.96    HLN    NO
9    2018-01-01 14:35:00+01:00   0.76    HLN    NO2
10   2018-01-01 14:35:00+01:00   0.80    HLN    CO
11   2018-01-01 14:35:00+01:00   1.19    HLN    NO
12   2018-01-01 14:40:00+01:00   1.10    AIS    NO2
13   2018-01-01 14:40:00+01:00   2.87    AIS    CO
14   2018-01-01 14:40:00+01:00   2.80    AIS    NO
15   2018-01-01 14:45:00+01:00   3.06    HLN    NO2
16   2018-01-01 13:45:00+01:00   2.86    HLN    CO
17   2018-01-01 13:45:00+01:00   2.22    HLN    NO

现在是我遇到问题的部分。在 pandas 中重新采样并绘制后,我得到了正确的预期结果,每小时一个值:

enter image description here

执行 SQL 查询后,使用以下代码将其重新采样为一小时:

SELECT date_trunc('hour', datetime) AS hour, type, AVG(value) AS measure, name
                    FROM data_table
                    GROUP BY datetime, type, name
                    ORDER BY datetime

我在绘图后得到这个:

enter image description here

这不太顺利,一小时内有多个值,我猜一小时内有所有值。

我的问题,如何在 SQL 中正确地对时间序列进行重新采样?

编辑:表格形式的预期结果:

 datetime             value  type  name
2018-01-01 13:00:00   1.235   HLN   NO2
2018-01-01 13:00:00   2.65   HLN   CO
2018-01-01 13:00:00   2.96   HLN   NO
2018-01-01 13:00:00   2.48   AIS   NO2
2018-01-01 13:00:00   2.65   AIS   CO
2018-01-01 13:00:00   2.26   AIS   NO
2018-01-01 14:00:00   2.78   HLN   NO2
2018-01-01 14:00:00   3.65   HLN   CO
2018-01-01 14:00:00   1.95   HLN   NO
2018-01-01 14:00:00   1.45   AIS   NO2
2018-01-01 14:00:00   1.64   AIS   CO
2018-01-01 14:00:00   3.23   AIS   NO

sql postgresql
1个回答
1
投票

另一种方法是使用

generate_series()
创建时间间隔,或者仅在子查询/CTE 中截断每个
type
name
的小时数,并在外部查询中连接两条记录并将
values
avg() 聚合
按列
hour
type
name
,例如

WITH j AS (
  SELECT DISTINCT date_trunc('hour', datetime) AS hour, type,name 
  FROM data_table
)
SELECT j.*, avg(d.value)
FROM data_table d
JOIN j ON date_trunc('hour', d.datetime) = j.hour AND 
          j.type = d.type AND 
          d.name = j.name
GROUP BY j.hour, j.name, j.type
ORDER BY j.hour ASC,j.type DESC;

退货

小时 类型 名字 平均
2018-01-01 13:00:00 HLN 二氧化碳 1.7700000000000000
2018-01-01 13:00:00 HLN 2.1100000000000000
2018-01-01 13:00:00 HLN 二氧化氮 1.23500000000000000000
2018-01-01 13:00:00 AIS 二氧化碳 2.6000000000000000
2018-01-01 13:00:00 AIS 2.3000000000000000
2018-01-01 13:00:00 AIS 二氧化氮 1.80000000000000000000
2018-01-01 14:00:00 HLN 二氧化碳 0.80000000000000000000
2018-01-01 14:00:00 HLN 1.1.19000000000000000000
2018-01-01 14:00:00 HLN 二氧化氮 1.9100000000000000
2018-01-01 14:00:00 AIS 二氧化碳 2.8700000000000000
2018-01-01 14:00:00 AIS 2.8000000000000000
2018-01-01 14:00:00 AIS 二氧化氮 1.1.10000000000000000000

db<>小提琴演示

© www.soinside.com 2019 - 2024. All rights reserved.