python - 创建记录对 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|
+---+---+---+---+---+---+
但我不想要冗余和自我配对。
解决方案
这个任务需要一个非等值连接,这在性能方面很糟糕。我希望你没有太多的行。
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|
+---+---+---+---+---+---+
推荐阅读
- vue.js - vuetify 突然显示奇怪的图标
- python - 如何格式化 MySql 表以避免“不正确的字符串值”错误?
- bash - BASH 如果命令包含“此文本”,请执行另一个命令?
- javascript - API get 调用返回状态 400
- elasticsearch - 查找nested.nested Elastic Search 文档的计数
- c++ - 在 C++ 中为堆栈编写推送方法
- php - 如何在重复 $_POST 提交时增加变量?
- python - 尝试使用烧瓶 html 下拉选择列表将列添加到 data_frame
- spring-integration - 由于令牌现已过期,处理与 MqttPahoMessageHandler 重新连接的最佳方法是什么?
- ruby-on-rails - Rails 救援 NoMethodError 替代方案