gpt4 book ai didi

python - 加快在 python 中读取非常大的 netcdf 文件

转载 作者:太空狗 更新时间:2023-10-29 17:25:46 26 4
gpt4 key购买 nike

我有一个非常大的 netCDF 文件,我正在使用 python 中的 netCDF4 读取它

我无法一次读取所有文件,因为它的尺寸 (1200 x 720 x 1440) 太大,整个文件无法一次进入内存。第一个维度代表时间,接下来的两个维度分别代表纬度和经度。

import netCDF4 
nc_file = netCDF4.Dataset(path_file, 'r', format='NETCDF4')
for yr in years:
nc_file.variables[variable_name][int(yr), :, :]

但是,一次阅读一年的速度非常慢。对于以下用例,我该如何加快速度?

--编辑

block 大小为1

  1. 我可以读取年份范围:nc_file.variables[variable_name][0:100, :, :]

  2. 有几个用例:

    年:

    numpy.ma.sum(nc_file.variables[variable_name][int(yr), :, :])

# Multiply each year by a 2D array of shape (720 x 1440)
for yr in years:
numpy.ma.sum(nc_file.variables[variable_name][int(yr), :, :] * arr_2d)

# Add 2 netcdf files together 
for yr in years:
numpy.ma.sum(nc_file.variables[variable_name][int(yr), :, :] +
nc_file2.variables[variable_name][int(yr), :, :])

最佳答案

我强烈建议您查看 xarraydask项目。使用这些强大的工具将使您能够轻松地将计算分成 block 。这带来了两个优势:您可以计算内存中放不下的数据,并且可以使用机器中的所有内核以获得更好的性能。 You can optimize the performance by appropriately choosing the chunk size (see documentation ).

您可以通过像

这样简单的操作从 netCDF 加载数据
import xarray as xr
ds = xr.open_dataset(path_file)

如果您想在时间维度上以年为单位对数据进行分 block ,则可以指定 chunks 参数(假设年份坐标名为“year”):

ds = xr.open_dataset(path_file, chunks={'year': 10})

由于其他坐标没有出现在 chunks 字典中,因此将为它们使用一个单独的 block 。 (请参阅文档 here 中的更多详细信息。)。这对于您的第一个要求很有用,您希望每年乘以一个二维数组。你只需要做:

ds['new_var'] = ds['var_name'] * arr_2d

现在,xarraydask 正在延迟计算您的结果。为了触发实际的计算,您可以简单地要求 xarray 将您的结果保存回 netCDF:

ds.to_netcdf(new_file)

计算是通过 dask 触发的,它负责将处理分成 block ,从而可以处理不适合内存的数据。此外,dask 将负责将所有处理器内核用于计算 block 。

xarraydask 项目仍然不能很好地处理 block 不能很好地“对齐”以进行并行计算的情况。由于在本例中我们仅在“年”维度中分 block ,因此我们预计不会出现任何问题。

如果要将两个不同的 netCDF 文件加在一起,很简单:

ds1 = xr.open_dataset(path_file1, chunks={'year': 10})
ds2 = xr.open_dataset(path_file2, chunks={'year': 10})
(ds1 + ds2).to_netcdf(new_file)

我已经使用 a dataset available online 提供了一个完整的示例.

In [1]:

import xarray as xr
import numpy as np

# Load sample data and strip out most of it:
ds = xr.open_dataset('ECMWF_ERA-40_subset.nc', chunks = {'time': 4})
ds.attrs = {}
ds = ds[['latitude', 'longitude', 'time', 'tcw']]
ds

Out[1]:

<xarray.Dataset>
Dimensions: (latitude: 73, longitude: 144, time: 62)
Coordinates:
* latitude (latitude) float32 90.0 87.5 85.0 82.5 80.0 77.5 75.0 72.5 ...
* longitude (longitude) float32 0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 20.0 ...
* time (time) datetime64[ns] 2002-07-01T12:00:00 2002-07-01T18:00:00 ...
Data variables:
tcw (time, latitude, longitude) float64 10.15 10.15 10.15 10.15 ...

In [2]:

arr2d = np.ones((73, 144)) * 3.
arr2d.shape

Out[2]:

(73, 144)

In [3]:

myds = ds
myds['new_var'] = ds['tcw'] * arr2d

In [4]:

myds

Out[4]:

<xarray.Dataset>
Dimensions: (latitude: 73, longitude: 144, time: 62)
Coordinates:
* latitude (latitude) float32 90.0 87.5 85.0 82.5 80.0 77.5 75.0 72.5 ...
* longitude (longitude) float32 0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 20.0 ...
* time (time) datetime64[ns] 2002-07-01T12:00:00 2002-07-01T18:00:00 ...
Data variables:
tcw (time, latitude, longitude) float64 10.15 10.15 10.15 10.15 ...
new_var (time, latitude, longitude) float64 30.46 30.46 30.46 30.46 ...

In [5]:

myds.to_netcdf('myds.nc')
xr.open_dataset('myds.nc')

Out[5]:

<xarray.Dataset>
Dimensions: (latitude: 73, longitude: 144, time: 62)
Coordinates:
* latitude (latitude) float32 90.0 87.5 85.0 82.5 80.0 77.5 75.0 72.5 ...
* longitude (longitude) float32 0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 20.0 ...
* time (time) datetime64[ns] 2002-07-01T12:00:00 2002-07-01T18:00:00 ...
Data variables:
tcw (time, latitude, longitude) float64 10.15 10.15 10.15 10.15 ...
new_var (time, latitude, longitude) float64 30.46 30.46 30.46 30.46 ...

In [6]:

(myds + myds).to_netcdf('myds2.nc')
xr.open_dataset('myds2.nc')

Out[6]:

<xarray.Dataset>
Dimensions: (latitude: 73, longitude: 144, time: 62)
Coordinates:
* time (time) datetime64[ns] 2002-07-01T12:00:00 2002-07-01T18:00:00 ...
* latitude (latitude) float32 90.0 87.5 85.0 82.5 80.0 77.5 75.0 72.5 ...
* longitude (longitude) float32 0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 20.0 ...
Data variables:
tcw (time, latitude, longitude) float64 20.31 20.31 20.31 20.31 ...
new_var (time, latitude, longitude) float64 60.92 60.92 60.92 60.92 ...

关于python - 加快在 python 中读取非常大的 netcdf 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35422862/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com