Расчет завихренности для нескольких вертикальных уровней в MetPy - PullRequest
2 голосов
/ 05 марта 2019

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

Вот код; Я использовал пример для сечений от https://unidata.github.io/MetPy/latest/examples/cross_section.html#sphx-glr-examples-cross-section-py.

import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import numpy as np
import xarray as xr

import metpy.calc as mpcalc
from metpy.cbook import get_test_data
from metpy.interpolate import cross_section
from metpy.units import units

data = xr.open_dataset(get_test_data('narr_example.nc', False))
data = data.metpy.parse_cf().squeeze()

data_crs = data['Temperature'].metpy.cartopy_crs
lat = data['lat']
lon = data['lon']
f = mpcalc.coriolis_parameter(lat)
dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat, initstring=data_crs.proj4_init)

Затем выполняется расчет завихренности.

vort = mpcalc.vorticity(data['u_wind'], data['v_wind'], dx, dy)

След:

Traceback (most recent call last):
  File "E:\Временные файлы\cross_section (1).py", line 63, in <module>
    vort = mpcalc.vorticity(data['u_wind'], data['v_wind'], dx, dy)
  File "C:\ProgramData\Miniconda3\lib\site-packages\metpy\xarray.py", line 436, in wrapper
    return func(*args, **kwargs)
  File "C:\ProgramData\Miniconda3\lib\site-packages\metpy\calc\kinematics.py", line 60, in wrapper
    ret = func(*args, **kwargs)
  File "C:\ProgramData\Miniconda3\lib\site-packages\metpy\calc\kinematics.py", line 121, in vorticity
    dudy = first_derivative(u, delta=dy, axis=-2)
  File "C:\ProgramData\Miniconda3\lib\site-packages\metpy\calc\tools.py", line 920, in wrapper
    return preprocess_xarray(func)(f, **kwargs)
  File "C:\ProgramData\Miniconda3\lib\site-packages\metpy\xarray.py", line 436, in wrapper
    return func(*args, **kwargs)
  File "C:\ProgramData\Miniconda3\lib\site-packages\metpy\calc\tools.py", line 1014, in first_derivative
    combined_delta = delta[tuple(delta_slice0)] + delta[tuple(delta_slice1)]
  File "C:\ProgramData\Miniconda3\lib\site-packages\pint\quantity.py", line 1400, in __getitem__
    value = self._magnitude[key]
IndexError: too many indices for array

Я абсолютно застрял. Поиск в «метаповременных вычислениях нескольких уровней» (без реальных кавычек) не дает релевантных результатов. Док говорит:

metpy.calc.vorticity(u, v, dx, dy)[source]
Calculate the vertical vorticity of the horizontal wind.

Parameters: 
u ((M, N) ndarray) – x component of the wind
v ((M, N) ndarray) – y component of the wind
dx (float or ndarray) – The grid spacing(s) in the x-direction. If an array, there should be one item less than the size of u along the applicable axis.
dy (float or ndarray) – The grid spacing(s) in the y-direction. If an array, there should be one item less than the size of u along the applicable axis.
dim_order (str or None, optional) – The ordering of dimensions in passed in arrays. Can be one of None, 'xy', or 'yx'. 'xy' indicates that the dimension corresponding to x is the leading dimension, followed by y. 'yx' indicates that x is the last dimension, preceded by y. None indicates that the default ordering should be assumed, which is ‘yx’. Can only be passed as a keyword argument, i.e. func(…, dim_order=’xy’).
Returns:    
(M, N) ndarray – vertical vorticity

Я пришел к выводу, что вход может иметь более 2-х измерений, но 3-х мерный ввод (как и в моем случае) дает ошибки. Что можно сделать, чтобы исправить их?

Я абсолютно новичок в Python, поэтому мог допустить глупую ошибку.

1 Ответ

2 голосов
/ 06 марта 2019

К сожалению, появившееся сообщение об ошибке не очень полезно в этом случае, если вы не знаете, что искать!

Проблема с вызовом функции vorticity в вашем примере заключается в том, что размерность ваших входных переменных не совпадает. data['u_wind'] и data['v_wind'] являются трехмерными массивами с формой (29, 118, 292), но dx и dy, так как они были вычислены из lat_lon_grid_deltas, являются двумерными массивами с формами (118, 291) и (117, 292) соответственно. Итак, нам нужно получить массивы, которые передаются соответствующим образом ... Есть много разных способов сделать это, но я бы порекомендовал два варианта:

Вариант 1: ручное вещание

Поскольку «дополнительное» измерение, в котором отсутствуют dx и dy, является первым измерением (по вертикали), мы можем просто сделать dx и dy в правильно выровненных трехмерных массивах, вставив размер- одно ведущее измерение:

dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat, initstring=data_crs.proj4_init)
dx = dx[None, :]
dy = dy[None, :]

vort = mpcalc.vorticity(data['u_wind'], data['v_wind'], dx, dy)

Вариант 2: Используйте вспомогательную функцию grid_deltas_from_dataarray()

MetPy также имеет вспомогательную функцию, позволяющую легко извлекать дельты сетки из xarray DataArray. Это также обеспечивает правильное вещание, поэтому вам не придется делать это самостоятельно. Используя его в вашем примере, это будет:

dx, dy = mpcalc.grid_deltas_from_dataarray(data['u_wind'])

vort = mpcalc.vorticity(data['u_wind'], data['v_wind'], dx, dy)
...