Ошибки при использовании metpy для расчета удельной влажности

Я хотел бы использовать его для расчета удельной влажности приповерхностного слоя (например, 2 м) с использованием данных ежечасного реанализа ERA5. Я только что установил вчера локально через pip, поэтому предполагаю, что мой код обновлен. Моя проблема в том, что я продолжаю сталкиваться с ошибками, указанными ниже.

Вот мой код на данный момент:

      # import modules
import numpy as np
import xarray as xr
from metpy.units import units
import metpy.calc as mpcalc

# read data
d2m = xr.open_dataset('netcdf/ERA5_dewpt2m_1992.nc')
sp = xr.open_dataset('netcdf/ERA5_pres_1992.nc')

# assign units (approach 1)
#d2m = d2m*units.kelvin
#sp = sp*units.pascal

# assign units (approach 2)
d2m = units.Quantity(d2m, "kelvin")
sp = units.Quantity(sp, "pascal")

# calculate specific humidity
aqh2m = mpcalc.specific_humidity_from_dewpoint(sp, d2m)

Если я проигнорирую шаг «единицы», то функция конечно же жалуется на отсутствие единиц. Обратите внимание, что я пробовал два разных подхода к обработке единиц, описанных выше, но ни один из них не работает.

Если я попробую этот подход:

      # assign units (approach 1)
d2m = d2m*units.kelvin
sp = sp*units.pascal

# calculate specific humidity
aqh2m = mpcalc.specific_humidity_from_dewpoint(sp, d2m)

то я получаю следующую ошибку:

      ValueError: This function changed in 1.0--double check that the function is being called properly.
`specific_humidity_from_dewpoint` given arguments with incorrect units: `pressure` requires "[pressure]" but given "none", `dewpoint` requires "[temperature]" but given "none"
Any variable `x` can be assigned a unit as follows:
    from metpy.units import units
    x = units.Quantity(x, "m/s")

Однако, если я использую подход к назначению единиц, предложенный в сообщении об ошибке, то есть:

      # assign units (approach 2)
d2m = units.Quantity(d2m, "kelvin")
sp = units.Quantity(sp, "pascal")

# calculate specific humidity
aqh2m = mpcalc.specific_humidity_from_dewpoint(sp, d2m)

тогда я просто получаю другое сообщение об ошибке:

      ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-86573b0b8029> in <module>()
----> 1 d2m = units.Quantity(d2m, "kelvin")
      2 sp = units.Quantity(sp, "pascal")
      3 
      4 # calculate specific humidity
      5 aqh2m = mpcalc.specific_humidity_from_dewpoint(sp, d2m)

~/.local/lib/python3.6/site-packages/pint/quantity.py in __new__(cls, value, units)
    201     def __new__(cls, value, units=None):
    202         if is_upcast_type(type(value)):
--> 203             raise TypeError(f"Quantity cannot wrap upcast type {type(value)}")
    204         elif units is None:
    205             if isinstance(value, str):

TypeError: Quantity cannot wrap upcast type xarray.core.dataset.Dataset

Что мне делать? Я не знаю, куда идти дальше. Будем признательны за любые советы / рекомендации, которые вы можете предоставить.

К вашему сведению, вот версии моих различных модулей. Я перечислю их все, так как я не уверен, что metpy использует внутренне для поддержки юнита:

  • Python 3.6.3
  • numpy 1.19.5
  • xarray 0.16.2
  • панды 1.1.5
  • пинта 0,17
  • дворняжка 1.4.0
  • pyproj 3.0.1
  • matplotlib 2.1.2
  • черты 4.3.2
  • scipy 1.0.0

Заранее спасибо.

2 ответа

Похоже, что units.Quantityне может обрабатывать объекты Xarray. Вместо xarray.DataArray объекты имеют Xarray.DataArray.metpy.quantify метод превращения данных в метипы pint.Quantity(обратите внимание, что это загружает в память массивы, не относящиеся к dask). Это переместит единицу измерения из атрибута в данные.

Вы можете пойти как:

      # import modules
import numpy as np
import xarray as xr
from metpy.units import units
import metpy.calc as mpcalc

# read data
d2m = xr.open_dataset('netcdf/ERA5_dewpt2m_1992.nc')
sp = xr.open_dataset('netcdf/ERA5_pres_1992.nc')

# assign units
d2m = d2m.metpy.quantify()
sp = sp.metpy.quantify()

# calculate specific humidity
aqh2m = mpcalc.specific_humidity_from_dewpoint(sp, d2m)

Я ожидаю, что ваши данные ERA5 будут отформатированы в соответствии с CF, так что это должно работать. Если нет, возможно, вам может помочь раздел «Наборы данных, не совместимые с CF» на странице, посвященной функциям Metpy, специфичным для Xarray: https://unidata.github.io/MetPy/latest/tutorials/xarray_tutorial.html

Одна из ваших проблем заключается в том, что результат xr.open_dataset() это Dataset, а не a, с которым вы действительно хотите работать для расчетных функций MetPy. Как только они у вас появятся, MetPy сможет автоматически обрабатывать DataArrays с метаданными объекта, например:

      import xarray as xr
import metpy.calc as mpcalc

# read data
d2m_ds = xr.open_dataset('netcdf/ERA5_dewpt2m_1992.nc')
sp_ds = xr.open_dataset('netcdf/ERA5_pres_1992.nc')

# Pull out DataArrays and ask MetPy to parse CF metadata
d2m_arr = d2m_ds.metpy.parse_cf('dewpt2m')
sp_arr = sp_ds.metpy.parse_cf('press')

# calculate specific humidity
aqh2m = mpcalc.specific_humidity_from_dewpoint(sp_arr, d2m_arr)
Другие вопросы по тегам