Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 搜索numpy数组((x,y,z)…)以查找与最近的x,y匹配的z_Python_Numpy_Scipy_Interpolation - Fatal编程技术网

Python 搜索numpy数组((x,y,z)…)以查找与最近的x,y匹配的z

Python 搜索numpy数组((x,y,z)…)以查找与最近的x,y匹配的z,python,numpy,scipy,interpolation,Python,Numpy,Scipy,Interpolation,我有一个非常大的数组,类似于以下格式的高程数据: triplets = ((x0, y0, z0), (x1, y1, z1), ... , (xn, yn, zn)) 其中x,y,z都是以米为单位的浮点数。您可以创建与此格式相匹配的合适测试数据: x = np.arange(20, 40, dtype=np.float64) y = np.arange(30, 50, dtype=np.float64) z = np

我有一个非常大的数组,类似于以下格式的高程数据:

triplets = ((x0, y0, z0), 
            (x1, y1, z1), 
            ... ,
            (xn, yn, zn))
其中x,y,z都是以米为单位的浮点数。您可以创建与此格式相匹配的合适测试数据:

x = np.arange(20, 40, dtype=np.float64)
y = np.arange(30, 50, dtype=np.float64)
z = np.random.random(20) * 25.0
triplets = np.hstack((x, y, z)).reshape((len(x),3))
我希望能够有效地找到给定(x,y)对对应的z值。到目前为止,我的研究引出了更多的问题。以下是我得到的:

  • 遍历所有三元组:

    query = (a, b) # where a, b are the x and y coordinates we're looking for
    for i in triplets:
      if i[0] == query[0] and i[1] == query[1]:
        result = i[2]
    
    缺点:速度慢<代码>a、b必须存在,这是比较浮动的问题

  • 用于查找最近的:

    points = triplets[:,0:2] # drops the z column
    tree = cKDTree(points)
    idx = tree.query((a, b))[1] # this returns a tuple, we want the index
    query = tree.data[idx]
    result = triplets[idx, 2]
    
    缺点:返回最近点而不是插值

  • 根据评论使用:

    f = interp2d(x, y, z)
    result = f(a, b)
    
    缺点:不适用于大型数据集。我得到了溢出错误:在实际数据上运行时,需要插入的数据点太多。(我的真实数据约为1100万点。)


  • 所以问题是:有没有我忽略的简单方法?有没有办法减少上述缺点

    您可以创建稀疏矩阵并使用简单的索引

    In [1]: import numpy as np
    In [2]: x = np.arange(20, 40, dtype=np.float64)
    In [3]: y = np.arange(30, 50, dtype=np.float64)
    In [4]: z = np.random.random(20) * 25.0
    In [9]: from scipy.sparse import coo_matrix
    In [12]: m = coo_matrix((z, (x, y))).tolil()
    In [17]: m[25,35]
    Out[17]: 17.410532044604292
    

    我不明白你的cKDTree代码,你得到了
    idx
    ,为什么再次执行for循环?您只需通过
    result=triplets[idx,2]
    即可获得结果

    from scipy.spatial import cKDTree
    
    x = np.arange(20, 40, dtype=np.float64)
    y = np.arange(30, 50, dtype=np.float64)
    z = np.random.random(20) * 25.0
    triplets = np.hstack((x, y, z)).reshape((len(x),3))
    
    a = 30.1
    b = 40.5
    
    points = triplets[:,0:2] # drops the z column
    tree = cKDTree(points)
    idx = tree.query((a, b))[1] # this returns a tuple, we want the index
    result = triplets[idx, 2]
    

    如果你想插入结果,而不是只为最近的邻居找到Z值,我会考虑做如下的事情:

  • 使用k-d树根据数据点的(x,y)坐标对数据点进行分区
  • 对于要插值的给定(xi,yi)点,查找其k近邻
  • 取其z值的平均值,根据其与(xi,yi)的距离加权
  • 代码可能如下所示:

    import numpy as np
    from scipy.spatial import cKDTree
    
    # some fake (x, y, z) data
    XY = np.random.rand(10000, 2) - 0.5
    Z = np.exp(-((XY ** 2).sum(1) / 0.1) ** 2)
    
    # construct a k-d tree from the (x, y) coordinates
    tree = cKDTree(XY)
    
    # a random point to query
    xy = np.random.rand(2) - 0.5
    
    # find the k nearest neighbours (say, k=3)
    distances, indices = tree.query(xy, k=3)
    
    # the z-values for the k nearest neighbours of xy
    z_vals = Z[indices]
    
    # take the average of these z-values, weighted by 1 / distance from xy
    dw_avg = np.average(z_vals, weights=(1. / distances))
    
    值得玩玩一下k值,k是最近邻居的平均数。这本质上是一种粗糙的形式,其中k值控制着对z值的基本分布施加的“平滑度”。k越大,平滑度越高

    类似地,您可能希望根据点与(xi,yi)的距离来权衡点的贡献,这取决于您认为z中的相似性如何随着x,y距离的增加而减少。例如,您可能希望通过
    (1/距离**2)
    而不是
    (1/距离)
    来加权

    在性能方面。请记住,您只需要为数据集构建一次树,如果需要,您可以通过将(N,2)数组传递到
    tree.query()
    ,一次查询多个点


    用于近似近邻搜索的工具(例如)可能更快,但在数据维数非常高的情况下,这些工具通常更有用。

    创建一个以
    (x,y)
    形式的元组作为键,映射到
    z
    值的字典是否可行?这将使查找时间保持不变,生成词典的前期成本很大,并且可能会严重影响内存使用。您需要这个吗?除非你事先知道你的钥匙。假设您的输入数据有一个(20.05,45.0,5.55)。我们用
    foo[(20.05,45.0)]=5.55将其分配到dict中。当你试图查询你的dict
    foo[(20,45)]
    时,你会得到一个
    KeyError
    。我想要的是返回最近点的值,或者更好的是,一个从附近点得到的插值。正如你所说,你有三组数据。是否可以使用类似的方式将它们表示为三个2D字段,然后进行2D插值?(这可能只有在z值非常平滑的情况下才能很好地工作)对于大型数据集,我怀疑任何东西都比不上cKDTree。这是一个好主意,但是,它不能可靠地工作!我运行了您提供的代码,对于某些值,它返回预期的结果。对于其他人,它返回0。例如,对于
    m[25,35]
    来说,它是有效的,就像
    m[25.1,35.999]
    一样。但是,对于
    m[25,36]
    我什么也得不到。好的,问题在于浮点值。因此,您可以为x和y值创建索引。例如,您可以从数组席、Y和Z创建矩阵M。席和彝是X和Y中的项目位置向量。您可以创建一个DICT,将值从x转换为席,或者预X,然后使用某种类型的二进制搜索来查找项目的索引。我已经更新了。谢谢