NetCDF: Как извлечь данные, которые выходят за границы?

У меня есть файл NetCDF с четырьмя измерениями: время, уровень, широта и долгота. Форма данных: 1, 60, 1440, 2880

Это означает, что существует 1 момент времени, 60 уровней, 1440 широт и 2880 долгот.

Широта варьируется от -90 до 90 с шагом 0,125. Например:

lats = np.arange(-90,90.125, 0.125)

Долгота варьируется от 0 до 360 с шагом 0,125. Например:

lons = np.arange(0,360, 0.125)

Имею "Станцию" с местоположением по GPS: station.lat, station.lon = 22.125, 275.250. Преобразуйте долготу в сетку на 360 градусов: station.lon = station.lon%360.0

Я хочу извлечь куб о своей станции. Например, 5 ячеек слева, 5 справа и все уровни. (включая камеру, в которой находится станция)

Для этого я получаю индекс lat в lats и индекс lon в lons.

Затем я создаю ряд индексов, которые использую для извлечения данных из файла netCDF:

    lat_index_range = np.arange(nearest_latitude_index-5, nearest_latitude_index+5, 1)%1441
    lon_index_range = np.arange(nearest_longitude_index-5, nearest_longitude_index+5, 1)%2881

Представим

lat_index_range = [1220,1221,1223,1224,1225,1226,1227,1228,1229,1230,1231]
lon_index_range = [2250,2251,2252,2253,2254,2255,2256,2257,2258,2259,2260,2261]

Затем я извлекаю данные:

factor = dataset[parameter][0]
factor[:,min(lat_index_range):max(lat_index_range),min(lon_index_range):max(lon_index_range)

Это работает нормально, однако индекс 2880 будет представлять 360 градусов, поэтому, если моя точка была расположена рядом с границей (т.е. у нее была долгота, индекс которой был сопоставлен с 2879), мне нужно вернуться к началу. Тогда мой lon_index_range будет выглядеть примерно так:

lon_index_range = [2879,2880,0,1,2,3,4,5,6,7,8]

Извлечь мои данные сейчас не получится ...

factor = dataset[parameter][0]
factor[:,1220:1231,0:2879) # this would take ALL the longitude data from 0 to 2879!!

Точно так же у меня не может быть чего-то вроде этого: factor[:,1220:1231,2879:8)

Та же проблема существует для широт ... поскольку моя точка может быть около границы широты.

Кто-нибудь знает, как я могу решить эту проблему?


person pookie    schedule 07.10.2017    source источник
comment
Я думаю, что Numpy roll() будет здесь полезен (и теперь, когда у вас импортирован Numpy, вы также можете избавиться от этих уродливых представлений о списках, например, lons = np.arange(...) или np.linspace(...))   -  person Bart    schedule 08.10.2017
comment
Возможный дубликат индексов кругового numpy-массива   -  person Bart    schedule 08.10.2017
comment
Спасибо, но я не спрашиваю, как создать круговой массив. У меня вопрос об извлечении данных из файла NetCDF. Ps Спасибо за np.arange совет - он делает намного красивее.   -  person pookie    schedule 09.10.2017


Ответы (2)


Я все еще думаю, что ответы здесь могут помочь. В качестве очень минимального примера;

import numpy as np

def cslice(a, start, stop): 
    if start > stop:
        part1  = a[start:]
        part2  = a[:stop ]
        return np.concatenate([part1, part2])
    else:
        return a[start:stop]

lons = np.arange(0,360,60)

print(lons)
print(cslice(lons, 0, 4))
print(cslice(lons, 4, 2))

Что приводит к:

[  0  60 120 180 240 300]
[  0  60 120 180]
[240 300   0  60]
person Bart    schedule 09.10.2017

Если вы не против сделать это из командной строки, это одна строка в CDO:

cdo sellonlatbox,lon1,lon2,lat1,lat2 in.nc out.nc

вы можете указать lon в диапазоне -180,180, а также 0 360, и он обработает его за вас.

person Adrian Tompkins    schedule 09.10.2017
comment
Сможет ли он с 257 до 8? - person pookie; 09.10.2017