'NC'文件的读取与使用

.NC文件的读取与使用

前言

NetCDF(network Common Data Form)网络通用数据格式是一种面向数组型并适于网络共享的数据的描述和编码标准。目前,NetCDF广泛应用于大气科学、水文、海洋学、环境模拟、地球物理等诸多领域。用户可以借助多种方式方便地管理和操作 NetCDF 数据集。

在数学建模的过程中,我们难免会接触到一些气象文件,而 .nc文件便是其中最为常见的一种,我们如果能利用好这些文件,对我们进行数学建模有着极大的好处和便利。

Matlab

Matlab是一款强大的数学建模软件,其中也加入了对于 .nc文件的支持

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
% 定义年份范围
start_year = 2014;
end_year = 2020;

% 遍历每一年
for year = start_year:end_year
% 构建文件名
nc_filename = sprintf('.nc\\MARv3.11.3-ssp245-%d_clip.nc', year);

% 获取文件信息
info = ncinfo(nc_filename);

% 创建结构体来存储RU变量的数据
data = struct();

% 读取RU变量的数据
varname = 'RU';
if ismember(varname, {info.Variables.Name})
data.(varname) = ncread(nc_filename, varname);
else
error('变量 %s 不存在于文件 %s 中。', varname, nc_filename);
end

% 构建CSV文件名
csv_filename = sprintf('RU_%d_data.csv', year);

% 将RU变量的数据写入CSV文件
writematrix(data.RU, csv_filename);

% 显示处理信息
fprintf('Data for year %d has been written to %s\n', year, csv_filename);
end

在这里我使用Matlab读取了从2014~2020全年的数据,并且只读取变量 RU的数值,将其写入到 CSV文件中,方便下一步处理

netCDF4

目前最新的Python 3.12尚不支持netCDF4,因此请使用Python 3.11版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import netCDF4
import matplotlib.pyplot as plt
# 打开 .nc 文件

for years in range(1993, 2014):
dataset = netCDF4.Dataset(r'.nc\MARv3.11.3-historical-{}_clip.nc'.format(years), 'r')

smb = dataset.variables['SMB'][:]
x = dataset.variables['x'][:]
y = dataset.variables['y'][:]

# 绘制 'SMB' 的空间分布图
plt.figure(figsize=(10, 6))
plt.contourf(x, y, smb[0, :, :], cmap='viridis')
plt.colorbar(label='SMB')
plt.title(r'Spatial Distribution Map of SMB {}'.format(years))
plt.xlabel('X')
plt.ylabel('Y')
plt.savefig(r'SMB\Spatial Distribution Map of SMB {}'.format(years), bbox_inches='tight')
# plt.show()

# 关闭文件
dataset.close()

xarray

此方法为ChatGPT生成的方法,本人在自己系统环境中没有使用成功过,因此只供参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import xarray as xr
import matplotlib.pyplot as plt

# 打开 .nc 文件,并忽略冲突的坐标解码
file_path = '/mnt/data/MARv3.11.3-historical-1993_clip.nc'
ds = xr.open_dataset(file_path, decode_cf=False)

# 查看数据集的信息
ds_info = ds

# 查看变量 'SMB' 的数据
smb = ds['SMB']
smb_info = smb

# 获取特定时间点的数据并绘制空间图
time_index = 0 # 选择第一个时间点
smb_at_time = smb.isel(time=time_index)

# 绘制 'SMB' 的空间分布图
plt.figure(figsize=(10, 6))
plt.contourf(ds['x'].values[0], ds['y'].values[:, 0], smb_at_time, cmap='viridis')
plt.colorbar(label='SMB')
plt.title(f'SMB at time index {time_index}')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()

# 获取特定位置的时间序列数据并绘制时间序列图
x_index = 10 # 选择一个 x 位置
y_index = 5 # 选择一个 y 位置
smb_time_series = smb[:, y_index, x_index]

# 绘制 'SMB' 的时间序列图
plt.figure(figsize=(10, 6))
plt.plot(ds['time'].values, smb_time_series)
plt.title(f'SMB Time Series at location (x={x_index}, y={y_index})')
plt.xlabel('Time')
plt.ylabel('SMB')
plt.show()

ds_info, smb_info