SQL 用最后观察到的值填充 nan

Posted

技术标签:

【中文标题】SQL 用最后观察到的值填充 nan【英文标题】:SQL fill nan with last observed value 【发布时间】:2021-04-25 10:56:48 【问题描述】:

编写 SQL 查询,用最后一个已知值填充 Value 列 NaN。 SQLite

client_id date value
1 14.04.2020 10000
1 15.04.2020 5000
1 16.04.2020 NaN
1 17.04.2020 NaN
1 18.04.2020 NaN
2 14.04.2020 250000
2 15.04.2020 250000
2 16.04.2020 230000
2 17.04.2020 230000
2 18.04.2020 225000
3 14.04.2020 50000
3 15.04.2020 NaN
3 16.04.2020 NaN

我正在考虑窗口函数,但不知道如何在这里应用它。

【问题讨论】:

用您正在使用的数据库标记您的问题。 【参考方案1】:

我从 'NaN' 的使用猜测你正在使用 Postgres。

不幸的是,Postgres 不支持窗口函数上的IGNORES NULL 选项。一种方法是为数字分配一个组,然后为该组估算值:

select t.*,
       max(nullif(value, 'NaN')) over (partition by grp) as imputed_value
from (select t.*,
             count(value) filter (where value <> 'NaN') over (partition by client_id order by date) as grp
      from t
     ) t

也可以在不使用数组的子查询的情况下执行此操作,但表达式相当复杂:

select t.*,
       (array_remove(array_agg(value)over (partition by client_id order by date), 'NaN'))[cardinality(array_remove(array_agg(value)over (partition by client_id order by date), 'NaN'))]
from t;

或者使用横向连接:

select t.*, t2.value as imputed_value
from t cross join lateral
     (select t2.value
      from t t2
      where t2.client_id = t.client_id and
            t2.date <= t.date and
            t2.value <> 'NaN'
      order by t2.date desc
      limit 1
     ) t2;

Here 是一个 dbfiddle。

【讨论】:

不错。但是当您添加多个 client_id 时,第一种方法会出错。另外,我使用 SQLite 来完成这项任务,而不是 Postgres,我忘了说。

以上是关于SQL 用最后观察到的值填充 nan的主要内容,如果未能解决你的问题,请参考以下文章

填写一列日期值,直到达到另一个日期值,然后继续填充新达到的值

熊猫:使用最后可用的填充缺失值

Pandas - 使用多个值填充 NaN

06 pandas DataFrame - 数据过滤、NaN处理、统计方法

用 pandas 数据框中另一列的值填充多列中的 Na

matlab 如何用插值给NAN赋值