使用 Python 读取 NetCDF 数据

2024年8月29日 | 阅读 7 分钟

在接下来的教程中,我们将通过 Python 编程语言来了解如何读取 NetCDF 数据。

但在我们开始之前,让我们简要了解一下 NetCDF 到底是什么。

理解 NetCDF

网络通用数据格式(也称为 NetCDF)通常用于存储多维地理数据。这些数据的一些示例包括降水、温度和风速。存储在 NetCDF 中的变量通常每天在(大陆)大区域上测量一次以上。每天测量一次以上,数据值会迅速累积,处理起来会变得非常繁琐。当每个值也分配到地理位置时,数据管理会变得更加复杂。NetCDF 为这些挑战提供了解决方案。本教程将引导您使用 Python 编程语言中的模块开始读取 NetCDF 文件中的数据。

安装

我们可以使用不同的 Python 模块来读取 NetCDF 文件。其中一些流行的模块包括 **netCDF4** 和 **gdal**。在本教程中,我们将主要关注 **netCDF4** 模块。

安装模块的过程很简单。我们可以使用 pip 安装程序或 anaconda Python 发行版。使用 pip 安装程序安装 netCDF4 模块的语法如下所示

语法

我们也可以使用 anaconda Python 发行版,以消除与依赖项和版本控制相关的混乱。使用 anaconda (conda) 安装模块的语法如下所示

语法

验证安装

模块安装完成后,我们可以通过创建一个空的 Python 程序文件并写入如下 import 语句来验证它:

文件:verify.py

现在,保存上述文件并在终端中使用以下命令执行它:

语法

如果上述 Python 程序文件未返回任何错误,则模块已正确安装。但是,如果引发异常,请尝试重新安装模块,并且还建议参考模块的官方文档。

加载 NetCDF 数据集

加载数据集非常简单。我们只需将 NetCDF 文件路径传递给 **netCDF4.Dataset()** 函数即可。在本教程中,我们将使用一个包含气候数据的文件的文件。

让我们看下面的代码片段来说明这一点:

示例

输出

说明

在上面的代码片段中,我们导入了所需的模块。然后,我们指定了 NetCDF 文件的路径。然后,我们使用 **Dataset()** 函数将 NetCDF 文件的数据转换为数据集。

一般文件结构

netCDF4 模块使我们能够访问与 NetCDF 文件相关的元数据和数据。NetCDF 文件包含三个基本部分:元数据、维度和变量。变量包含元数据和数据。

访问元数据

打印数据集会向我们提供有关文件中存储的变量及其维度信息。

让我们考虑以下演示相同内容的代码片段。

示例

输出

<class 'netCDF4._netCDF4.Dataset'>
root group (NETCDF4 data model, file format HDF5):
    start_year: 2021
    month: 01
    source: Daymet Software Version 4.0
    Version_software: Daymet Software Version 4.0
    Version_data: Daymet Data Version 4.0
    Conventions: CF-1.6
    citation: Please see http://daymet.ornl.gov/ for current Daymet data citation information
    references: Please see http://daymet.ornl.gov/ for current information on Daymet references
    dimensions(sizes): x(284), y(584), time(31), nv(2)
    variables(dimensions): float32 x(x), float32 y(y), float32 lat(y, x), float32 lon(y, x), float32 time(time), int16 yearday(time), float32 time_bnds(time, nv), int16 lambert_conformal_conic(), float32 prcp(time, y, x)
    groups:

说明

在上面的代码片段中,我们使用了 **print()** 函数为用户打印数据集。正如我们所观察到的,以上信息包括文件格式、数据源、数据版本、引用、维度和变量。我们感兴趣的变量是 **lat**、**lon**、time 和 **prcp**(降水量)。我们可以使用这些变量在特定时间找到特定位置的降水量。此文件仅包含 31 个时间步长(**time** 维度为 **31**)。

我们还可以将元数据作为 Python 字典访问,这更有帮助。让我们看下面的示例来演示这一点。

示例

输出

{'start_year': 2021, 'month': '01', 'source': 'Daymet Software Version 4.0', 'Version_software': 'Daymet Software Version 4.0', 'Version_data': 'Daymet Data Version 4.0', 'Conventions': 'CF-1.6', 'citation': 'Please see http://daymet.ornl.gov/ for current Daymet data citation information', 'references': 'Please see http://daymet.ornl.gov/ for current information on Daymet references'}

说明

在上面的代码片段中,我们导入了所需的模块并定义了 NetCDF 文件的路径。然后,我们使用 **Dataset()** 函数创建文件的数据集。最后,我们将数据转换为字典并为用户打印结果数据。

然后,我们可以使用其键访问任何元数据元素。让我们看下面的示例来演示这一点

示例

输出

2021

说明

在上面的代码片段中,我们指定了键并为用户打印了结果值。

维度

访问维度与文件元数据类似。每个维度都存储为一个维度类,该类包含相关信息。通过循环遍历所有可用维度,我们可以访问所有维度的元数据。让我们看下面的代码片段来演示这一点。

示例

输出

<class 'netCDF4._netCDF4.Dimension'>: name = 'x', size = 284
<class 'netCDF4._netCDF4.Dimension'>: name = 'y', size = 584
<class 'netCDF4._netCDF4.Dimension'> (unlimited): name = 'time', size = 31
<class 'netCDF4._netCDF4.Dimension'>: name = 'nv', size = 2

说明

在以下代码片段中,我们导入了所需的库并定义了 NetCDF 文件的路径。然后,我们使用 **Dataset()** 函数创建文件的数据集。最后,我们使用 **for** 循环遍历数据集中的每个维度来打印数据集的维度。

我们也可以像这样访问单个维度:**dSet.dimensions['x']**。

变量元数据

我们可以通过与访问维度类似的方式访问变量元数据。让我们看下面的代码片段来演示这一点。

示例

输出

<class 'netCDF4._netCDF4.Variable'>
float32 x(x)
    units: m
    long_name: x coordinate of projection
    standard_name: projection_x_coordinate
unlimited dimensions:
current shape = (284,)
filling on, default _FillValue of 9.969209968386869e+36 used
<class 'netCDF4._netCDF4.Variable'>
float32 y(y)
    units: m
    long_name: y coordinate of projection
    standard_name: projection_y_coordinate
unlimited dimensions:
current shape = (584,)
filling on, default _FillValue of 9.969209968386869e+36 used
<class 'netCDF4._netCDF4.Variable'>
float32 lat(y, x)
    units: degrees_north
    long_name: latitude coordinate
    standard_name: latitude
unlimited dimensions:
current shape = (584, 284)
filling on, default _FillValue of 9.969209968386869e+36 used
<class 'netCDF4._netCDF4.Variable'>
float32 lon(y, x)
    units: degrees_east
    long_name: longitude coordinate
    standard_name: longitude
unlimited dimensions:
current shape = (584, 284)
filling on, default _FillValue of 9.969209968386869e+36 used
<class 'netCDF4._netCDF4.Variable'>
float32 time(time)
    standard_name: time
    calendar: standard
    units: days since 1950-01-01 00:00:00
    bounds: time_bnds
    long_name: 24-hour day based on local time
unlimited dimensions: time
current shape = (31,)
filling on, default _FillValue of 9.969209968386869e+36 used
<class 'netCDF4._netCDF4.Variable'>
int16 yearday(time)
    long_name: day of year (DOY) starting with day 1 on January 1st
unlimited dimensions: time
current shape = (31,)
filling on, default _FillValue of -32767 used
<class 'netCDF4._netCDF4.Variable'>
float32 time_bnds(time, nv)
unlimited dimensions: time
current shape = (31, 2)
filling on, default _FillValue of 9.969209968386869e+36 used
<class 'netCDF4._netCDF4.Variable'>
int16 lambert_conformal_conic()
    grid_mapping_name: lambert_conformal_conic
    longitude_of_central_meridian: -100.0
    latitude_of_projection_origin: 42.5
    false_easting: 0.0
    false_northing: 0.0
    standard_parallel: [25. 60.]
    semi_major_axis: 6378137.0
    inverse_flattening: 298.257223563
unlimited dimensions:
current shape = ()
filling on, default _FillValue of -32767 used
<class 'netCDF4._netCDF4.Variable'>
float32 prcp(time, y, x)
    _FillValue: -9999.0
    long_name: daily total precipitation
    units: mm/day
    missing_value: -9999.0
    coordinates: lat lon
    grid_mapping: lambert_conformal_conic
    cell_methods: area: mean time: sum
unlimited dimensions: time
current shape = (31, 584, 284)
filling on

说明

在上面的代码片段中,我们导入了所需的模块并定义了 NetCDF 文件的路径。然后,我们使用 **Dataset()** 函数创建文件的数据集。最后,我们使用 **for** 循环遍历数据集的变量并为用户打印它们。

我们也可以访问单个变量。让我们看下面的示例来演示这一点

示例

输出

<class 'netCDF4._netCDF4.Variable'>
float32 prcp(time, y, x)
    _FillValue: -9999.0
    long_name: daily total precipitation
    units: mm/day
    missing_value: -9999.0
    coordinates: lat lon
    grid_mapping: lambert_conformal_conic
    cell_methods: area: mean time: sum
unlimited dimensions: time
current shape = (31, 584, 284)
filling on

说明

在上面的代码片段中,我们通过将其指定为 **dSet** 变量的参数来打印 **prcp** 变量的值。

结论

NetCDF 文件通常用于地理时间序列数据。最初,由于 CSV 和栅格文件(最常用)的数据量大且格式不同,处理它们可能会非常令人生畏。NetCDF 由于其内置的文档和元数据,是记录地理数据的绝佳方式。这使得最终用户能够轻松准确地理解数据代表的内容,歧义很少。NetCDF 数据被访问为 NumPy 数组,这为分析和整合到现有实用程序和工作流提供了许多可能性。