在没有for循环的情况下使用多个numpy数组进行计算

2024-05-23 22:32:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我是蛮力计算最短距离从一个点到多个其他2D平面上的数据来自熊猫数据帧使用df['column'].to_numpy()。你知道吗

目前,我正在使用numpy数组上的嵌套for循环来填充一个列表,获取该列表的最小值,并将该值存储在另一个列表中。你知道吗

检查1000点(从df_point)和25000点(从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 = []

这不是一个特别的Python。有没有一种方法可以通过矢量化或至少不使用嵌套for循环来实现这一点?你知道吗


Tags: theto数据innumpydf列表for
3条回答

我给你一个方法:

  1. 创建列为->;pointID、CoordX、CoordY的数据帧
  2. 创建偏移值为1的辅助数据帧(oldDF.iloc公司[点IDX]=newDF.iloc公司[点IDX]-1)
  3. 这个偏移值需要从1循环到坐标数-1
  4. tempDF[“Euclid Dist”]=sqrt(正方形(oldDf[“CoordX”]-newDF[“CoordX”])+正方形(oldDf[“CoordY”]-newDF[“CoordY”])
  5. 将此tempDF附加到列表中

加快速度的原因:

  1. 只有一个循环迭代从1到坐标数-1的偏移量
  2. 矢量化已在步骤4中完成
  3. 利用numpy平方根和平方函数来确保最佳结果

您可以尝试分别在x和y方向上查找最近的点,而不是查找最近的点,然后通过使用内置的min函数(如此问题的顶部答案)比较这两个方向以查找更接近的点:

min(myList, key=lambda x:abs(x-myNumber))

from list of integers, get number closest to a given value

编辑: 如果您在一个函数调用中完成所有操作,那么您的循环将以这样的方式结束。另外,我不确定min函数是否会以与当前代码所用时间相同的方式循环通过比较数组:

for k,m in np.nditer([point_x, point_y]): min = min(compare_x, compare_y, key=lambda x,y: (x-k)**2 + (y-m)**2 )

另一种方法是预先计算比较数组中所有点与(0,0)或其他点(如(-10001000))之间的距离,在此基础上对比较数组进行排序,然后仅检查与参考具有类似距离的点。你知道吗

方法是创建一个1000 x 25000的矩阵,然后找到行最小值的索引。你知道吗

# distances for all combinations (1000x25000 matrix)
dum_arr = (point_x[:, None] - compare_x)**2 + (point_y[:, None] - compare_y)**2

# indices of minimums along rows
idx = np.argmin(dum_arr, axis=1)

# Not sure what is needed from the indices, this get the values 
# from `point_name` dataframe using found indices
min_vals = df_compare['point_name'].iloc[idx]

相关问题 更多 >