激发组内的成对差异

时间:2018-08-28 16:06:20

标签: apache-spark apache-spark-sql apache-spark-mllib

我有一个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中的某些内容可能是适当的,但同样,我也没有找到任何东西。

1 个答案:

答案 0 :(得分:1)

可以通过内部联接实现,结果与预期相同:

df.alias("left").join(df.alias("right"),"id")
  .select($"id",
      ($"left.x"-$"right.x").alias("dx"),
      ($"left.y"-$"right.y").alias("dy"))