我不确定如何在卫星数据中采用u和v分量的导数。我以为我可以用这种方式使用numpy.gradient:
from netCDF4 import Dataset
import numpy as np
import matplotlib.pyplot as plt
GridSat = Dataset('analysis_20040713_v11l30flk.nc4','r',format='NETCDF4')
missing_data = -9999.0
lat = GridSat.variables['lat']
lat = lat[:]
lat[np.where(lat==missing_data)] = np.nan
lat[np.where(lat > 90.0)] = np.nan
lon = GridSat.variables['lon']
lon = lon[:]
lon[np.where(lon==missing_data)] = np.nan
uwind_data = GridSat.variables['uwnd']
uwind = GridSat.variables['uwnd'][:]
uwind_sf = uwind_data.scale_factor
uwind_ao = uwind_data.add_offset
miss_uwind = uwind_data.missing_value
uwind[np.where(uwind==miss_uwind)] = np.nan
vwind_data = GridSat.variables['vwnd']
vwind = GridSat.variables['vwnd'][:]
vwind_sf = vwind_data.scale_factor
vwind_ao = vwind_data.add_offset
miss_vwind = vwind_data.missing_value
vwind[np.where(vwind==miss_vwind)] = np.nan
uwind = uwind[2,:,:]
vwind = vwind[2,:,:]
dx = 28400.0 # meters calculated from the 0.25 degree spatial gridding
dy = 28400.0 # meters calculated from the 0.25 degree spatial gridding
dv_dx, dv_dy = np.gradient(vwind, [dx,dy])
du_dx, du_dy = np.gradient(uwind, [dx,dy])
File "<ipython-input-229-c6a5d5b09224>", line 1, in <module>
np.gradient(vwind, [dx,dy])
File "/Users/anaconda/lib/python2.7/site-packages/nump/lib/function_base.py", line 1040, in gradient
out /= dx[axis]
ValueError: operands could not be broadcast together with shapes (628,1440) (2,) (628,1440)
老实说,我不知道如何计算(0.25x0.25)度间距的卫星数据的中心差异。我不认为我的dx和dy也是正确的。如果有人对接近卫星数据中的这些类型的计算有一个好主意,我将非常感激。谢谢!!
答案 0 :(得分:1)
在@moarningsun
评论时,更改您致电np.gradient
的方式应更正ValueError
dv_dx, dv_dy = np.gradient(vwind, dx,dy)
du_dx, du_dy = np.gradient(uwind, dx,dy)
如何从文件中获取vwind
并不是特别重要,尤其是因为我们无法访问该文件。虽然我们可以从错误消息中猜出,但vwind
的形状本来是有用的。错误中对(2,)
数组的引用是[dx,dy]
。当您收到broadcasting
错误时,请检查各种参数的形状。
np.gradient
代码是直截了当的,只是因为它可以处理1,2,3d和更高的数据。基本上它做了像
(z[:,2:]-z[:,:-2])/2
(z[2:,:]-z[:-2,:])/2
表示内部值,1表示步骤表示边界值。
我将从渐变(或不是)中获得curl
的问题留给其他人。
答案 1 :(得分:0)
如上所述,存在必须实现某种离散卷曲运算符的问题。这可能是大气物理学中常见的问题所以你可以查看一本教科书。
另一种方法可能是将样条拟合到数据,以便您可以使用连续操作。例如
bspl = scipy.interpolate.SmoothBivariateSpline(x,y,z,s=0)
s
这是一个你应该玩的平滑因素;如果数据非常精确s=0
会得到最好的结果;如果他们有大量的分散,你会想要一些平滑。现在你可以直接计算卷曲:
curl = bspl.integral(x0,x1,y0,y1) / ((x1-x0)*(y1-y0))
编辑: 上面的表达式没有给出卷曲,但基本的想法是合理的。
答案 2 :(得分:-1)
下面的代码可以在Matlab wind数据集上运行,文件wind.mat位于
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
import scipy.io as sio
def curl(x,y,z,u,v,w):
dx = x[0,:,0]
dy = y[:,0,0]
dz = z[0,0,:]
dummy, dFx_dy, dFx_dz = np.gradient (u, dx, dy, dz, axis=[1,0,2])
dFy_dx, dummy, dFy_dz = np.gradient (v, dx, dy, dz, axis=[1,0,2])
dFz_dx, dFz_dy, dummy = np.gradient (w, dx, dy, dz, axis=[1,0,2])
rot_x = dFz_dy - dFy_dz
rot_y = dFx_dz - dFz_dx
rot_z = dFy_dx - dFx_dy
l = np.sqrt(np.power(u,2.0) + np.power(v,2.0) + np.power(w,2.0));
m1 = np.multiply(rot_x,u)
m2 = np.multiply(rot_y,v)
m3 = np.multiply(rot_z,w)
tmp1 = (m1 + m2 + m3)
tmp2 = np.multiply(l,2.0)
av = np.divide(tmp1, tmp2)
return rot_x, rot_y, rot_z, av
mat = sio.loadmat('wind.mat')
x = mat['x']; y = mat['y']; z = mat['z']
u = mat['u']; v = mat['v']; w = mat['w']
rot_x, rot_y, rot_z, av = curl(x,y,z,u,v,w)
# plot a small area of the wind
i=5;j=7;k=8;S = 3
x1 = x[i-S:i+S, j-S:j+S, k-S:k+S];
y1 = y[i-S:i+S, j-S:j+S, k-S:k+S];
z1 = z[i-S:i+S, j-S:j+S, k-S:k+S];
u1 = u[i-S:i+S, j-S:j+S, k-S:k+S];
v1 = v[i-S:i+S, j-S:j+S, k-S:k+S];
w1 = w[i-S:i+S, j-S:j+S, k-S:k+S];
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.view_init(elev=47, azim=-145)
ax.quiver(x1, y1, z1, u1, v1, w1, length=0.05, color = 'black')
i=5;j=7;k=8;
x0=x[i,j,k]
y0=y[i,j,k]
z0=z[i,j,k]
cx0=rot_x[i,j,k]
cy0=rot_y[i,j,k]
cz0=rot_z[i,j,k]
ax.quiver(x0, y0, z0, 0, cy0, cz0, length=1.0, color = 'blue')
plt.show()