Python: Netcdf: есть ли способ получить общее среднее значение от одной переменной, когда другая переменная перекрывается уникальным значением? - PullRequest
0 голосов
/ 31 марта 2020

У меня есть файл netcdf с трехмерной переменной int32, называемой тегом (время формы), и трехмерной переменной float64, называемой p (форма времени, длина). Размеры формы идентичны для обеих переменных. Целочисленные значения для переменной тега имеют начальное значение в 0 и неизвестное число для его конечного значения (они монотонно увеличиваются). Значение 0 не требуется, поэтому я хотел бы начать общее (пространство-время) среднее значение p var, где значение тега = 1 до наибольшего значения тега n.

Пример (пространство массива (время, широта, lon)): первое целочисленное значение тега равно 1. Это значение встречается, скажем, (0,45,45) и (1,45,46). Значения p в этих тегах = 1 пространства массива, скажем, 2 и 4. Таким образом, усредненный результат должен быть равен 3. Следующее целочисленное значение тега равно 2. Это значение происходит, скажем, (2 100,99), (2 101,99) и (3 101,98), где значения p в этих пространствах массивов равны 3, 8 и 1. Таким образом, усредненный результат должен быть равен 4. Последнее целочисленное значение равно n. Это значение имеет место, скажем, (360 200 100), (361 200 100), (361 201 100) и (361 (202 100)), где значения p в этих пространствах массивов равны 1, 1, 5 и 9. Таким образом, усредненный результат должен быть равен 4. Когда они записываются в текстовый файл, он должен выглядеть следующим образом:

3
4
.
.
4

Приведенный ниже код python читает файлы и переменные netcdf:

import datetime as dt  # Python standard library datetime  module
import numpy as np
from netCDF4 import Dataset  # http://code.google.com/p/netcdf4-python/


def ncdump(nc_fid, verb=True):
    '''
    ncdump outputs dimensions, variables and their attribute information.
    The information is similar to that of NCAR's ncdump utility.
    ncdump requires a valid instance of Dataset.

    Parameters
    ----------
    nc_fid : netCDF4.Dataset
        A netCDF4 dateset object
    verb : Boolean
        whether or not nc_attrs, nc_dims, and nc_vars are printed

    Returns
    -------
    nc_attrs : list
        A Python list of the NetCDF file global attributes
    nc_dims : list
        A Python list of the NetCDF file dimensions
    nc_vars : list
        A Python list of the NetCDF file variables
    '''
    def print_ncattr(key):
        """
        Prints the NetCDF file attributes for a given key

        Parameters
        ----------
        key : unicode
            a valid netCDF4.Dataset.variables key
        """
        try:
            print "\t\ttype:", repr(nc_fid.variables[key].dtype)
            for ncattr in nc_fid.variables[key].ncattrs():
                print '\t\t%s:' % ncattr,\
                      repr(nc_fid.variables[key].getncattr(ncattr))
        except KeyError:
            print "\t\tWARNING: %s does not contain variable attributes" % key

    # NetCDF global attributes
    nc_attrs = nc_fid.ncattrs()
    if verb:
        print "NetCDF Global Attributes:"
        for nc_attr in nc_attrs:
            print '\t%s:' % nc_attr, repr(nc_fid.getncattr(nc_attr))
    nc_dims = [dim for dim in nc_fid.dimensions]  # list of nc dimensions
    # Dimension shape information.
    if verb:
        print "NetCDF dimension information:"
        for dim in nc_dims:
            print "\tName:", dim 
            print "\t\tsize:", len(nc_fid.dimensions[dim])
            print_ncattr(dim)
    # Variable information.
    nc_vars = [var for var in nc_fid.variables]  # list of nc variables
    if verb:
        print "NetCDF variable information:"
        for var in nc_vars:
            if var not in nc_dims:
                print '\tName:', var
                print "\t\tdimensions:", nc_fid.variables[var].dimensions
                print "\t\tsize:", nc_fid.variables[var].size
                print_ncattr(var)
    return nc_attrs, nc_dims, nc_vars

nc_f = './tag.nc'  # Your filename
nc_fid = Dataset(nc_f, 'r')  # Dataset is the class behavior to open the file
                             # and create an instance of the ncCDF4 class
nc_attrs, nc_dims, nc_vars = ncdump(nc_fid)
# Extract data from NetCDF file
lats = nc_fid.variables['lat'][:]  # extract/copy the data
lons = nc_fid.variables['lon'][:]
time = nc_fid.variables['time'][:]
tag = nc_fid.variables['tag'][:]  # shape is time, lat, lon as shown above

nc_p = '../p/p.nc'  # Your filename
nc_fid = Dataset(nc_p, 'r')  # Dataset is the class behavior to open the file
                             # and create an instance of the ncCDF4 class
nc_attrs, nc_dims, nc_vars = ncdump(nc_fid)

p = nc_fid.variables['p'][:]  # shape is time, lat, lon as shown above

Этот код возвращает :

NetCDF Global Attributes:
NetCDF dimension information:
        Name: time
                size: 365
                type: dtype('float64')
                axis: u'T'
                calendar: u'standard'
                standard_name: u'time'
                units: u'hours since 1800-01-01 00:00'
        Name: lat
                size: 287
                type: dtype('float64')
                long_name: u'latitude'
                units: u'degrees_north'
                standard_name: u'latitude'
                axis: u'Y'
        Name: lon
                size: 612
                type: dtype('float64')
                long_name: u'longitude'
                units: u'degrees_east'
                standard_name: u'longitude'
                axis: u'X'
NetCDF variable information:
        Name: tag
                dimensions: (u'time', u'lat', u'lon')
                size: 64110060
                type: dtype('int32')

Я играл с функцией pandas groupby, но пока не нашел что-то, что подходит для моего примера.

1 Ответ

0 голосов
/ 01 апреля 2020

Я нашел решение, которое работает быстро. Проверяя результаты, они верны.

Используя xarray, чтобы открыть данные, я затем преобразовал данные в фрейм данных. После этого я мог использовать pandas groupby для вычисления.

from pylab import *
import numpy as np
import pandas as pd
import xarray as xr
import netCDF4

# Open data with xarray
dt = xr.open_mfdataset(['../tag.nc', '../p/p.nc'], combine='by_coords')

# Convert to data frame
dtdf = dt.to_dataframe()

dm = {'p': ['mean']}
mean = dtdf.groupby('tag').agg(dm)
mean.columns = ['_'.join(col) for col in mean.columns.values]
p_mean = mean.loc[1:, 'p_mean']
...