找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2445

积分

0

好友

319

主题
发表于 6 小时前 | 查看: 0| 回复: 0

在气象、遥感及地球科学领域,GeoTIFF(通常简称为TIF)与NetCDF是两种极为常见的栅格数据格式。

TIF格式因其“即插即用”的特性,常被各类GIS软件偏爱;而NetCDF格式则以其自描述性、支持多维数据以及丰富的元数据能力,成为科研数据交换的“通用语”。

气象或高维地球科学数据通常以NetCDF、GRIB等格式存储。本文将介绍如何使用 Python 将CHIRPS数据集的TIF格式降水数据,高效地批量转换为更便于分析和管理的NetCDF格式。

🔍 TIF vs NetCDF:坐标差异解析

在进行格式转换前,理解两者在数据组织上的核心差异至关重要,尤其是在坐标定义上。

GeoTIFF与NetCDF坐标差异对比表

关键点在于参考系的差异:GeoTIFF通常将坐标关联到像元的左上角,而遵循CF(Climate and Forecast)约定的NetCDF则将坐标定义为网格中心

因此,TIF的左上角坐标并不直接等于NetCDF中最左或最上的经纬度值。在转换时,我们需要根据仿射变换参数,将左上角点坐标向左和向上移动半个像元的大小,才能得到NetCDF所需的“网格中心”经纬度数组。

实际案例:CHIRPS降水数据处理

数据下载

本例使用CHIRPS V3.0日尺度降水数据。数据下载地址为:https://data.chc.ucsb.edu/products/CHIRP-v3.0/daily/global/tifs/

你可以从中获取全球范围的逐日TIF格式降水文件。

处理目的

原始数据以每日一个独立TIF文件的形式提供,在处理时间序列或进行区域分析时并不方便。我们的目标是:将多个日期的TIF文件批量转换为NetCDF格式,并为其添加正确的时间维度,以便后续进行合并或分析。

查看单个TIF文件信息

首先,我们使用rasterio库来读取单个文件,了解其空间参考、范围、分辨率等关键信息。

import rasterio

tif_path = "./obs/chirp-v3.0.2025.01.01.tif"

with rasterio.open(tif_path) as ds:
    print("📌 文件基本信息")
    print("Driver        :", ds.driver)
    print("Width, Height :", ds.width, ds.height)
    print("Bands         :", ds.count)
    print("Data type     :", ds.dtypes)

    print("\n📌 投影信息(CRS)")
    print(ds.crs)

    print("\n📌 仿射变换(Affine Transform)")
    print(ds.transform)

    print("\n📌 分辨率")
    print("x_res =", ds.res[0])
    print("y_res =", ds.res[1])

    print("\n📌 空间范围(Bounding Box)")
    print(ds.bounds)

    print(ds.profile)

运行上述代码,将输出类似以下信息:

TIF文件元信息展示

从输出可知,该CHIRPS数据分辨率为0.05°,覆盖全球范围(-180°E 到 180°E,-60°S 到 60°N),采用WGS84地理坐标系。

CHIRPS全球降水分布示意图

单个文件转换示例

直接使用rioxarray(基于xarray和rasterio)读取TIF再保存为NetCDF是最便捷的方法,因为它会自动处理前文提到的坐标边界转换问题。

import pandas as pd
import xarray as xr
import numpy as np

# 假设你的文件名是 "chirp-v3.0.2025.01.01.tif"
tif_path = "./obs/chirp-v3.0.2025.01.01.tif"

# 从文件名中提取日期
import re
m = re.search(r"(\d{4}\.\d{2}\.\d{2})", tif_path)
date_str = m.group(1)  # "2025.01.01"
time = pd.to_datetime(date_str, format="%Y.%m.%d")  # 转成 pandas.Timestamp

# 使用 rioxarray 打开 tif 文件并处理
import rioxarray as rxr
da = rxr.open_rasterio(tif_path).squeeze('band')
da = da.rename({"x": "longitude", "y": "latitude"})
da = da.drop_vars("band")
da = da.drop_vars("spatial_ref")
da.name = "prec"
da.attrs = {"units": "mm/day"}

# 增加 time 维度
da = da.expand_dims(time=[time])

# 保存为 NetCDF 文件,并启用压缩以减小文件体积
da.to_netcdf(
    "./obs/20250101.nc",
        encoding={
        "prec": {
            "zlib": True,       # 开启压缩
            "complevel": 4,     # 压缩等级 1~9(平衡速度与压缩率)
            "dtype": "float32", # 可选,指定数据类型以控制存储大小
            "_FillValue": np.nan
        }
    }
)

这段代码完成了单个文件的转换,核心步骤包括:解析日期、读取数据、重命名坐标轴、添加时间维度,最后以压缩格式输出NetCDF文件。

动态心形表情

思路延伸与批量处理

掌握了单个文件的转换后,批量处理就变得非常简单。你只需要将上述代码包裹在一个循环中,遍历指定目录下的所有TIF文件即可。关键点在于为每个文件正确解析出对应的日期,并作为time维度坐标。

这种从原始栅格数据到标准化NetCDF的转换流程,是 智能 & 数据 & 云 时代下,进行气象、海洋或环境科学数据分析的常见且重要的数据预处理步骤。希望本教程能帮助你更高效地管理地球科学数据。

本文的示例代码与思路,可以轻松扩展到处理其他来源的GeoTIFF数据。如果你在实践过程中遇到问题,或想探讨更多关于数据处理的技术细节,欢迎在云栈社区与大家交流。




上一篇:2026年CISO工作重点:网络安全、AI防护与韧性建设策略
下一篇:HBM芯片:从AI算力配角到地缘政治咽喉的存储架构演变
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-25 19:43 , Processed in 0.333672 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表