如何程序化填充潮汐数据列表中的缺失阶梯值?
程序化填充潮汐数据中的缺失值
我有一个记录24小时内3-5次高低潮事件的列表,事件按时间戳对应到列表的索引位置:
tides = [None, None, None, (0.07, 'low'), None, None, None, None, None, None, (2.14, 'high'), None, None, None, None, None, (0.32, 'low'), None, None, None, None, None, (1.34, 'high'), None]
例如:(0.07, 'low')位于索引3,因为它发生在凌晨3点左右。
我希望用已知值之间的阶梯值替换None值。
我知道手动实现的方法:
difference = tides[10][0] - tides[3][0] # 2.07 steps = 10 - 3 # 7 increment = difference / steps # 0.2957142857 # 为每个列表项赋值 tides[4] = (tides[3][0] + (increment * 1), '') tides[5] = (tides[3][0] + (increment * 2), '') tides[6] = (tides[3][0] + (increment * 3), '') # 以此类推...
……但该如何程序化实现这一过程?
实现方案需满足以下要求:
- 考虑潮汐的升降方向,生成正负阶梯值
- 处理每日潮汐事件数量和时间的变化(即已知列表项的数量和索引可变)
- 通过“反射”相邻已知阶梯值填充首尾未知值,以完成曲线
尝试失败的方案
我的尝试围绕遍历上述列表并定义阶梯值展开:
for i in range(24): if tides[i] != None: # 已知值 else: # 缺失值 # 获取已知相邻值并计算阶梯
我卡在最后一步:在循环中如何定位当前索引的最近已知相邻值并计算阶梯。
我还尝试创建一个包含索引的单独“已知值”列表用于对比:
tidesKnown = [(3, 0.07, 'low'), (10, 2.14, 'high'), (16, 0.32, 'low'), (22, 1.34, 'high')]
解决方案
以下是满足所有要求的实现代码:
def fill_tides(tides): # 提取已知潮汐点:(索引, 高度, 类型) known = [] for idx, val in enumerate(tides): if val is not None: known.append((idx, val[0], val[1])) if not known: return tides # 无已知值时直接返回原列表 # 填充中间的缺失值 for i in range(len(known)-1): start_idx, start_height, _ = known[i] end_idx, end_height, _ = known[i+1] steps = end_idx - start_idx if steps <= 1: continue # 相邻无缺失值,跳过 increment = (end_height - start_height) / steps # 填充中间每个位置 for j in range(start_idx + 1, end_idx): current_height = start_height + increment * (j - start_idx) tides[j] = (round(current_height, 6), '') # 保留6位小数避免精度问题 # 填充头部缺失值(反射第一个已知段的步长) first_idx, first_height, _ = known[0] if first_idx > 0: # 取第一个已知段的增量作为反向增量 next_idx, next_height, _ = known[1] increment = (next_height - first_height) / (next_idx - first_idx) # 反向填充头部 for j in range(first_idx - 1, -1, -1): current_height = first_height + increment * (j - first_idx) tides[j] = (round(current_height, 6), '') # 填充尾部缺失值(反射最后一个已知段的步长) last_idx, last_height, _ = known[-1] if last_idx < len(tides)-1: # 取最后一个已知段的增量作为反向增量 prev_idx, prev_height, _ = known[-2] increment = (last_height - prev_height) / (last_idx - prev_idx) # 正向填充尾部 for j in range(last_idx + 1, len(tides)): current_height = last_height + increment * (j - last_idx) tides[j] = (round(current_height, 6), '') return tides # 测试示例 tides = [None, None, None, (0.07, 'low'), None, None, None, None, None, None, (2.14, 'high'), None, None, None, None, None, (0.32, 'low'), None, None, None, None, None, (1.34, 'high'), None] filled_tides = fill_tides(tides) for idx, val in enumerate(filled_tides): print(f"{idx}: {val}")
代码说明
- 提取已知点:遍历原列表,收集所有非None的潮汐点,包含其索引、高度和类型
- 填充中间值:遍历每对相邻已知点,计算两点间的步长增量,逐个填充中间的缺失位置,自动处理升降方向(增量为正表示涨潮,负表示退潮)
- 填充首尾值:头部使用第一个已知段的增量反向计算,尾部使用最后一个已知段的增量正向计算,实现“反射”效果,保证曲线延续性
- 适配可变场景:不管已知点的数量和索引如何变化,代码都能自动处理,无需手动调整
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

