Я настоятельно рекомендую вам взглянуть на проекты xarray
и dask
. Использование этих мощных инструментов позволит вам легко разделить вычисления на куски. Это дает два преимущества: вы можете рассчитывать на данные, которые не подходят в памяти, и вы можете использовать все ядра на вашем компьютере для лучшей производительности. Вы можете оптимизировать производительность, соответствующим выбору размера куска (см. documentation).
Вы можете загрузить данные из NetCDF делать что-то же просто, как
import xarray as xr
ds = xr.open_dataset(path_file)
Если вы хотите, чтобы кусок данных в годы вдоль измерения времени, то можно указать параметр chunks
(при условии, что год координат называется «год»):
ds = xr.open_dataset(path_file, chunks={'year': 10})
Поскольку другие координаты не появляются в chunks
Словаре, то один блок будет использоваться для них. (См. Более подробную информацию в документации here.). Это будет полезно для вашего первого требования, где вы хотите умножать каждый год 2D-массив. Вы бы просто сделать:
ds['new_var'] = ds['var_name'] * arr_2d
Теперь xarray
и dask
вычисляют свой результат лениво. Для того, чтобы вызвать фактическое вычисление, вы можете просто попросить xarray
сохранить результат обратно в NetCDF:
ds.to_netcdf(new_file)
Расчет сработал через dask
, который заботится о расщеплении обработку в кусках и, таким образом, позволяет работать с данных, которые не соответствуют памяти. Кроме того, dask
позаботится о том, чтобы использовать все процессорные ядра для вычислительных блоков.
Проекты xarray
и dask
все еще не справляются с хорошими ситуациями, когда куски не «выравниваются» хорошо для параллельных вычислений. Поскольку в этом случае мы размещались только в «годичном» измерении, мы не ожидаем никаких проблем.
Если вы хотите добавить две разные 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 ...
Вы уверены, что читаете какие-либо другие вопросы (например, весь файл за раз), будет быстрее? Можете ли вы попробовать с обрезанным файлом? –
Любое [существенное профилирование] (http://stackoverflow.com/questions/582336/how-can-you-profile-a-python-script) сделано? –
Вы делаете что-либо с данными года, как только вы его читаете? Можете ли вы прочитать несколько лет, например. '[1997: 2007,:,:]'? – hpaulj