【发布时间】:2019-04-13 16:35:42
【问题描述】:
我是蛮力计算二维平面上从一个点到许多其他点的最短距离,数据来自使用df['column'].to_numpy() 的熊猫数据框。
目前,我正在使用 numpy 数组上的嵌套 for 循环来填充列表,获取该列表的最小值,并将该值存储在另一个列表中。
检查 1000 个点(来自 df_point)和 25,000 个点(来自 df_compare)大约需要一分钟,因为这是一个低效的过程可以理解。我的代码如下。
point_x = df_point['x'].to_numpy()
compare_x = df_compare['x'].to_numpy()
point_y = df_point['y'].to_numpy()
compare_y = df_compare['y'].to_numpy()
dumarr = []
minvals = []
# Brute force caclulate the closet point by using the Pythagorean theorem comparing each
# point to every other point
for k in range(len(point_x)):
for i,j in np.nditer([compare_x,compare_y]):
dumarr.append(((point_x[k] - i)**2 + (point_y[k] - j)**2))
minval.append(df_compare['point_name'][dumarr.index(min(dumarr))])
# Clear dummy array (otherwise it will continuously append to)
dumarr = []
这不是一个特别的pythonic。有没有办法通过矢量化或至少不使用嵌套的 for 循环来做到这一点?
【问题讨论】:
-
您可以使用 scipy 库中的 cdist 来获得 1k x 25k 距离矩阵,然后在沿相应轴的距离矩阵上使用 numpy.min 来获得 1k 分钟的数组。假设您有足够的 RAM 在内存中保存完整的距离矩阵,它会快得多
-
@thesilkworm 你能举个例子说明使用四个数组而不是两个数组吗?
-
我假设你的 4 个数组是 1d,但最好确认一下(甚至可以举一些小例子)。并且不要使用
nditer。zip(compare_x, compare_y)更简单(更快)。 -
@DrakeMurdoch - 它只适用于两个数组,但它们可以是二维数组,就像我刚刚发布的示例一样。