关于#Python#的问题,如何解决?

问题遇到的现象和发生背景

想利用Python计算两个array之间的距离
points1是表1的array,points2是表2的array

points1 = dfA.values
points2 = dfe1.values
我的解答思路和尝试过的方法

使用过分块计算和np.sqrt计算,但是不支持float类型的计算,出错了

我想要达到的结果

下面两个表每一列代表坐标x,y,z,想计算表1和表2两两点的距离并筛选出表1每个点与表2中距离最近的40个点
注:每个表基本上都有几十万行,所以计算速度是个问题,而且每一列的数据类型都是float,最好能够使用分块计算
表1

img

表2

img

参考GPT和自己的思路:你可以使用scipy.spatial.distance.cdist函数来计算两个array之间的距离,并使用argsort函数和切片来找到表1每个点与表2中距离最近的40个点。以下是一个示例代码,它使用分块计算来加快速度:

import numpy as np
from scipy.spatial.distance import cdist

# 假设points1和points2是两个array,每一行代表一个点的坐标
points1 = np.random.rand(100000, 3)
points2 = np.random.rand(200000, 3)

# 将points2划分成多个块,每个块包含1000个点
block_size = 1000
blocks2 = [points2[i:i+block_size] for i in range(0, len(points2), block_size)]

# 计算每个点在points1中与所有块中的点的距离,并找到每个点距离最近的40个点的索引
k = 40
distances = []
for block2 in blocks2:
    dist = cdist(points1, block2)
    indices = np.argpartition(dist, k-1)[:, :k]
    distances.append((dist, indices))
distances = np.concatenate(distances, axis=1)
nearest_indices = np.argsort(distances, axis=1)[:, :k]

# 最近的40个点在points2中的坐标
nearest_points2 = np.concatenate([blocks2[i][nearest_indices[:, i]] for i in range(len(blocks2))])

# 计算表1每个点与最近的40个点的距离
distances = np.linalg.norm(points1[:, np.newaxis] - nearest_points2, axis=2)


这个代码首先将points2划分成多个块,并分别计算每个点在points1中与所有块中的点的距离,然后找到每个点距离最近的40个点的索引。最后,它计算最近的40个点在points2中的坐标,并计算表1每个点与最近的40个点的距离。

可以使用 scipy.spatial.distance.cdist 函数计算两个数组之间的距离,并使用 numpy.argsort 函数获取距离最近的点的索引。下面是一段示例代码,它演示了如何计算表1和表2中每个点与最近的40个点之间的距离:

import numpy as np
from scipy.spatial.distance import cdist

# 生成两个示例数组
points1 = np.random.rand(10000, 3)
points2 = np.random.rand(20000, 3)

# 计算距离矩阵
distances = cdist(points1, points2)

# 获取每个点距离最近的40个点的索引
nearest_indices = np.argsort(distances, axis=1)[:, :40]

# 获取每个点距离最近的40个点的距离
nearest_distances = distances[np.arange(len(points1))[:, None], nearest_indices]

# 输出结果
print(nearest_distances)


在这个示例中,我们首先使用 cdist 函数计算表1和表2之间的距离矩阵,然后使用 argsort 函数获取每个点距离最近的40个点的索引。由于 argsort 函数返回的是排序后的索引,所以我们需要使用 np.arange(len(points1))[:, None] 创建一个列向量,以便使用 NumPy 广播机制获取每个点的距离最近的40个点的距离。

需要注意的是,这个示例中使用的是随机生成的示例数据,如果您的实际数据是从文件或数据库中读取的,请先将数据转换为 NumPy 数组,然后再执行计算。此外,如果您的数据集非常大,可以考虑使用分块计算,以免内存不足。

该回答引用GPTᴼᴾᴱᴺᴬᴵ
您可以使用scipy库中的spatial.distance.cdist函数来计算两个数组之间的距离,它支持float类型的计算。

首先,您需要安装scipy库。在命令行中运行以下命令:

pip install scipy

然后,在Python中导入scipy库,并使用cdist函数计算两个数组之间的距离:

from scipy.spatial.distance import cdist

distances = cdist(points1, points2)

此代码将计算points1和points2之间的距离,并将结果存储在名为distances的数组中。该数组的第i行和第j列的元素表示points1中第i行和points2中第j行之间的距离。

接下来,您可以使用numpy库的argsort函数来找到每个点最近的40个点:

import numpy as np

nearest_indices = np.argsort(distances, axis=1)[:, :40]

此代码将对distances中的每一行进行排序,并找到距离最近的40个点的索引。结果存储在名为nearest_indices的数组中。

最后,您可以使用这些索引来选择points2中距离每个点最近的40个点:

nearest_points = points2[nearest_indices]

此代码将从points2中选择与points1中每个点距离最近的40个点,并将结果存储在名为nearest_points的数组中。

希望这个解决方案能够帮助您计算两个数组之间的距离。

numpy.sqrt 可以使用float类型,不太明白题主提到的“不支持”是什么意思,数据是在表格中,读取到的表格内容是不是没有转换格式就直接用作计算了呢

我举个例子哈

import numpy as np

points1 = np.array([1.0, 1.0])
points2 = np.array([1.0, 6.0])

dist = np.sqrt(np.sum(np.square(points1 - points2)))
print(dist)


如果阵列有两个以上的维度,我们可以使用axis参数指定计算距离的维度,数组的数据类型不影响参数的使用。

import numpy as np

points1 = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
points2 = np.array([[2.0, 3.0], [4.0, 5.0], [6.0, 7.0]])

dist = np.linalg.norm(points1 - points2, axis=1)
print(dist)


找最近的点我写个demo给你个参考

import numpy as np

points1 = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
points2 = np.array([2.0, 3.0])

distances = np.linalg.norm(points1 - points2, axis=1)
min_index = np.argmin(distances)
closest_point = points1[min_index]

print(closest_point)


参考GPT和自己的思路,您可以使用SciPy库中的cKDTree方法计算点之间的距离,同时使用NumPy库中的argsort方法筛选出表1每个点与表2中距离最近的40个点。

首先,您需要导入所需的库:

import numpy as np
from scipy.spatial import cKDTree

接下来,您可以使用以下代码计算表1和表2中每个点之间的距离:

# 计算表1和表2中每个点之间的距离
tree = cKDTree(points2)
distances, indices = tree.query(points1, k=40)

其中,参数k设置为40,以便仅返回表1中每个点与表2中距离最近的40个点。

最后,您可以使用以下代码获取表1每个点与表2中距离最近的40个点的索引:

# 获取表1每个点与表2中距离最近的40个点的索引
sorted_indices = np.argsort(distances, axis=1)
closest_indices = indices[np.arange(len(points1))[:, None], sorted_indices]

其中,sorted_indices是按距离排序后的索引,closest_indices是根据sorted_indices获取的表1每个点与表2中距离最近的40个点的索引。

注意,如果数据量非常大,您可以考虑使用分块计算,将数据分成多个块,并逐块计算距离。然后,您可以将结果合并在一起,以获得最终结果。

基于最新版ChatGPT4和自己的思路回答,望采纳!!!有其他问题也可以询问我哦💕(最新版更智能,功能更加强大):
您可以尝试使用Scipy库中的cdist函数,该函数可用于计算两个数组中所有点之间的距离。cdist函数支持处理浮点类型的计算,并且使用Cython实现,因此速度非常快。
以下是使用cdist函数计算两个数组中所有点之间的距离的示例代码:

from scipy.spatial.distance import cdist

# 计算两个数组中所有点之间的距离
distances = cdist(points1, points2)

# 对于每个点,获取最近的40个点
nearest_indices = distances.argsort(axis=1)[:, :40]
nearest_distances = distances[np.arange(len(points1))[:, None], nearest_indices]

这里使用cdist函数计算了points1和points2中所有点之间的距离,并将结果保存在distances数组中。然后,使用argsort函数获取每个点最近的40个点的索引,并将这些索引保存在nearest_indices数组中。最后,使用索引来提取nearest_distances数组中对应的距离。

注意,如果您的数据集非常大,您可能需要将数据拆分为更小的块,以便内存能够容纳。您可以使用np.array_split函数将数组拆分为多个块,并使用cdist函数对每个块进行计算。