Итак, я мог бы придумать что-то, что можно квалифицировать как «решение».
Нулевые массивы, очевидно, могут быть проиндексированы одним и тем же списком итераций, например.
a = np.reshape(range(0,16),(4,4),order='F')
a = a[ [[0,1], [1]] ]
возвращается a
равна array([4,5])
. Другим примером может быть [[range(3),[1 2],3]]
. Эти одиночные списки разворачиваются в порядке *subscripts
, как если бы вы прямо запросили a[[0,1],1]
вместо a[ [[0,1],1] ]
.
Итак, если вы можете запросить позицию и длину каждого измерения в переменной netCDF (довольно легко с nc_fid[var].dimension
и nc_fid[var].shape
), вы можете просто переставить список в соответствии с расположением каждого измерения. Например, если у вас есть данные о время формы Лон на латах, и вы хотите всех долгот, всех широты и временный индекс t=5
, вы можете использовать что-то вроде
order_want = ['lon', 'lat', 'time'] # must figure out dimension names a priori
nlon = nc_fid[var].shape[nc_fid[var].dimensions.index('lon')]
nlat = nc_fid[var].shape[nc_fid[var].dimensions.index('lat')]
ids = [ range(0,nlon), range(0,nlat), 5 ]
ids_permute = [order_want.index(n) for n in nc_fid[var].dimensions]
ids_query = [l[i] for l,i in zip(ids,ids_permute)]
sliced_data = nc_fid[var][list_query]
Это требует не существует априорные знание размерной позиции и не требуют загрузки всех размеров переменной.
Обратите внимание, что после некоторого тестирования %timeit
в IPython появляется некоторая специальная задержка для индексирования целых чисел, например. list_query = [0,0,0,0]
будет принимать 80 мс тогда как list_query = [range(1),0,0,0]
или даже list_query = [[0,1,2,3,4,5],0,0,0]
займет 1ms. Очень загадочно; в любом случае, очевидно, вы должны попытаться убедиться, что list_query
- это не просто список целых чисел.