在numpy数组中找到最近的xy点和第二个最近的条件
Finding nearest xy-point in numpy array and second nearest with condition
我的问题和线程Finding index of nearest point in numpy arrays of x and y coordinates中的问题一样,但是扩展了:
为了更好地可视化,这里有一张图片
(经过处理的图像,来自:by 112BKS - Eigenes WerkOriginal graph/Data from [.. ? ..], CC BY-SA 3.0, link to page):
一方面有数组datafield
。它由一个带有元素 [value x y]
的 numpy 数组组成。那是带有数字的蓝色细线(它们是 value
)。另一方面,在具有元素 [x y]
的 numpy 数组中存在数组 orangeline
。
我想做的是计算orangeline
中任何元素的value
。
我用绿色圆圈形象化了orangeline
中的一个具体元素。它的值可以用 datafield
中的两个元素进行插值,用三角形可视化。结果我得到绿色圆圈 value
介于 225 和 230 之间。
第一步:
为orangeline
中的每个元素查找datafield
中最接近的元素。
(In粉红色三角形的例子。)
第二步:
为 'orangeline' 中的每个元素查找 datafield
中最接近的元素,但与另一个 value
比第一步的那个。
(在例子中是棕色三角形。)
第三步: 根据两个已建立的值和到这些元素的距离,为 orangeline
中的每个元素插入 value
。
第一步可以用
解决
mytree = scipy.spatial.cKDTree(datafield[:, 1:3])
dist1, indexes1 = mytree.query(orangeline)
但现在我不知道如何为第二步过滤数据字段。有解决办法吗?
在 @unutbu 的评论的帮助下,我发现这个解决方案在 orangeline
未穿过字段的情况下也非常有效。
网格函数如下:
import matplotlib.mlab as mlab
import numpy as np
import scipy
def define_grid(rawdata):
xmin, xmax = np.amin(rawdata[:, 1]), np.amax(rawdata[:,1])
ymin, ymax = np.amin(rawdata[:, 2]), np.amax(rawdata[:,2])
x, y, z = rawdata[:, 1], rawdata[:, 2], rawdata[:, 0]
# Size of regular grid
ny, nx = (ymax - ymin), (xmax - xmin)
# Generate a regular grid to interpolate the data.
xi = np.linspace(xmin, xmax, nx)
yi = np.linspace(ymin, ymax, ny)
xi, yi = np.meshgrid(xi, yi)
# Interpolate using delaunay triangularization
zi = mlab.griddata(x,y,z,xi,yi)
return xi, yi, zi
def grid_as_array(xi,yi,zi):
xi_flat, yi_flat, zi_flat = np.ravel(xi), np.ravel(yi), np.ravel(zi)
# reduce arrays for faster calculation, take only every second element
xi_red, yi_red, zi_red = xi_flat[1::2], yi_flat[1::2], zi_flat[1::2]
# stack to array with elements [x y z], but there are z values that are 'nan'
xyz_with_nan = np.hstack((xi_red[:, np.newaxis], yi_red[:, np.newaxis],
zi_red[:, np.newaxis]))
# sort out those elements with 'nan'
xyz = xyz_with_nan[~np.isnan(xyz_with_nan).any(axis=1)]
return xyz
为 orangeline 中的值查找距网格最近点的另一个函数:
def closest_node(points, datafield):
mytree = scipy.spatial.cKDTree(datafield)
dist, indexes = mytree.query(points)
return indexes
现在代码:
# use function to create from the raw data an interpolated datafield
xi, yi, zi = define_grid(datafield)
# rearrange those values to bring them in the form of an array with [x y z]
xyz = grid_as_array(xi, yi, zi)
# search closest values from grid for the points of the orangeline
# orangeline_xy is the array with elements [x y]
indexes = self.closest_node(orangeline_xy, xyz[:,0:2])
# take z values from the grid which we found before
orangeline_z = xyz[indexes, 2]
# add those z values to the points of the orangeline
orangeline_xyz = np.hstack((orangeline_xy,orangeline_z[:, np.newaxis]))
我的问题和线程Finding index of nearest point in numpy arrays of x and y coordinates中的问题一样,但是扩展了:
为了更好地可视化,这里有一张图片
(经过处理的图像,来自:by 112BKS - Eigenes WerkOriginal graph/Data from [.. ? ..], CC BY-SA 3.0, link to page):
一方面有数组datafield
。它由一个带有元素 [value x y]
的 numpy 数组组成。那是带有数字的蓝色细线(它们是 value
)。另一方面,在具有元素 [x y]
的 numpy 数组中存在数组 orangeline
。
我想做的是计算orangeline
中任何元素的value
。
我用绿色圆圈形象化了orangeline
中的一个具体元素。它的值可以用 datafield
中的两个元素进行插值,用三角形可视化。结果我得到绿色圆圈 value
介于 225 和 230 之间。
第一步:
为orangeline
中的每个元素查找datafield
中最接近的元素。
(In粉红色三角形的例子。)
第二步:
为 'orangeline' 中的每个元素查找 datafield
中最接近的元素,但与另一个 value
比第一步的那个。
(在例子中是棕色三角形。)
第三步: 根据两个已建立的值和到这些元素的距离,为 orangeline
中的每个元素插入 value
。
第一步可以用
解决mytree = scipy.spatial.cKDTree(datafield[:, 1:3])
dist1, indexes1 = mytree.query(orangeline)
但现在我不知道如何为第二步过滤数据字段。有解决办法吗?
在 @unutbu 的评论的帮助下,我发现这个解决方案在 orangeline
未穿过字段的情况下也非常有效。
网格函数如下:
import matplotlib.mlab as mlab
import numpy as np
import scipy
def define_grid(rawdata):
xmin, xmax = np.amin(rawdata[:, 1]), np.amax(rawdata[:,1])
ymin, ymax = np.amin(rawdata[:, 2]), np.amax(rawdata[:,2])
x, y, z = rawdata[:, 1], rawdata[:, 2], rawdata[:, 0]
# Size of regular grid
ny, nx = (ymax - ymin), (xmax - xmin)
# Generate a regular grid to interpolate the data.
xi = np.linspace(xmin, xmax, nx)
yi = np.linspace(ymin, ymax, ny)
xi, yi = np.meshgrid(xi, yi)
# Interpolate using delaunay triangularization
zi = mlab.griddata(x,y,z,xi,yi)
return xi, yi, zi
def grid_as_array(xi,yi,zi):
xi_flat, yi_flat, zi_flat = np.ravel(xi), np.ravel(yi), np.ravel(zi)
# reduce arrays for faster calculation, take only every second element
xi_red, yi_red, zi_red = xi_flat[1::2], yi_flat[1::2], zi_flat[1::2]
# stack to array with elements [x y z], but there are z values that are 'nan'
xyz_with_nan = np.hstack((xi_red[:, np.newaxis], yi_red[:, np.newaxis],
zi_red[:, np.newaxis]))
# sort out those elements with 'nan'
xyz = xyz_with_nan[~np.isnan(xyz_with_nan).any(axis=1)]
return xyz
为 orangeline 中的值查找距网格最近点的另一个函数:
def closest_node(points, datafield):
mytree = scipy.spatial.cKDTree(datafield)
dist, indexes = mytree.query(points)
return indexes
现在代码:
# use function to create from the raw data an interpolated datafield
xi, yi, zi = define_grid(datafield)
# rearrange those values to bring them in the form of an array with [x y z]
xyz = grid_as_array(xi, yi, zi)
# search closest values from grid for the points of the orangeline
# orangeline_xy is the array with elements [x y]
indexes = self.closest_node(orangeline_xy, xyz[:,0:2])
# take z values from the grid which we found before
orangeline_z = xyz[indexes, 2]
# add those z values to the points of the orangeline
orangeline_xyz = np.hstack((orangeline_xy,orangeline_z[:, np.newaxis]))