13

我正在尝试处理来自非常大的 netCDF 文件(每个约 400 Gb)的数据。每个文件都有一些变量,它们都比系统内存大得多(例如 180 Gb 与 32 Gb RAM)。我正在尝试使用 numpy 和 netCDF4-python 通过一次复制一个切片并对该切片进行操作来对这些变量进行一些操作。不幸的是,读取每个切片需要很长时间,这会影响性能。

例如,其中一个变量是一个 shape 数组(500, 500, 450, 300)。我想对 slice 进行操作[:,:,0],所以我执行以下操作:

import netCDF4 as nc

f = nc.Dataset('myfile.ncdf','r+')
myvar = f.variables['myvar']
myslice = myvar[:,:,0]

但是最后一步需要很长时间(在我的系统上大约 5 分钟)。例如,如果我(500, 500, 300)在 netcdf 文件中保存了一个形状变量,那么相同大小的读取操作只需几秒钟。

有什么办法可以加快速度吗?一个明显的路径是转置数组,以便我选择的索引首先出现。但在如此大的文件中,这在内存中是不可能的,而且考虑到一个简单的操作已经花费了很长时间,尝试它似乎更慢。我想要的是一种以 Fortran 接口 get_vara 函数的方式读取 netcdf 文件片段的快速方法。或某种有效转置数组的方法。

4

2 回答 2

8

您可以使用 nccopy 实用程序转置太大而无法放入内存的 netCDF 变量,此处记录了该实用程序:

http://www.unidata.ucar.edu/netcdf/docs/guide_nccopy.html

这个想法是通过指定变量所需的块形状(多维图块)来“重新分块”文件。您可以指定将多少内存用作缓冲区以及将多少内存用于块缓存,但不清楚如何在这些用途之间以最佳方式使用内存,因此您可能只需要尝试一些示例并为它们计时。您可能不想完全转置变量,而是希望通过指定沿切片的 2 个大维度具有大量数据而沿其他维度只有少数值的块来“部分转置”它。

于 2012-08-22T22:42:33.107 回答
3

这是评论,不是答案,但我无法对上述内容发表评论,对不起。

我了解您要myvar[:,:,i]处理iin range(450)。在这种情况下,您将执行以下操作:

for i in range(450):
    myslice = myvar[:,:,i]
    do_something(slice)

瓶颈在于访问myslice = myvar[:,:,i]. 您是否尝试过比较访问需要多长时间moreslices = myvar[:,:,0:n]?这将是连续数据,也许您可​​以节省时间。您可以选择n内存所能提供的最大容量,然后处理下一个数据块,moreslices = myvar[:,:,n:2n]依此类推。

于 2012-08-22T13:36:53.663 回答