無人問津的森林系技能樹

喝咖啡,吃甜食,務必把握時間讓你胃食道逆流一下

0%

[python/linux]Interpolation of .nc file

目標

  • 將.nc檔案內插為2km解析度
  • 在Linux系統上執行(可能為無系統管理員權限的狀況)
  • 使用Python

方法

自動生成 grid_2km.txt

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
42
43
44
import xarray as xr


def generate_grid_file_from_netcdf(input_file, output_grid_file, resolution):
"""
從 NetCDF 檔案自動生成目標網格文件。

:param input_file: NetCDF 檔案路徑
:param output_grid_file: 目標網格文件名
:param resolution: 目標網格解析度(度)
"""
# 載入 NetCDF 檔案
dataset = xr.open_dataset(input_file) # .nc檔案
lat = dataset["XLAT"] #緯度
lon = dataset["XLONG"] #經度

# 獲取經緯度範圍
lat_min, lat_max = lat.min().item(), lat.max().item()
lon_min, lon_max = lon.min().item(), lon.max().item()
print(f"Latitude range: {lat_min} to {lat_max}")
print(f"Longitude range: {lon_min} to {lon_max}")

# 計算網格點數
x_size = int((lon_max - lon_min) / resolution) + 1
y_size = int((lat_max - lat_min) / resolution) + 1

# 生成網格文件
with open(output_grid_file, "w") as f:
f.write("gridtype = latlon\n")
f.write(f"xsize = {x_size}\n")
f.write(f"ysize = {y_size}\n")
f.write(f"xfirst = {lon_min}\n")
f.write(f"xinc = {resolution}\n")
f.write(f"yfirst = {lat_min}\n")
f.write(f"yinc = {resolution}\n")
print(f"Grid file '{output_grid_file}' has been created.")


input_nc_file = "input.nc" # 原始 NetCDF 檔案
grid_file = "grid_2km.txt" # 目標網格文件
resolution = 0.018 # 2km ≈ 0.018度

generate_grid_file_from_netcdf(input_nc_file, grid_file, resolution)

調整維度順序

  • Time 移到最前
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import xarray as xr

    ds = xr.open_dataset("input.nc")

    output_file = "fixed.nc"
    reordered_vars = {}
    for var_name in ds.data_vars:
    var = ds[var_name]
    if 'Time' in var.dims:
    # 將 'Time' 移到最前
    reordered_vars[var_name] = var.transpose("Time", *[dim for dim in var.dims if dim != "Time"])
    else:
    # 若無 'Time' 維度,保持不變
    reordered_vars[var_name] = var

    # 建立新的資料集
    reordered_ds = xr.Dataset(reordered_vars, coords=ds.coords)

    # 存為新的 NetCDF 檔案
    reordered_ds.to_netcdf(output_file)

Python with CDO(Climate Data Operators)

1
2
3
4
5
6
7
8
9
10
from cdo import Cdo

cdo = Cdo()

input_file = "fixed.nc"
output_file = "output_2km.nc"

grid_file = "grid_2km.txt"
print(f'start cdo - {input_file}')
cdo.remapbil(grid_file, input=input_file, output=output_file)

Tips on Linux server

  • 創建虛擬環境
  • 安裝CDO
    1
    2
    3
    conda install cdo
    conda install python-cdo
    conda install netcdf4 #相依關係,調整維度用

後續

  • 建立批次處理流程