以快速方式读取变量的非连续子集

时间:2018-01-30 16:03:30

标签: python python-3.x numpy netcdf

我有一个netCDF4.Variable对象:

<class 'netCDF4._netCDF4.Variable'>
int16 myvar(time, latitude, longitude)
    standard_name: my_var
    long_name: Something
    units: (0 - 1)
    add_offset: 0.499999843485
    scale_factor: 1.54488841466e-05
    _FillValue: -32767
    missing_value: -32767
unlimited dimensions: time
current shape = (13148, 1441, 2880)
filling off

此变量是一个3D变量,其中第一个维度是时间维度,另外两个是空间维度。

我想访问此变量的子集:

  • 时间范围的子集(例如,从70008000)。
  • 由空间范围的展平版本中的索引标识的点的子集 - 在上面的示例中,索引的范围介于01441 * 2880之间。

基本上,我有:

tmin = 7000
tmax = 8000
upts = [42829, 9289, 3242]

我目前的访问方式是:

z = np.zeros(len(upts),  tmax - tmin)
for i in range(tmin, tmax):
    z[:, i - tmin] = my_var[i, :, :].flatten()[upts]

我想知道是否有更快的方法来做到这一点?

我无法将整个数据集加载到内存中,因为它已经很大了,而且可能更大。

我也不能仅使用一个i,因为我想在z行(对应于&#34;列&#34; my_var中)进行操作。< / p>

2 个答案:

答案 0 :(得分:1)

不确定这是否以内存方式工作,但您是否会考虑首先使用NCO或CDO从python外部的命令行中删除文件,然后从python中读取该文件?这取决于您是否需要重复访问文件的不同块,或者这是否是一次性访问。

NCO中hyperslab的命令是

ncks -d dim_name,val1,val2 in.nc -O out.nc 

如果val是一个整数,则使用索引完成切割,如果它是浮点数,则在维度的值上完成。您可以在参数列表中放置多个维度。 (如本回答所示:NCO cropping a netcdf file using dimension values rather than indices

CDO需要您所拥有的标准尺寸,纬度,经度和时间,因此您可以使用

切割lat-lon框和一系列时间步长
cdo seltimestep,7000,8000 -sellonlatbox,lon1,lon2,lat1,lat2 in.nc out.nc

CDO的优势在于您还可以使用日期格式缩短时间。所以你可以使用

从7000切换到8000
cdo seldate,yyyymmdd,yyyymmdd in.nc out.nc

我觉得非常有用。

根据我的经验,当NCO正常工作时,CDO似乎会扼杀内存要求,这可能会影响您的选择。在任何情况下,如果你需要反复挑选文件的不同部分,这个建议对你来说不是很有用,但希望对其他人有用。

答案 1 :(得分:0)

如果要访问数据以进行只读,则不必将子集中的所有元素复制到新列表中。相反,您只需将引用复制到列表中即可:

z = [my_var[i] for i in range(tmin, tmax)]

如果您需要可以编辑的子集副本而不影响整个集合,那么您必须像当前代码那样复制元素。