使用Xarray创建NetCDF文件时变量维度不匹配问题求助
问题:Pandas转Xarray后生成NetCDF时,BA变量无法被识别为二维变量
我将Pandas DataFrame转换为Xarray Dataset后尝试创建NetCDF文件,但变量conca['BA']始终不被识别为二维变量。试过reshape操作、强制生成二维变量、重新构建Xarray Dataset,都没解决问题。相关代码如下:
import pandas as pd import xarray as xr #pour les netCDF import os from matplotlib import pyplot as plt import numpy as np import cartopy.crs as ccrs import cartopy.feature as cfeature import matplotlib.pyplot as plt import cartopy as cart import netCDF4 as nc folder_path = 'XXXXXXXXXXXXXXX' def build_nc(ds, file_name): f = nc.Dataset('XXXXXXXXXXXXXXXX' + file_name, mode='w', format='NETCDF4_CLASSIC') # f is the newly created file f.createDimension('lon', len(ds['lon'])) f.createDimension('lat', len(ds['lat'])) longitude = f.createVariable('lon', 'f4', 'lon') latitude = f.createVariable('lat', 'f4', 'lat') BA_m2 = f.createVariable('BA', 'f4', ('lat', 'lon')) longitude[:] = ds['lon'].values latitude[:] = ds['lat'].values BA_m2[:] = ds['BA'].values f.description = "surface brûlée" longitude.units = "degrees east" latitude.units = "degrees north" BA_m2.units = "km2 brûlé" f.close() dfs = [] for file_name in os.listdir(folder_path): if os.path.isfile(os.path.join(folder_path, file_name)): print(file_name) ds = xr.open_dataset(folder_path + file_name) ds = ds.to_dataframe().reset_index() ds = ds[['lat','lon','burntFractionAll']] ds['burntFractionAll'] = ds['burntFractionAll']/100 ds = ds.groupby(['lon','lat'])['burntFractionAll'].mean() dfs.append(ds) del ds del folder_path conca = pd.concat(dfs, axis=0) del dfs #On renomme burntFractionAll en burntfractionall par BA_100 conca = conca.to_frame().reset_index() conca = conca.groupby(['lon','lat'])['burntFractionAll'].mean() conca = conca.to_frame().reset_index() conca['BA_100'] = conca['burntFractionAll']*29.5 rad = abs(np.cos(np.abs(conca['lat'])*0.0174)) # cos(lat*0.0174) surf_area = rad*1239 # cos(lat)*cell_area_2 km2 [1°*1°] conca['BA'] = conca['BA_100'] * surf_area conca['BA'] = conca['BA'] * 0.001# km2 to Mha car 1 ha = 10000 m2 conca = conca.set_index(['lon','lat']).to_xarray() conca['BA'] = conca['BA'].values.reshape(len(conca['lat']), len(conca['lon'])) build_nc(conca, file_name)
解决方案
1. 先确认数据维度结构
当前用set_index(['lon','lat']).to_xarray()生成的Dataset,BA大概率是一维数组——因为原始DataFrame是长格式(每行对应一组lon-lat对),转Xarray后不会自动网格化。先打印数据集结构确认:
print(conca)
如果BA的维度是(lon, lat)但实际是一维数组,说明数据未被正确转换为网格格式。
2. 正确将长格式数据转为二维网格
用Pandas的unstack把长格式数据转为宽格式网格,再转Xarray,这是核心修复步骤:
# 替换原代码中`conca = conca.set_index(['lon','lat']).to_xarray()`这一行 conca_grid = conca.set_index(['lat', 'lon'])['BA'].unstack(level='lon') conca = conca_grid.to_xarray()
处理后BA会变成标准的二维变量,维度为(lat, lon),完全匹配NetCDF定义的维度。
3. 用Xarray自带方法简化NetCDF生成
Xarray支持直接导出NetCDF,无需手动调用netCDF4库,能避免手动操作的维度匹配错误:
# 添加属性 conca.attrs['description'] = "surface brûlée" conca['lon'].attrs['units'] = "degrees east" conca['lat'].attrs['units'] = "degrees north" conca['BA'].attrs['units'] = "km2 brûlé" # 导出NetCDF conca.to_netcdf('你的目标文件路径/文件名.nc', format='NETCDF4_CLASSIC')
4. 若坚持用原build_nc函数的修复方案
如果一定要保留手动创建NetCDF的逻辑,需确保lat、lon是排序后的唯一值,且reshape顺序完全匹配:
# 先对lat和lon排序,保证reshape顺序正确 conca = conca.sort_values(['lat', 'lon']) # 获取唯一排序后的坐标 unique_lats = sorted(conca['lat'].unique()) unique_lons = sorted(conca['lon'].unique()) # 转换为Xarray并reshape conca_xr = conca.set_index(['lat', 'lon']).to_xarray() conca_xr['BA'] = (('lat', 'lon'), conca_xr['BA'].values.reshape(len(unique_lats), len(unique_lons))) # 更新坐标为唯一排序值 conca_xr['lat'] = unique_lats conca_xr['lon'] = unique_lons # 调用原函数 build_nc(conca_xr, file_name)
内容的提问来源于stack exchange,提问作者Lapingo
相关产品推荐
相关产品推荐

