【sql 孤岛问题 】填充空值为最近的不为空的数据

文章介绍了如何利用SQL的gaps-and-islands方法,特别是Lead函数,来处理数据表中缺失值的问题。通过创建临时表确定数据组的边界,并对null值进行填充,确保每个组内的数据完整。这种方法适用于处理时间序列数据中的空缺值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0. 题目

根据value数据原表补充缺失数据,如果当月value数据没有则取上月填充,上月也没有则一直向上查找首个不为空的值

输入表

monthvalue
1200
2null
3null
4600
5null

预期结果集

monthvalue
1200
2200
3200
4600
5600

1、gaps-and-islands

这类问题被称为gaps-and-islands (间隙与孤岛),

思路:将行拆分为“组”。其中每个组中只有第一行(上边界)为NOT NUL 即,组的上边界 是第一行not null的值,组的下边界是下一组第一行not null的值的序号减一。这样再组内赋值即可。

关键:使用开窗函数 lead,lead :形象的理解就是把数据从下向上顶👆,下端出现空格

lead 语法:
lead(col,n,default) 用于统计窗口内往下第n行值
- 参数1为列名,即需要查找的字段
- 参数2为往下第n行(可选,默认为1),即往后查找的num行的数据
- 参数3为默认值(当往下第n行为null时候,取默认值,如不指定,则为null

最终sql

with t as (
select month as roof_idx,
lead(month,1, (select max(month) from table) +1) ---若没有找到边界,取月份最大值+1
over (order by month ) -1 as floor_idx,  ---注意这里有个减一,因为lead取的是下个组第一行not null的值,所以得减
value 
where value is  not null),  --t表先找到每组中not null的值,并通过lead确定每组的下界
result as (
select raw.month ,t.value  --给null的行赋值
from table raw,t   --t是with临时表的名称,这里是笛卡尔积;实际生产建议按需join
where raw.value is null and (raw.month between t.from_month and t.to_month) -- 按组找出null值的行,赋值
union all  --上面给null行赋值操作排除了not null行,下面union回来
select month ,value from table where value is not null) 
select * from result order by month 
  1. t 这个临时表的工作就是找出每个组的roof和floor 的index,这里month是按顺序来的所以可以直接用,一般我们可能还需要先row number 构造一个序列;
  2. t 构造好上下组边界后,result临时表开始构建返回结果,我们 where clause 选择 value 为null的行 +

也可以用cte递归写法,待补充

### 如何使用 Pandas 的 Forward Fill 和 Backward Fill 方法填充空值 在 Pandas 中,`fillna()` 函数提供了一种灵活的方式来处理数据框或系列中的缺失值。其中 `method='ffill'` 表示前向填充(Forward Fill),即用前面最近的非空值填充当前空值;而 `method='bfill'` 表示后向填充(Backward Fill),即将后面最近的非空值用来填充当前空值[^1]。 以下是具体的实现方式: #### 前向填充 (FFill) 当指定参数 `method='ffill'` 时,Pandas 将会从前到后遍历数据,并用上一个有效的非空值替换掉遇到的任何 NaN 值。如果起始位置本身就是 NaN,则不会被填充,除非指定了额外的限制条件如 `limit` 参数[^2]。 ```python import pandas as pd # 创建带有缺失值的数据帧 data = {'A': [1, None, None, 4], 'B': [None, 2, None, 5]} df = pd.DataFrame(data) print("原始数据:") print(df) # 应用 ffill 进行前向填充 filled_ffill = df.fillna(method='ffill') print("\n应用 FFill 后的结果:") print(filled_ffill) ``` #### 后向填充 (BFill) 另一方面,通过设置 `method='bfill'` 或者其别名 `'backfill'`,可以实现相反方向的操作—从后向前扫描并利用后续的第一个可用数值填补白处。需要注意的是,在这种情况下,结尾部分如果有连续多个 NA 存在于末端则无法得到补充[^3]。 ```python # 应用 bfill 进行后向填充 filled_bfill = df.fillna(method='bfill') print("\n应用 BFill 后的结果:") print(filled_bfill) ``` 这两种技术对于时间序列分析特别有用,因为它们允许基于已知的时间点上的观测结果来进行预测或者平滑化处理过程[^4]。 ### 结论 无论是采用 forward fill 还是 backward fill 方式都可以有效地解决某些特定场景下的缺失数据问题,但是使用者应当依据实际需求以及数据特性谨慎选择最合适的策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值