如何一次计算指定坐标和二维 xarray 数据之间的欧几里得距离
How to calculate the euclidian distance between a specified coordinate and 2-d xarray data at once
如何一次计算指定坐标与二维xarray数据之间的欧氏距离(无for循环)?
我写了下面的代码。但是如果数据量变大,这个脚本就会显得很慢。如果没有 for 循环,我怎么能做同样的事情?
import math
import xarray as xr
import numpy as np
#set the specified lat, lon
specific_lat = 15
specific_lon = 65
#create sample xarry data
lat = [0, 10, 20]
lon = [50, 60, 70, 80]
#sample data
test_data = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
#to xarray
data_xarray = xr.DataArray(test_data, dims=("lat","lon"), coords={"lat":lat, "lon":lon})
#calculate distance
xarray_distance = data_xarray #copy
xarray_distance.data[:,:] = 0.0 #zero-reset
for lat in data_xarray.lat.data:
for lon in data_xarray.lon.data:
xarray_distance.loc[{"lat":lat,"lon":lon}] = math.sqrt((lat- spec_lat)**2 + (lon - spec_lon)**2)
print(xarray_distance)
#<xarray.DataArray (lat: 3, lon: 4)>
#array([[21, 15, 15, 21],
# [15, 7, 7, 15],
# [15, 7, 7, 15]])
#Coordinates:
# * lat (lat) int64 0 10 20
# * lon (lon) int64 50 60 70 80
首先,xarray_distance = data_xarray
不复制对象。两个名称将看到相同的对象以及对它发生的任何更改。对于副本,您想执行 data_xarray.copy()
.
现在,您不想使用循环,而是想利用 numpy 的矢量化和广播一次性创建二维数组并将其设置为您的 xarray 对象数据。
lat = np.array(lat)
lon = np.array(lon)
xarray_distance.data = np.sqrt((lat - spec_lat)[:,None]**2 + ((lon - spec_lon)**2))
结果
<xarray.DataArray (lat: 3, lon: 4)>
array([[21.21320344, 15.8113883 , 15.8113883 , 21.21320344],
[15.8113883 , 7.07106781, 7.07106781, 15.8113883 ],
[15.8113883 , 7.07106781, 7.07106781, 15.8113883 ]])
Coordinates:
* lat (lat) int32 0 10 20
* lon (lon) int32 50 60 70 80
您会注意到数据是浮点数,考虑到它们代表什么,它们可能应该是浮点数。如果你想要它们在数据的原始类型中,替换为
xarray_distance.data = np.sqrt(...)
和
xarray_distance.data = np.sqrt(...).astype(xarray_distance.data.dtype)
您需要通过以下公式计算余弦权重:(lon - spec_lon)**2
等于 (cos(lat)*(lon - spec_lon))
如何一次计算指定坐标与二维xarray数据之间的欧氏距离(无for循环)?
我写了下面的代码。但是如果数据量变大,这个脚本就会显得很慢。如果没有 for 循环,我怎么能做同样的事情?
import math
import xarray as xr
import numpy as np
#set the specified lat, lon
specific_lat = 15
specific_lon = 65
#create sample xarry data
lat = [0, 10, 20]
lon = [50, 60, 70, 80]
#sample data
test_data = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
#to xarray
data_xarray = xr.DataArray(test_data, dims=("lat","lon"), coords={"lat":lat, "lon":lon})
#calculate distance
xarray_distance = data_xarray #copy
xarray_distance.data[:,:] = 0.0 #zero-reset
for lat in data_xarray.lat.data:
for lon in data_xarray.lon.data:
xarray_distance.loc[{"lat":lat,"lon":lon}] = math.sqrt((lat- spec_lat)**2 + (lon - spec_lon)**2)
print(xarray_distance)
#<xarray.DataArray (lat: 3, lon: 4)>
#array([[21, 15, 15, 21],
# [15, 7, 7, 15],
# [15, 7, 7, 15]])
#Coordinates:
# * lat (lat) int64 0 10 20
# * lon (lon) int64 50 60 70 80
首先,xarray_distance = data_xarray
不复制对象。两个名称将看到相同的对象以及对它发生的任何更改。对于副本,您想执行 data_xarray.copy()
.
现在,您不想使用循环,而是想利用 numpy 的矢量化和广播一次性创建二维数组并将其设置为您的 xarray 对象数据。
lat = np.array(lat)
lon = np.array(lon)
xarray_distance.data = np.sqrt((lat - spec_lat)[:,None]**2 + ((lon - spec_lon)**2))
结果
<xarray.DataArray (lat: 3, lon: 4)>
array([[21.21320344, 15.8113883 , 15.8113883 , 21.21320344],
[15.8113883 , 7.07106781, 7.07106781, 15.8113883 ],
[15.8113883 , 7.07106781, 7.07106781, 15.8113883 ]])
Coordinates:
* lat (lat) int32 0 10 20
* lon (lon) int32 50 60 70 80
您会注意到数据是浮点数,考虑到它们代表什么,它们可能应该是浮点数。如果你想要它们在数据的原始类型中,替换为
xarray_distance.data = np.sqrt(...)
和
xarray_distance.data = np.sqrt(...).astype(xarray_distance.data.dtype)
您需要通过以下公式计算余弦权重:(lon - spec_lon)**2
等于 (cos(lat)*(lon - spec_lon))