Python实战:5分钟高效处理NCDC气象数据(ISD-Lite转Excel全流程解析)
气象数据分析工作中,原始数据格式转换往往是令人头疼的第一道门槛。美国国家气候数据中心(NCDC)提供的ISD-Lite格式数据虽然体积小巧,但直接阅读和分析却不太友好。本文将带你用Python快速实现批量转换,将晦涩的ISD-Lite文件转化为直观的Excel表格,整个过程只需不到5分钟即可完成配置。
1. 环境准备与数据理解
在开始转换前,我们需要先了解ISD-Lite数据的结构特点。这种格式以固定宽度空格分隔的文本文件存储,每行包含12个气象要素:
"""
列序号 要素名称 单位 换算系数 缺失值标记
-------------------------------------------------
1 年 - 1 -
2 月 - 1 -
3 日 - 1 -
4 小时 - 1 -
5 温度 ℃ 10 -9999
6 露点温度 ℃ 10 -9999
7 气压 hPa 10 -9999
8 风向 度 1 -9999
9 风速 m/s 10 -9999
10 云量 八分制 1 -9999
11 1小时降雨量 mm 10 -9999
12 6小时降雨量 mm 10 -9999
"""
注意:原始数据中的温度、气压等要素需要除以10才能得到实际物理值,这是ISD-Lite格式的特殊设计。
所需工具准备清单:
- Python 3.6+ 环境
- pandas库(数据处理核心)
- openpyxl或xlwt库(Excel输出支持)
- 原始ISD-Lite数据文件夹(通常按年份组织)
安装依赖只需一行命令:
pip install pandas openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple
2. 核心转换函数开发
我们构建一个智能转换函数,自动处理数据读取、格式解析、单位换算和缺失值处理全流程:
import os
import pandas as pd
import numpy as np
def isd_to_excel(input_path, output_folder='converted_excel'):
"""
批量转换ISD-Lite文件为Excel格式
参数:
input_path: str - ISD-Lite文件或文件夹路径
output_folder: str - 输出目录(默认当前目录下converted_excel)
返回:
error_files: list - 转换失败的文件列表
"""
# 创建输出目录
os.makedirs(output_folder, exist_ok=True)
# 处理单个文件或批量文件
files_to_process = []
if os.path.isfile(input_path):
files_to_process = [input_path]
else:
files_to_process = [os.path.join(input_path, f)
for f in os.listdir(input_path)
if not f.startswith('.')]
error_files = []
column_names = ['年','月','日','小时','温度(℃)','露点温度(℃)',
'气压(hPa)','风向(度)','风速(m/s)','云量(八分制)',
'1小时降雨量(mm)','6小时降雨量(mm)']
for file in files_to_process:
try:
# 读取原始数据
raw_data = pd.read_csv(file, header=None, delim_whitespace=True)
# 数据清洗与转换
df = raw_data.replace(-9999, np.nan)
scaled_columns = [4,5,6,8,10,11] # 需要换算的列索引
df[scaled_columns] = df[scaled_columns] / 10
# 添加时间索引
df.columns = column_names
df['时间'] = pd.to_datetime(df[['年','月','日','小时']])
df.set_index('时间', inplace=True)
df.drop(['年','月','日','小时'], axis=1, inplace=True)
# 保存为Excel
output_name = os.path.splitext(os.path.basename(file))[0] + '.xlsx'
df.to_excel(os.path.join(output_folder, output_name))
except Exception as e:
print(f"处理失败: {file} - 错误: {str(e)}")
error_files.append(file)
return error_files
提示:函数内置了错误捕获机制,转换失败的文件会单独记录,避免因个别文件问题中断整个批处理流程。
3. 实战应用场景解析
3.1 单文件转换模式
对于只需要处理单个ISD-Lite文件的情况:
# 转换单个文件示例
input_file = "data/china_isd_lite_2020/545110-99999-2020"
isd_to_excel(input_file, output_folder="2020_stations")
3.2 批量处理年度数据
当需要处理整个年份文件夹时:
# 批量转换2020年所有站点数据
input_folder = "data/china_isd_lite_2020"
errors = isd_to_excel(input_folder)
if errors:
print(f"有{len(errors)}个文件转换失败,请检查:")
for err in errors:
print(f" - {err}")
else:
print("所有文件转换成功!")
3.3 多年度数据整合
对于跨年度的气象分析,可以先分别转换再合并:
import glob
# 转换多个年份数据
for year in range(2018, 2021):
isd_to_excel(f"data/china_isd_lite_{year}", f"converted_{year}")
# 合并所有年份数据
all_data = pd.concat([
pd.read_excel(f)
for f in glob.glob("converted_*/**.xlsx")
])
all_data.to_excel("combined_weather_2018-2020.xlsx")
4. 高级技巧与性能优化
4.1 内存优化策略
处理超大规模数据时,可采用分块处理模式:
def chunked_conversion(input_path, chunk_size=10000):
""" 分块处理大文件 """
reader = pd.read_csv(input_path, header=None,
delim_whitespace=True,
chunksize=chunk_size)
for i, chunk in enumerate(reader):
processed_chunk = process_data(chunk) # 应用相同的处理逻辑
if i == 0:
processed_chunk.to_excel("output.xlsx")
else:
with pd.ExcelWriter("output.xlsx", mode='a') as writer:
processed_chunk.to_excel(writer, header=False)
4.2 并行处理加速
利用多核CPU加速批量转换:
from concurrent.futures import ThreadPoolExecutor
def parallel_convert(files, workers=4):
""" 多线程并行转换 """
with ThreadPoolExecutor(max_workers=workers) as executor:
results = list(executor.map(isd_to_excel, files))
return results
4.3 数据质量检查
转换后自动生成数据质量报告:
def quality_report(df):
""" 生成数据质量报告 """
report = pd.DataFrame({
'缺失值比例': df.isna().mean(),
'平均值': df.mean(),
'标准差': df.std(),
'最小值': df.min(),
'最大值': df.max()
})
return report.round(2)
5. 常见问题解决方案
问题1:文件编码错误
# 指定编码格式读取
raw_data = pd.read_csv(file, header=None,
delim_whitespace=True,
encoding='latin1')
问题2:输出Excel过大
# 使用压缩格式
with pd.ExcelWriter("output.xlsx", engine='openpyxl') as writer:
df.to_excel(writer, index=False)
writer.book.save("compressed.xlsx",
save_compressed=True)
问题3:时间格式异常
# 自定义时间解析
def parse_time(row):
try:
return pd.datetime(row[0], row[1], row[2], row[3])
except:
return pd.NaT
df['时间'] = df.apply(parse_time, axis=1)
实际项目中,建议将转换后的Excel文件与原始ISD-Lite文件分开存放,并建立文件索引数据库方便后续检索。对于长期运行的气象分析项目,可以考虑将转换流程封装为自动化脚本,配合定时任务实现数据自动更新。
2253



被折叠的 条评论
为什么被折叠?



