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)
标签:extension,nc,修改,复制,netcdf,stereographic,file,var,new
From: https://www.cnblogs.com/echohye/p/18577608