问题描述
我想使用 metpy
来计算使用 ERA5 每小时再分析数据的近地表(即 2m)比湿度。我昨天刚刚通过 pip 在本地安装了 metpy
,所以我假设我的代码是最新的。我的问题是我一直遇到以下错误。
这是我目前的代码:
# 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,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,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
提前致谢。
解决方法
看来 units.Quantity
无法处理 Xarray 对象。取而代之的是 xarray.DataArray
对象具有 Xarray.DataArray.metpy.quantify
方法来将数据转换为metpy 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 格式,因此这应该可以工作。如果没有,也许 Xarray 特定 Metpy 功能页面上的“非 CF 兼容数据集”部分可能会有所帮助:https://unidata.github.io/MetPy/latest/tutorials/xarray_tutorial.html
,您遇到的问题之一是 xr.open_dataset()
的结果是 Dataset
,而不是 DataArray
,这是您真正想要用于 MetPy 计算的功能。拥有这些之后,MetPy 应该能够自动处理 DataArray
的单位元数据,例如:
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)