使用Window操作替换所有列值吗?

时间:2018-11-02 20:19:34

标签: apache-spark pyspark apache-spark-sql pyspark-sql

嗨,数据框如下创建。

df = sc.parallelize([
    (1, 3),
    (2, 3),
    (3, 2),
    (4,2),
    (1, 3)
]).toDF(["id",'t']) 

如下图所示。

+---+---+
| id|  t|
+---+---+
|  1|  3|
|  2|  3|
|  3|  2|
|  4|  2|
|  1|  3|
+---+---+

我的主要目的是,我想用重复多少次来替换每列中的重复值。

所以我尝试了流代码,但它没有按预期工作。

from pyspark.sql.functions import col
column_list = ["id",'t']
w = Window.partitionBy(column_list)
dfmax=df.select(*((count(col(c)).over(w)).alias(c) for c in df.columns))
dfmax.show()
+---+---+
| id|  t|
+---+---+
|  2|  2|
|  2|  2|
|  1|  1|
|  1|  1|
|  1|  1|
+---+---+

我的预期输出将是

+---+---+
| id|  t|
+---+---+
|  2|  3|
|  1|  3|
|  1|  1|
|  1|  1|
|  2|  3|
+---+---+

1 个答案:

答案 0 :(得分:0)

如果我对您的理解正确,那么您正在寻找的只是:

df.select(*[count(c).over(Window.partitionBy(c)).alias(c) for c in df.columns]).show()
#+---+---+
#| id|  t|
#+---+---+
#|  2|  3|
#|  2|  3|
#|  1|  2|
#|  1|  3|
#|  1|  2|
#+---+---+

此内容与您发布的内容之间的区别在于,我们一次只能划分一列。

请记住,DataFrame是无序的。如果要维持行顺序,可以使用pyspark.sql.functions.monotonically_increasing_id()添加一个排序列:

from pyspark.sql.functions import monotonically_increasing_id

df.withColumn("order", monotonically_increasing_id())\
    .select(*[count(c).over(Window.partitionBy(c)).alias(c) for c in df.columns])\
    .sort("order")\
    .drop("order")\
    .show()
#+---+---+
#| id|  t|
#+---+---+
#|  2|  3|
#|  1|  3|
#|  1|  2|
#|  1|  2|
#|  2|  3|
#+---+---+