import numpy as np
from netCDF4 import Dataset
from datetime import datetime
# 獲取當前時間
current_time = datetime.now()
# 格式化為只顯示時間
formatted_time = current_time.strftime("%m-%d-%H-%M-%S")
def extend_list(lst, extension_count):
"""
擴充套件列表兩端,增加指定數量的元素
:param lst: 原始列表
:param extension_count: 擴充套件的元素數量
:return: 擴充套件後的列表
"""
original_type = type(lst[0])
delta = lst[1] - lst[0]
# 向左擴充套件
left_extension = [original_type(lst[0] - delta * i) for i in range(1, extension_count + 1)]
left_extension.reverse()
# 向右擴充套件
right_extension = [original_type(lst[-1] + delta * i) for i in range(1, extension_count + 1)]
# 合併擴充套件後的結果
extended_lst = np.concatenate([left_extension, lst, right_extension])
return extended_lst
def copy_variable_attributes(src_var, dst_var):
"""
複製變數的所有屬性並設定分塊大小
:param src_var: 源變數
:param dst_var: 目標變數
"""
# 複製變數的屬性
for attr_name in src_var.ncattrs():
if attr_name != '_FillValue': # 跳過 _FillValue
dst_var.setncattr(attr_name, src_var.getncattr(attr_name))
def copy_polar_stereographic(src_nc, dst_nc):
"""
複製 polar_stereographic 變數及其屬性
:param src_nc: 源 NetCDF 檔案
:param dst_nc: 目標 NetCDF 檔案
"""
polar_stereographic_src = src_nc.variables['polar_stereographic']
polar_stereographic_target = dst_nc.createVariable(
'polar_stereographic', polar_stereographic_src.datatype, polar_stereographic_src.dimensions
)
# 複製所有屬性
for attr in polar_stereographic_src.ncattrs():
polar_stereographic_target.setncattr(attr, polar_stereographic_src.getncattr(attr))
# 複製資料(如果是一個簡單的標量資料,可以直接複製)
polar_stereographic_target[:] = polar_stereographic_src[:]
x_max = int(dst_nc.variables['x'][:][-1] + 3125)
y_yax = int(dst_nc.variables['y'][:][-1] + 3125)
# 設定 GeoTransform(示例值,可以根據需要調整)
polar_stereographic_target.GeoTransform = f'-{x_max} 6250 0 {y_yax} 0 -6250'
def create_and_save_nc(input_file_path, output_file_path, extension_count=100):
"""
擴充套件原始 NetCDF 資料並儲存到新檔案
:param input_file_path: 輸入的 NetCDF 檔案路徑
:param output_file_path: 輸出的 NetCDF 檔案路徑
:param extension_count: 要擴充套件的座標數(預設擴充套件 100)
"""
# 開啟原始 NetCDF 檔案並讀取資料
with Dataset(input_file_path, mode='r') as nc_file:
# 讀取現有的 x、y 和 z
x = nc_file.variables['x'][:]
y = nc_file.variables['y'][:]
z = nc_file.variables['z'][:]
# 獲取現有的形狀
x_size, y_size = x.shape[0], y.shape[0]
# 計算新座標,增加指定數量的座標點
new_x = extend_list(x, extension_count) # 在 x 軸增加指定數量的點
new_y = extend_list(y, extension_count) # 在 y 軸增加指定數量的點
# 建立新的 z 陣列,形狀為新的 x 和 y 的交叉形狀
new_z = np.full((new_y.shape[0], new_x.shape[0]), 50, dtype=np.float32) # 新陣列賦值為 50
# 將現有的 z 陣列放入新的 z 陣列中,保持原有資料
new_z[extension_count:y_size + extension_count, extension_count:x_size + extension_count] = z # 現有資料放入新陣列的中間
# 建立新的 NetCDF 檔案來儲存資料
with Dataset(output_file_path, mode='w', format='NETCDF4') as new_nc_file:
# 建立新的維度
new_nc_file.createDimension('x', new_x.shape[0])
new_nc_file.createDimension('y', new_y.shape[0])
# 建立新的變數並儲存資料
x_var = new_nc_file.createVariable('x', 'f8', ('x',), zlib=False)
y_var = new_nc_file.createVariable('y', 'f8', ('y',), zlib=False)
# 設定分塊大小 (例如: 'x' 維度塊大小為 1,'y' 維度塊大小為 1264)
chunk_sizes = (1, x_var.size) # 根據你的需求設定塊大小
z_var = new_nc_file.createVariable('z', np.float32, ('y', 'x'),
fill_value=nc_file.variables['z']._FillValue, chunksizes=chunk_sizes,
zlib=True)
# 將資料寫入變數
x_var[:] = new_x
y_var[:] = new_y
z_var[:] = new_z
# 複製原始變數的屬性並設定分塊
copy_variable_attributes(nc_file.variables['x'], x_var)
copy_variable_attributes(nc_file.variables['y'], y_var)
copy_variable_attributes(nc_file.variables['z'], z_var)
# 複製空間參考資訊
copy_polar_stereographic(nc_file, new_nc_file)
print(f"資料已儲存到 {output_file_path}")
if __name__ == '__main__':
input_file_path = r'F:\Polar\data\sea_ice_concentration_241130.nc'
output_file_path = fr'F:\Polar\data\{formatted_time}-sea_ice_concentration_241130.nc'
create_and_save_nc(input_file_path, output_file_path, extension_count=100)