使用Python,np.gradient计算u和v的风散度

时间:2015-09-02 10:41:41

标签: python numpy netcdf

我是Python的新手,目前正试图复制我之前使用GrADs的情节等。我想根据netCDF气候模型文件,使用u和v风场(仅根据特定湿度q来缩放)来计算每个网格框的分歧。

从无休止的搜索中我知道我需要使用np.gradient和np.sum的某种组合,但无法找到正确的组合。我只知道要手工完成它,计算就是 divg = dqu / dx + dqv / dy 我知道下面的内容不对,但这是我迄今为止最好的......

nc = Dataset(ifile)
q = np.array(nc.variables['hus'][0,:,:])
u = np.array(nc.variables['ua'][0,:,:])
v = np.array(nc.variables['va'][0,:,:])
lon=nc.variables['lon'][:]
lat=nc.variables['lat'][:]

qu = q*u
qv = q*v  

dqu/dx, dqu/dy = np.gradient(qu, [dx, dy])
dqv/dx, dqv/dy = np.gradient(qv, [dx, dy])

divg = np.sum(dqu/dx, dqv/dy)

这会产生错误' SyntaxError:无法分配给运营商'。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

尝试类似:

dqu_dx, dqu_dy = np.gradient(qu, [dx, dy])
dqv_dx, dqv_dy = np.gradient(qv, [dx, dy])

你不能分配给python中的任何操作;其中任何一个都是语法错误:

a + b = 3
a * b = 7
# or, in your case:
a / b = 9

<强>更新

关注Pinetwig的评论:a/b不是有效的标识符名称;它是(运算符的返回值)。

答案 1 :(得分:1)

尝试删除[dx,dy]。

   [dqu_dx, dqu_dy] = np.gradient(qu)
   [dqv_dx, dqv_dy] = np.gradient(qv)

还要指出你是否正在重建情节。渐变在1.82和1.9之间变化。这对于在python中重建matlab图有效,因为1.82是matlab方法。我不确定这与GrAD有什么关系。以下是两者的措辞。

1.82

“使用内部中心差异计算渐变     和边界的第一个差异。因此返回的梯度具有     形状与输入数组相同。“

1.9

“使用内部二阶精确中心差异计算梯度,边界处的第一差异或二阶精确单边(向前或向后)差异。返回的渐变因此具有与输入数组相同的形状。“

1.82的渐变功能就在这里。

def gradient(f, *varargs):
"""
Return the gradient of an N-dimensional array.

The gradient is computed using central differences in the interior
and first differences at the boundaries. The returned gradient hence has
the same shape as the input array.

Parameters
----------
f : array_like
  An N-dimensional array containing samples of a scalar function.
`*varargs` : scalars
  0, 1, or N scalars specifying the sample distances in each direction,
  that is: `dx`, `dy`, `dz`, ... The default distance is 1.


Returns
-------
gradient : ndarray
  N arrays of the same shape as `f` giving the derivative of `f` with
  respect to each dimension.

Examples
--------
>>> x = np.array([1, 2, 4, 7, 11, 16], dtype=np.float)
>>> np.gradient(x)
array([ 1. ,  1.5,  2.5,  3.5,  4.5,  5. ])
>>> np.gradient(x, 2)
array([ 0.5 ,  0.75,  1.25,  1.75,  2.25,  2.5 ])

>>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=np.float))
[array([[ 2.,  2., -1.],
       [ 2.,  2., -1.]]),
array([[ 1. ,  2.5,  4. ],
       [ 1. ,  1. ,  1. ]])]

"""
  f = np.asanyarray(f)
  N = len(f.shape)  # number of dimensions
  n = len(varargs)
  if n == 0:
      dx = [1.0]*N
  elif n == 1:
      dx = [varargs[0]]*N
  elif n == N:
      dx = list(varargs)
  else:
      raise SyntaxError(
              "invalid number of arguments")

# use central differences on interior and first differences on endpoints

  outvals = []

# create slice objects --- initially all are [:, :, ..., :]
  slice1 = [slice(None)]*N
  slice2 = [slice(None)]*N
  slice3 = [slice(None)]*N

  otype = f.dtype.char
  if otype not in ['f', 'd', 'F', 'D', 'm', 'M']:
      otype = 'd'

# Difference of datetime64 elements results in timedelta64
  if otype == 'M' :
    # Need to use the full dtype name because it contains unit information
      otype = f.dtype.name.replace('datetime', 'timedelta')
  elif otype == 'm' :
    # Needs to keep the specific units, can't be a general unit
      otype = f.dtype

  for axis in range(N):
    # select out appropriate parts for this dimension
      out = np.empty_like(f, dtype=otype)
      slice1[axis] = slice(1, -1)
      slice2[axis] = slice(2, None)
      slice3[axis] = slice(None, -2)
    # 1D equivalent -- out[1:-1] = (f[2:] - f[:-2])/2.0
      out[slice1] = (f[slice2] - f[slice3])/2.0
      slice1[axis] = 0
      slice2[axis] = 1
      slice3[axis] = 0
    # 1D equivalent -- out[0] = (f[1] - f[0])
      out[slice1] = (f[slice2] - f[slice3])
      slice1[axis] = -1
      slice2[axis] = -1
      slice3[axis] = -2
    # 1D equivalent -- out[-1] = (f[-1] - f[-2])
      out[slice1] = (f[slice2] - f[slice3])

    # divide by step size
      outvals.append(out / dx[axis])

    # reset the slice object in this dimension to ":"
      slice1[axis] = slice(None)
      slice2[axis] = slice(None)
      slice3[axis] = slice(None)

  if N == 1:
      return outvals[0]
  else:
      return outvals

答案 2 :(得分:0)

如果您的网格是高斯网格且文件中的风名称是“u”和“v”,您还可以使用cdo直接计算分歧:

cdo uv2dv in.nc out.nc

有关详细信息,请参阅https://code.mpimet.mpg.de/projects/cdo/embedded/index.html#x1-6850002.13.2