我有一个spark数据框,为了便于讨论,让它成为:
coord.x
我想计算具有相同ID的数据帧中条目之间的所有成对差异,然后将结果输出到另一个数据帧。对于较小的数据框,我可以通过以下方式实现:
val df = sc.parallelize(
Seq(("a",1,2),("a",1,4),("b",5,6),("b",10,2),("c",1,1))
).toDF("id","x","y")
+---+---+---+
| id| x| y|
+---+---+---+
| a| 1| 2|
| a| 1| 4|
| b| 5| 6|
| b| 10| 2|
| c| 1| 1|
+---+---+---+
但是,对于大型数据框,这不是一种合理的方法,因为crossJoin大部分会产生将被后续where子句丢弃的数据。
我仍然很新,而groupBy似乎是一个很自然的地方,但是我不知道如何使用groupBy来完成。任何帮助都将受到欢迎。
我最终想删除冗余,例如:
df.crossJoin(
df.select(
(df.columns.map(x=>col(x).as("_"+x))):_*)
).where(
col("id")===col("_id")
).select(
col("id"),
(col("x")-col("_x")).as("dx"),
(col("y")-col("_y")).as("dy")
)
+---+---+---+
| id| dx| dy|
+---+---+---+
| c| 0| 0|
| b| 0| 0|
| b| -5| 4|
| b| 5| -4|
| b| 0| 0|
| a| 0| 0|
| a| 0| -2|
| a| 0| 2|
| a| 0| 0|
+---+---+---+
但是如果通过冗余更容易地做到这一点,那么我可以接受。
这不是在ML中执行的常见转换,因此我认为MLlib中的某些内容可能是适当的,但同样,我也没有找到任何东西。
答案 0 :(得分:1)
可以通过内部联接实现,结果与预期相同:
df.alias("left").join(df.alias("right"),"id")
.select($"id",
($"left.x"-$"right.x").alias("dx"),
($"left.y"-$"right.y").alias("dy"))