Python 如何避免交叉连接以查找Spark数据帧中每两行之间的成对距离
我有一个火花数据框,有3列,表示原子的位置,即X、Y和Z的位置。现在,为了求出每两个原子之间的距离,我需要应用距离公式。距离公式为Python 如何避免交叉连接以查找Spark数据帧中每两行之间的成对距离,python,apache-spark,pyspark,apache-spark-sql,euclidean-distance,Python,Apache Spark,Pyspark,Apache Spark Sql,Euclidean Distance,我有一个火花数据框,有3列,表示原子的位置,即X、Y和Z的位置。现在,为了求出每两个原子之间的距离,我需要应用距离公式。距离公式为d=sqrt((x2−x1)^2+(y2−y1)^2+(z2-z1)^2)。对于较小的数据集,建议使用交叉连接,但对于效率非常低且耗时的较大数据集,建议使用交叉连接。目前,我正在使用以下代码 df = atomsDF.withColumn("id", F.monotonically_increasing_id()) windowSpec = W.orderBy("id
d=sqrt((x2−x1)^2+(y2−y1)^2+(z2-z1)^2)
。对于较小的数据集,建议使用交叉连接,但对于效率非常低且耗时的较大数据集,建议使用交叉连接。目前,我正在使用以下代码
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,这非常耗时。
有没有其他有效的方法来计算每两行之间的成对距离?你说你需要计算每两个原子之间的距离。因此,由于结果大小为N^2,因此运行时间根据定义是二次的。您可以对它进行一些优化,但它仍然是二次的 只有当你实际上不需要找到每2个原子之间的N^2距离,而只需要根据一些标准找到对时,你才能优化它
例如,通常需要找到比某个阈值距离更近的对-因为R树提供了更好的可伸缩性。在Spark中,可能更容易将原子分割成大小等于阈值距离的立方体网格,然后您只需要在相同或相邻立方体中的原子和原子之间交叉连接。要在距离上应用一些阈值,我仍然必须先找到距离。正如您提到的,通常需要找到比某个阈值距离更近的对。我还在做交叉连接,寻找距离。对吗?它会优化结果吗?这就是诀窍——你可以过滤掉很多对,你可以保证它们之间的距离大于阈值,而不需要实际计算这些对之间的精确距离。然后,您只需要计算剩余对之间的精确距离。在维基百科中查找R-树,我还注意到答案中更简单的立体微笑。