我有一个x数组数据集,它有不规则的纬度和经度坐标。我的目标是在最接近某个lat/lon的点上找到变量的值。
由于x和y维度不是lat/lon值,因此在这种情况下,ds.sel()方法本身似乎无法使用。是否有以x数组为中心的方法,通过引用多维lat/lon维度来定位最近期望的lat/lon点?例如,我想取出最近的lat=21.2和lon=-122.68的速度值。
下面是一个示例数据集..。
lats = np.array([[21.138  , 21.14499, 21.15197, 21.15894, 21.16591],
                 [21.16287, 21.16986, 21.17684, 21.18382, 21.19079],
                 [21.18775, 21.19474, 21.20172, 21.2087 , 21.21568],
                 [21.21262, 21.21962, 21.22661, 21.23359, 21.24056],
                 [21.2375 , 21.2445 , 21.25149, 21.25848, 21.26545]])  
lons = np.array([[-122.72   , -122.69333, -122.66666, -122.63999, -122.61331],
                 [-122.7275 , -122.70082, -122.67415, -122.64746, -122.62078],
                 [-122.735  , -122.70832, -122.68163, -122.65494, -122.62825],
                 [-122.7425 , -122.71582, -122.68912, -122.66243, -122.63573],
                 [-122.75001, -122.72332, -122.69662, -122.66992, -122.64321]])
speed = np.array([[10.934007, 10.941321, 10.991583, 11.063932, 11.159435],
                  [10.98778 , 10.975482, 10.990983, 11.042522, 11.131154],
                  [11.013505, 11.001573, 10.997754, 11.03566 , 11.123781],
                  [11.011163, 11.000227, 11.010223, 11.049   , 11.1449  ],
                  [11.015698, 11.026604, 11.030653, 11.076904, 11.201464]])
ds = xarray.Dataset({'SPEED':(('x', 'y'),speed)},
                    coords = {'latitude': (('x', 'y'), lats),
                              'longitude': (('x', 'y'), lons)},
                    attrs={'variable':'Wind Speed'})ds值
<xarray.Dataset>
Dimensions:    (x: 5, y: 5)
Coordinates:
    latitude   (x, y) float64 21.14 21.14 21.15 21.16 ... 21.25 21.26 21.27
    longitude  (x, y) float64 -122.7 -122.7 -122.7 ... -122.7 -122.7 -122.6
Dimensions without coordinates: x, y
Data variables:
SPEED      (x, y) float64 10.93 10.94 10.99 11.06 ... 11.03 11.03 11.08 11.2
Attributes:
    variable:  Wind Speed同样,ds.sel(latitude=21.2, longitude=-122.68)无法工作,因为纬度和经度不是数据集维度。
发布于 2019-11-11 10:22:16
我喜欢@blaylockbk给出的答案,但我无法用最短的距离来计算数据点。下面,我提供了一种仅使用Pythagoras的替代方法,并提供了一种网格化数据集ds的方法。为了不混淆数据集中的(x,y)和x,y大地坐标,我把它们重命名为(i,j)。
import numpy as np
import xarray
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
lats = np.array([[21.138, 21.14499, 21.15197, 21.15894, 21.16591],
                 [21.16287, 21.16986, 21.17684, 21.18382, 21.19079],
                 [21.18775, 21.19474, 21.20172, 21.2087, 21.21568],
                 [21.21262, 21.21962, 21.22661, 21.23359, 21.24056],
                 [21.2375, 21.2445, 21.25149, 21.25848, 21.26545]])
lons = np.array([[-122.72, -122.69333, -122.66666, -122.63999, -122.61331],
                 [-122.7275, -122.70082, -122.67415, -122.64746, -122.62078],
                 [-122.735, -122.70832, -122.68163, -122.65494, -122.62825],
                 [-122.7425, -122.71582, -122.68912, -122.66243, -122.63573],
                 [-122.75001, -122.72332, -122.69662, -122.66992, -122.64321]])
speed = np.array([[10.934007, 10.941321, 10.991583, 11.063932, 11.159435],
                  [10.98778, 10.975482, 10.990983, 11.042522, 11.131154],
                  [11.013505, 11.001573, 10.997754, 11.03566, 11.123781],
                  [11.011163, 11.000227, 11.010223, 11.049, 11.1449],
                  [11.015698, 11.026604, 11.030653, 11.076904, 11.201464]])
ds = xarray.Dataset({'SPEED': (('i', 'j'), speed)},
                    coords={'latitude': (('i', 'j'), lats),
                            'longitude': (('i', 'j'), lons)},
                    attrs={'variable': 'Wind Speed'})
lat_min = float(np.min(ds.latitude))
lat_max = float(np.max(ds.latitude))
lon_min = float(np.min(ds.longitude))
lon_max = float(np.max(ds.longitude))
margin = 0.02
fig, ((ax1, ax2)) = plt.subplots(nrows=1, ncols=2, figsize=(12, 5))
ax1.set_xlim(lat_min - margin, lat_max + margin)
ax1.set_ylim(lon_min - margin, lon_max + margin)
ax1.axis('equal')
ds.SPEED.plot(ax=ax1, x='latitude', y='longitude', cmap=plt.cm.jet)
ax1.scatter(ds.latitude, ds.longitude, color='black')
# find nearest_point for a requested lat/ lon
lat_requested = 21.22
lon_requested = -122.68
d_lat = ds.latitude - lat_requested
d_lon = ds.longitude - lon_requested
r2_requested = d_lat**2 + d_lon**2
i_j_loc = np.where(r2_requested == np.min(r2_requested))
nearest_point = ds.sel(i=i_j_loc[0], j=i_j_loc[1])
# Plot nearest point in the array red# Plot nearest point in the array red
ax1.scatter(lat_requested, lon_requested, color='green')
ax1.text(lat_requested, lon_requested, 'requested')
ax1.scatter(nearest_point.latitude, nearest_point.longitude, color='red')
ax1.text(nearest_point.latitude, nearest_point.longitude, 'nearest')
ax1.set_title(f'speed at nearest point: {float(nearest_point.SPEED.data):.2f}')
# define grid from the dataset
num_points = 100
lats_i = np.linspace(lat_min, lat_max, num_points)
lons_i = np.linspace(lon_min, lon_max, num_points)
# grid and contour the data.
speed_i = griddata((ds.latitude.values.flatten(), ds.longitude.values.flatten()),
                   ds.SPEED.values.flatten(),
                   (lats_i[None, :], lons_i[:, None]), method='cubic')
ax2.set_xlim(lat_min - margin, lat_max + margin)
ax2.set_ylim(lon_min - margin, lon_max + margin)
ax2.axis('equal')
ax2.set_title(f'griddata test {num_points} points')
ax2.contour(lats_i, lons_i, speed_i, 15, linewidths=0.5, colors='k')
contour = ax2.contourf(lats_i, lons_i, speed_i, 15, cmap=plt.cm.jet)
plt.colorbar(contour, ax=ax2)
# plot data points and labels
ax2.scatter(ds.latitude, ds.longitude, marker='o', c='b', s=5)
for i, (lat, lon) in enumerate(zip(ds.latitude.values.flatten(),
                                   ds.longitude.values.flatten())):
    text_label = f'{ds.SPEED.values.flatten()[i]:0.2f}'
    ax2.text(lat, lon, text_label)
# Plot nearest point in the array red
ax2.scatter(lat_requested, lon_requested, color='green')
ax2.text(lat_requested, lon_requested, 'requested')
ax2.scatter(nearest_point.latitude, nearest_point.longitude, color='red')
plt.subplots_adjust(wspace=0.2)
plt.show()结果:

https://stackoverflow.com/questions/58758480
复制相似问题