首页 > 解决方案 > 创建记录对 n PySpark DataFrame

问题描述

我有一个 PySpark DataFrame,它看起来像:

+---+---+---+
|  x|  y|  z|
+---+---+---+
|  A|  1|  2|
|  B|  3|  4|
|  C|  5|  6|
|  D|  7|  8|
+---+---+---+

我想要一个结果 DataFrame,其中包含上述 DataFrame 中存在的成对记录(每条记录都与其他记录相对,除了它自己)。不应该有重复的对。例如,如果出现 AB 和 BA,则仅保留 AB。

对数应等于 len(df) * (len(df) - 1) / 2 (= 6 对于上述 DataFrame)

预期输出:

+---+---+---+---+---+---+
|x_1|y_1|z_1|x_2|y_2|z_2|
+---+---+---+---+---+---+
|  A|  1|  2|  B|  3|  4|
|  A|  1|  2|  C|  5|  6|
|  A|  1|  2|  D|  7|  8|
|  B|  3|  4|  C|  5|  6|
|  B|  3|  4|  D|  7|  8|
|  C|  5|  6|  D|  7|  8|
+---+---+---+---+---+---+

我如何在 PySpark 中做到这一点?有没有像自我连接或笛卡尔积这样的连接?谢谢。

- 编辑 -

我能够进行交叉连接并获得所有对(16 对)。

temp2 = temp.withColumnRenamed('x', 'x_1').crossJoin(temp.withColumnRenamed('x', 'x_2'))
temp2.orderBy(['x_1', 'x_2'], ascending = [True, True]).show()

输出:

+---+---+---+---+---+---+
|x_1|  y|  z|x_2|  y|  z|
+---+---+---+---+---+---+
|  A|  1|  2|  A|  1|  2|
|  A|  1|  2|  B|  3|  4|
|  A|  1|  2|  C|  5|  6|
|  A|  1|  2|  D|  7|  8|
|  B|  3|  4|  A|  1|  2|
|  B|  3|  4|  B|  3|  4|
|  B|  3|  4|  C|  5|  6|
|  B|  3|  4|  D|  7|  8|
|  C|  5|  6|  A|  1|  2|
|  C|  5|  6|  B|  3|  4|
|  C|  5|  6|  C|  5|  6|
|  C|  5|  6|  D|  7|  8|
|  D|  7|  8|  A|  1|  2|
|  D|  7|  8|  B|  3|  4|
|  D|  7|  8|  C|  5|  6|
|  D|  7|  8|  D|  7|  8|
+---+---+---+---+---+---+

但我不想要冗余和自我配对。

标签: pythonpyspark

解决方案


这个任务需要一个非等值连接,这在性能方面很糟糕。我希望你没有太多的行。

from pyspark.sql import functions as F, Window as w

a = [
    ("A", 1,2),
    ("B", 3,4),
    ("C", 5,6),
    ("D", 7,8),
]

b = "x y z".split()

df = spark.createDataFrame(a,b)


df_2 = df.withColumn(
    "nb", 
    F.row_number().over(w.orderBy("x"))
)


df_final = df_2.alias("df_l").crossJoin(df_2.alias("df_r"))

df_final.where("df_l.nb < df_r.nb").select(
    "df_l.x",
    "df_l.y",
    "df_l.z",
    "df_r.x",
    "df_r.y",
    "df_r.z",
).show()

+---+---+---+---+---+---+
|  x|  y|  z|  x|  y|  z|
+---+---+---+---+---+---+
|  A|  1|  2|  B|  3|  4|
|  A|  1|  2|  C|  5|  6|
|  A|  1|  2|  D|  7|  8|
|  B|  3|  4|  C|  5|  6|
|  B|  3|  4|  D|  7|  8|
|  C|  5|  6|  D|  7|  8|
+---+---+---+---+---+---+


推荐阅读