Python: извлечение данных CSV из данных временных рядов из данных netCDF с высоким разрешением с использованием xarray - PullRequest
1 голос
/ 27 сентября 2019

Попытка загрузить несколько файлов netCDF с высоким разрешением, используя OpenDAP и xarray, в один набор данных;а затем извлекать данные временных рядов по координатам широты и долготы в отдельные файлы CSV.Я использую xarray и dask.

Я могу написать один CSV, но цикл по всему набору данных займет> 1200 часов.

Лучше выбрать отдельные точки или все точки, а затем преобразовать все в файлы CSV?

import xarray as xr


Variables = collections.namedtuple('Variables', ['new_name', 'conversion', 'units'])
toMJm2 = 3.6e-3
toDegC = 273.15
tomm = 1.0

VARS_DICT = {"rsds": Variables('SRAD', toMJm2, "MJ m**-2"),
             "tasmax": Variables("TMax", toDegC, "C"),
             "tasmin": Variables("TMin", toDegC, "C"),
             "pr": Variables("Rain", tomm, "mm")}


def open_rename_ds(file):
    ds = xr.open_dataset(file, chunks={"lat": 5, "lon": 10, "time": -1})
    ds = ds.squeeze('crs').drop('crs')
    ds = ds.assign_coords(lon=(((ds.lon + 180) % 360) - 180))
    var_name = os.path.basename(file).split("_")[2]
    v = VARS_DICT[var_name]
    for k in ds.data_vars:
        if v.conversion == 273.15:
            ds[v.new_name] = ds[k] - v.conversion
        else:
            ds[v.new_name] = ds[k] * v.conversion
        ds[v.new_name].attrs["units"] = v.units
    _ds = ds.drop([k])
    return _ds.sel(time=slice("2020-01-01","2099-12-30"))

fileslist = ['http://thredds.northwestknowledge.net:8080/thredds/dodsC/agg_macav2metdata_tasmax_bcc-csm1-1_r1i1p1_rcp85_2006_2099_CONUS_daily.nc',
'http://thredds.northwestknowledge.net:8080/thredds/dodsC/agg_macav2metdata_tasmin_bcc-csm1-1_r1i1p1_rcp85_2006_2099_CONUS_daily.nc', 'http://thredds.northwestknowledge.net:8080/thredds/dodsC/agg_macav2metdata_pr_bcc-csm1-1_r1i1p1_rcp85_2006_2099_CONUS_daily.nc', 'http://thredds.northwestknowledge.net:8080/thredds/dodsC/agg_macav2metdata_rsds_bcc-csm1-1_r1i1p1_rcp85_2006_2099_CONUS_daily.nc']

dss = [open_rename_ds(file) for file in fileslist]
# Create a single dataset for the four opened datasets using `.update`
ds = dss[0]
for d in dss[1:]:
    ds.update(d)

# drop the attributes for brevity
ds.attrs = {}

Вот размер и информация о наборе данных:

print("ds size in GB {:0.2f}\n".format(ds.nbytes / 1e9))
print(ds.info())

ds size in GB 379.06

xarray.Dataset {
dimensions:
    lat = 585 ;
    lon = 1386 ;
    time = 29219 ;

variables:
    float64 lat(lat) ;
        lat:long_name = latitude ;
        lat:standard_name = latitude ;
        lat:units = degrees_north ;
        lat:axis = Y ;
        lat:description = Latitude of the center of the grid cell ;
    float64 lon(lon) ;
    datetime64[ns] time(time) ;
        time:description = days since 1900-01-01 ;
    float32 TMax(time, lat, lon) ;
        TMax:units = C ;
    float32 TMin(time, lat, lon) ;
        TMin:units = C ;
    float32 Rain(time, lat, lon) ;
        Rain:units = mm ;
    float32 SRAD(time, lat, lon) ;
        SRAD:units = MJ m**-2 ;

// global attributes:
}

Нужно отбросить все nan широта / долгота, потому что это должно уменьшить размер файла.

Я пытаюсь что-то вроде:

dd = ds.isel(lat=list_of_valid_lats, lon=list_of_valid_lons).to_dataframe()
dd.to_csv("testing_filename.csv.gz", index=False, compression="gzip")

Этоберет навсегда и часто вылетает мой компьютер.Я также пытался использовать to_dask_dataframe()

Я также пытался:

df = ds.isel(lat=0, lon=1049).to_dataframe().reset_index()
df.to_csv("testing_filename_csv.gz", index=False, compression="gzip")

Это работает, но очень медленно, когда есть более ~ 400 000 точек сетки.

Я такженужно повторить это для ~ 40 похожих файлов.

Будут ли признательны любые мысли или идеи по улучшению производительности?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...