如何提高大型 .nc 文件(70GB-350GB)的文件读取时间?

问题描述 投票:0回答:1

我正在使用 ERA5 大气数据以最大空间和时间分辨率计算全球任何地方的风速。这会产生一个包含一年数据的未压缩 70GB 文件,我想总共分析 5 年的数据,因此它可以快速扩展。

在我的应用程序中,我想检索单个空间坐标的整个时间历史数据,一年内会产生单个

[1x8760]
数组(来自
[721x1440x8760]
的总数组)。然而,使用
xarray
读取此数据大约需要 12 秒。考虑到我想做一个让用户直接输入坐标的 API,这个时间太长了,而且我还需要 5 年时间。此外,我想扩大不同气压下的数据,并且由于数据将存储在外部设备中,因此会产生更多的时间开销。以下是代码工作原理的片段:

import xarray as xr                                                                
import dask.array as da                                                                                                                   
import time                                                                        

# Timer starts                                                                      
start = time.time()                                                                

# Specifying the coordinates                                                                               
lat = 1                                                                            
lon = 1                                                                            

# Opening the file                                          
ds = xr.open_dataset('2023Data.nc', engine='netcdf4')                                                                                                                                                                                                                                              
                                                                                   
# For now the method of obtaining data is just by choosing the nearest point                             
u_region = ds.u.sel(lat=lat, lon=lon, method='nearest').data                       
v_region = ds.v.sel(lat=lat, lon=lon, method='nearest').data                                                                                  

# Converting the data into absolute velocity and angle                                                                                                                                                
abs_region = da.sqrt(u_region ** 2 + v_region ** 2)                                
theta = da.arctan2(u_region, v_region)                                                                                                                         
                                                                                   
print(abs_region, theta)                                                           
end = time.time()                                                                  
print(end - start)

有没有一种索引方法可以更快地检索这些数据?考虑到数据文件和查询的大小,这些读取时间是否正常?难道只是我电脑的问题?

我尝试使用

cdo
和 line chunks 选项将其压缩到 deflate level 9,这导致更高的开销(我猜压缩太深了,但我不确定分块是否有帮助)。对于
cdo
,我还尝试减小
--resolution
和位大小
-b
,因为我只需要 3 位小数,但这甚至不起作用。

我也尝试过使用

dask
的本机分块算法,但我不太确定这是否有助于仅读取文件的部分内容。我只想访问一个坐标,如下图左侧的图,所以我想通过正确的索引,可以大大减少阅读时间。

NetCDF Data Access Patterns

dask python-xarray netcdf netcdf4 era5
1个回答
0
投票

关键问题是原始数据的分块。为了提取任何单个点,需要读取和解码一块数据。假设您的数据具有像 [1x360x2190] 这样的分块,这相当于 int/float64 内存中的 6MB/块。在这种情况下,输出一维数组的每个点都需要读取和解压缩/解码 6MB 的数据(磁盘上的大小取决于压缩),因此您的进程需要扫描 8760x6MB = 52GB 的数据。同样,这是针对 64 位值以及我对您的分块可能是什么的猜测。

请注意,您无法在不重写数据的情况下更改数据分块。如果您需要的话,有像

rechunker
这样的工具可以帮助您。调整你的访问模式和分块本身就是一个普通的对话。

请注意,如果您发现 dask 没有提供良好的并行性,您可以尝试使用 kerchunk

 扫描文件。但是,我怀疑这不会产生什么影响,并且您会受到磁盘和内存速度的瓶颈。

© www.soinside.com 2019 - 2024. All rights reserved.