如何根据另一列计算值的数量?

时间:2017-06-20 23:37:51

标签: scala apache-spark apache-spark-sql

问题标题可能过于含蓄。 假设我们有一个火花数据框:

user_ID         phone_number
--------------------------------
A                 1234567
B                 1234567
C                 8888888
D                 9999999
E                 1234567
F                 8888888
G                 1234567

我们需要为每个user_ID计算有多少user_ID与之共享同一个phone_number。对于之前列出的表,所需的结果应为:

user_ID         count_of_userID_who_share_the_same_phone_number
----------------------------------------------------------------
A                 4
B                 4
C                 2
D                 1
E                 4
F                 2
G                 4

可以通过在spark.sql(query)中编写自联接查询来实现,但性能非常令人心碎。 有什么建议我怎么能更快地实现?谢谢:))

1 个答案:

答案 0 :(得分:4)

使用Spark的Window功能应该明显优于self-join

val df = Seq(
  ("A", "1234567"),
  ("B", "1234567"),
  ("C", "8888888"),
  ("D", "9999999"),
  ("E", "1234567"),
  ("F", "8888888"),
  ("G", "1234567")
).toDF(
    "user_id", "phone_number"
)

// Add phone number count via window function
import org.apache.spark.sql.expressions.Window
val df2 = df.withColumn("count", count("user_id").over(
  Window.partitionBy("phone_number")
)).orderBy("user_id")

df2.show
+-------+------------+-----+
|user_id|phone_number|count|
+-------+------------+-----+
|      A|     1234567|    4|
|      B|     1234567|    4|
|      C|     8888888|    2|
|      D|     9999999|    1|
|      E|     1234567|    4|
|      F|     8888888|    2|
|      G|     1234567|    4|
+-------+------------+-----+