当前位置: 首页 > 知识库问答 >
问题:

如何避免交叉连接以查找Spark数据帧中每两行之间的成对距离

商焕
2023-03-14

我有一个火花数据框,有三列,指示原子的位置,即位置X,Y

df = atomsDF.withColumn("id", F.monotonically_increasing_id())
windowSpec = W.orderBy("id")
df = df.withColumn("id", F.row_number().over(windowSpec))
df_1 = df.select(*(F.col(col).alias("{}_1".format(col)) for col in df.columns))
df_3 = df_1.crossJoin(df).where("id_1 != id")

df_3 = df_3.withColumn(
        "Distance",
        F.sqrt(
            F.pow(df_3["Position_X_1"] - df_3["Position_X"], F.lit(2))
            + F.pow(df_3["Position_Y_1"] - df_3["Position_Y"], F.lit(2))
            + F.pow(df_3["Position_Z_1"] - df_3["Position_Z"], F.lit(2))
        )
    )

我的数据框如下所示:

Position_X|Position_Y|Position_Z|
+----------+----------+----------+
|    27.545|     6.743|    12.111|
|    27.708|     7.543|    13.332|
|    27.640|     9.039|    12.970|
|    26.991|     9.793|    13.693|
|    29.016|     7.166|    14.106|
|    29.286|     8.104|    15.273|
|    28.977|     5.725|    14.603|
|    28.267|     9.456|    11.844|
|    28.290|    10.849|    11.372|
|    26.869|    11.393|    11.161|
+----------+----------+----------+

现在,我如何避免交叉连接,因为交叉连接后,行数呈指数增长?例如,对于交叉连接后有3000行的数据集,总行数增长到3000*2999=8997000,这非常耗时。还有其他有效的方法来计算每两行之间的成对距离吗?


共有1个答案

路雅懿
2023-03-14

你说你需要找到每两个原子之间的距离。因此,由于结果大小为N^2,因此运行时间按定义是二次的。你可以对它进行一些优化,但它仍然是二次的。

只有当你实际上不需要找到每两个原子之间的N^2距离,而只需要根据一些标准找到对时,你才能优化它。

例如,人们通常需要找到比某个阈值距离更近的对,因为R树提供了更好的可伸缩性。在Spark中,可能更容易将原子分裂成大小等于阈值距离的立方体网格,然后只需要在相同或相邻立方体中的原子和原子之间交叉连接。

 类似资料:
  • 我有以下数据框: 我想用列创建一个新的数据帧,并从开始连接每两列,因此最终表如下所示:

  • 假设我有两个这种格式的数据帧(称它们为和): 我希望获得所有行的数据帧,这些行在和中有一个公共的。(即,如果同时位于和中,则在输出数据帧中包括这两行) 我能想到很多方法来解决这个问题,但它们都让我觉得笨拙。例如,我们可以在每个数据帧中找到所有唯一的s,创建每个数据帧的集合,找到它们的交集,用结果集过滤两个数据帧,并连接两个过滤后的数据帧。 也许这是最好的方法,但我知道熊猫很聪明。有没有更简单的方法

  • 问题内容: 假设我有x1,y1,还有x2,y2。 我如何找到它们之间的距离?这是一个简单的数学函数,但是此在线代码段吗? 问题答案: dist = sqrt( (x2 - x1)2 + (y2 - y1)2 ) 正如其他人指出的那样,您也可以使用等效的内置函数:

  • 我有两个数据帧df1和df2,其中df2是df1的子集。我如何获得一个新的数据帧(df3),它是两个数据帧之间的差值? 换句话说,一个数据帧,它包含了df1中所有的行/列,而不是DF2中的行/列?

  • 问题内容: 我找不到关于交叉联接的任何信息,包括合并/联接或其他一些东西。我需要使用{my function}作为myfunc处理两个数据帧。相当于: 相当于: 但我需要更有效的解决方案:如果使用了应用,我将如何实现它们; ^^ 问题答案: 对于叉积,请参阅此问题。 本质上,您必须进行常规合并,但为每一行赋予相同的键以进行连接,以使每一行在框架之间相互连接。 然后可以通过应用函数将列添加到新框架:

  • 我有两个数据帧和包含IP地址,我正在尝试将IP地址映射到地理位置信息,如经度和纬度,它们是中的列。 我运行它作为一个火花提交作业,但操作花了很长时间,即使只有不到2500行。 我的代码: 有没有其他方法可以加入这两张桌子?还是我做错了?