如何读取含两类行结构、无固定宽度且存在大量缺失值的空格分隔数据
非标准JMA台风历史数据的结构化清洗方案
核心处理难点
- 数据名义上遵循官方公开的固定宽度格式规范,实际存在列宽偏移问题:比如指定4位宽度的列会偶尔收缩为3位,和相邻字段的分隔间距变小
- 缺失值没有统一标记规则,仅靠连续空格占位,不像NOAA飓风数据那样用固定的-999或NaN标注缺失,读取难度高
- 文件内同时存在三类不同结构的行:带刻度的格式说明行、台风元信息头行、实际路径观测数据行,无法直接套用常规读取函数
- 通用读取方法(比如
pd.read_fwf、连续空格分隔读取)的容错率极低,遇到列偏移的畸形样本就会出现整列错位,完全没法直接输出规整的DataFrame
落地清洗步骤
第一步:行级预筛选
逐行读取原始文本,先过滤掉两类无信息价值的行:
- 带刻度符号的格式说明行(包含
::::+::::|这类标识的行) - 仅由数字组成的位置刻度行(就是开头标注5、10、15…80的索引行)
剩下的有效行按照字段长度做分类: - 短字段行:台风元信息头行,用来记录当前台风的ID、名称等基础属性
- 长字段行:逐次的路径观测数据行
第二步:放弃硬固定宽度切分,改用灵活的分隔匹配
不要直接用pd.read_fwf按官方给的列宽硬切,这类方法对列偏移的容错率为0,只要有一个样本的列宽不对,整表的列就会全部错位。
改用正则匹配切分逻辑:
- 对每一行有效文本,用
\s{2,}(匹配2个及以上连续空格的间隔)作为分隔符,把行拆成独立的字段列表 - 对拆分后字段数少于标准值的行,识别为“列宽收缩导致的字段间隔变小”的场景,按照字段的语义规则手动拆分粘连内容:比如经纬度、气压、风速这类数值型字段,可以通过正则匹配“带负号/不带负号的连续数字”的模式,把粘连在一起的相邻字段拆分开
第三步:跨行关联上下文信息
把识别出的台风元信息头行作为当前全局上下文,后续所有跟着的观测数据行,自动补上当前台风的ID、名称这类关联属性,直到遇到下一个台风的元信息头行再更新上下文参数。
第四步:标准化数据格式
- 拆分后为空字符串的字段,统一替换为pandas的
NaN标记缺失值 - 对所有数值类型的字段做强制类型转换,转换失败的内容自动标记为缺失值
- 按官方定义的字段顺序,把所有行对齐拼成结构化的表格
第五步:取值范围校验校正错位
对拼接好的表格逐列做取值范围校验,通过业务常识判断错位:
- 中心气压的合理值范围为500-1100 hPa
- 最大风速的合理值范围为0-200 m/s
- 经纬度的合理值范围为0-360°
如果某行的字段值超出对应列的合理范围,就判定为切分位置错位,重新调整切分逻辑直到取值符合业务范围。
内容的提问来源于stack exchange,提问作者rocksNwaves
相关产品推荐
相关产品推荐

