【发布时间】:2020-07-21 08:17:03
【问题描述】:
我正在尝试使用 python netCDF4 模块将多个变量(例如 A 和 B)写入单个 netcdf 文件。
我的函数在每次循环迭代中为A 输出一个新时间片,为B 输出一个新时间片,我试图在这些新片出现时将它们保存到文件中,而不是在 RAM 中累积并一次性节省。
以下是我目前的尝试:
import numpy as np
from netCDF4 import Dataset, date2num, num2date
fout=Dataset('test.nc', 'w')
x=np.arange(10)
y=np.arange(20)
xx,yy=np.meshgrid(x,y)
# create dimensions
fout.createDimension('x', len(x))
fout.createDimension('y', len(y))
fout.createDimension('t', None)
x_ax=fout.createVariable('x', np.float, ['x',])
x_ax[:]=x
y_ax=fout.createVariable('y', np.float, ['y',])
y_ax[:]=y
t_ax=fout.createVariable('t', np.float, ['t',])
# a big loop
for ii in range(10):
# some function that outputs a slice of A and a slice of B
var_aii=(xx*ii + yy)[None, ...]
var_bii=(xx + yy*ii)[None, ...]
if 'var_A' not in fout.variables.keys():
# if 1st time writing "var_A", create new variable
var_A=fout.createVariable('var_A', np.float, ['t', 'y', 'x'])
var_A[:]=var_aii
else:
# if variable already created, append to the end of 1st dimension
var_A=fout.variables['var_A']
var_A[:]=np.concatenate([var_A[:], var_aii])
if 'var_B' not in fout.variables.keys():
var_B=fout.createVariable('var_B', np.float, ['t', 'y', 'x'])
var_B[:]=var_aii
else:
var_B=fout.variables['var_B']
var_B[:]=np.concatenate([var_B[:], var_aii])
print('ii=', ii, 'var_A.shape=', var_A.shape, 'var_B.shape=', var_B.shape)
fout.close()
这是输出:
ii= 0 var_A.shape= (1, 20, 10) var_B.shape= (1, 20, 10)
ii= 1 var_A.shape= (3, 20, 10) var_B.shape= (3, 20, 10)
ii= 2 var_A.shape= (5, 20, 10) var_B.shape= (5, 20, 10)
ii= 3 var_A.shape= (7, 20, 10) var_B.shape= (7, 20, 10)
ii= 4 var_A.shape= (9, 20, 10) var_B.shape= (9, 20, 10)
ii= 5 var_A.shape= (11, 20, 10) var_B.shape= (11, 20, 10)
ii= 6 var_A.shape= (13, 20, 10) var_B.shape= (13, 20, 10)
ii= 7 var_A.shape= (15, 20, 10) var_B.shape= (15, 20, 10)
ii= 8 var_A.shape= (17, 20, 10) var_B.shape= (17, 20, 10)
ii= 9 var_A.shape= (19, 20, 10) var_B.shape= (19, 20, 10)
问题在于t 维度的时间增长了 2 步,而不是 1。我认为这是因为无限的 t 维度会随着更多数据的添加而自动扩展,因此在 ii==1 迭代中,写入var_A后,时间维度增长到2的长度,所以在追加var_B时,var_B在追加之前已经有2的长度了。
我没有使用ii 作为索引来分配像var_A[ii]=var_aii 这样的值,因为我觉得它容易出错。如果循环中有一些条件continues 跳过了几个iis,就会产生间隙。
那么沿时间维度递增地追加多个变量的更稳健的方法是什么?
【问题讨论】: