Xarray读取Copernicus NetCDF文件时内存占用远超文件本身的问题咨询
Xarray读取Copernicus NetCDF文件时内存占用远超文件本身的问题咨询
大家好,
我最近在用xarray 2024-11-0版本读取Copernicus数据中心的NetCDF文件,用的是open_dataset函数,代码如下:
import xarray as xr file1=xr.open_dataset("2021-04.nc") tem = file1['t2m']
这个NetCDF文件的实际大小只有16.6MB,但读取后的t2m变量占用内存居然达到了39MB——从变量输出的第一行就能看到,用top命令监控也是这个情况。下面是这个变量的详细信息:
<xarray.DataArray 't2m' (valid_time: 30, latitude: 411, longitude: 791)> Size: 39MB [9753030 values with dtype=float32] Coordinates: number int64 8B ... * latitude (latitude) float64 3kB 38.0 37.9 37.8 37.7 ... -2.8 -2.9 -3.0 * longitude (longitude) float64 6kB -18.0 -17.9 -17.8 ... 60.8 60.9 61.0 * valid_time (valid_time) datetime64[ns] 240B 2021-04-01 ... 2021-04-30 Attributes: (12/32) GRIB_paramId: 167 GRIB_dataType: fc GRIB_numberOfPoints: 325101 GRIB_typeOfLevel: surface GRIB_stepUnits: 1 GRIB_stepType: instant ... GRIB_totalNumber: 0 GRIB_units: K long_name: 2 metre temperature units: K standard_name: unknown GRIB_surface: 0.0
我实在搞不懂为什么xarray会占用这么多内存?小文件的话还能接受,但处理大文件或者需要频繁复制变量做计算的时候,这个问题就特别棘手,根本吃不消。
我试过用file1['t2m'].astype('float16')把数据转成float16类型,内存能直接减半,但这样做的代价是大部分数值都会被四舍五入到小数点后一位,直接损失了原始数据的精度。我想要的是读取真实的原始数据,同时内存占用不要超过文件本身的大小。
下面是读取为float32时的数据示例,能看到完整的精度:
<xarray.DataArray 't2m' (valid_time: 30)> Size: 120B array([293.87134, 296.0669 , 299.4065 , 302.60474, 305.29443, 306.87646, 301.10645, 302.47388, 299.23267, 294.26587, 295.239 , 299.19238, 302.20923, 307.48193, 307.2202 , 310.6953 , 315.64746, 312.76416, 305.2173 , 299.25488, 299.9475 , 302.3435 , 306.32422, 312.75342, 299.99878, 300.59155, 303.36475, 307.11768, 308.49292, 310.6853 ], dtype=float32) Coordinates:
而转成float16后,精度明显下降了:
<xarray.DataArray 't2m' (valid_time: 30)> Size: 60B array([293.8, 296. , 299.5, 302.5, 305.2, 307. , 301. , 302.5, 299.2, 294.2, 295.2, 299.2, 302.2, 307.5, 307.2, 310.8, 315.8, 312.8, 305.2, 299.2, 300. , 302.2, 306.2, 312.8, 300. , 300.5, 303.2, 307. , 308.5, 310.8], dtype=float16)
另外,我还写了一段代码追踪内存使用情况,发现把数据加载到RAM后,内存占用是文件实际数据大小的好几倍:
import psutil process = psutil.Process() print("memory used in MB=", process.memory_info().rss / 1024**2) tem.data print("memory used in MB=", process.memory_info().rss / 1024**2)
有没有大佬能帮我解答一下这个问题?谢谢大家!
备注:内容来源于stack exchange,提问作者Kernel
相关产品推荐
相关产品推荐

