如何在pyspark中重命名类似于使用spark兼容的sql pivot语句的列?

bq3bfh9z  于 2021-05-27  发布在  Spark
关注(0)|答案(2)|浏览(538)

我在spark中运行了这个查询

f"""
                    select
                        col_cate,
                        true as segment_true,
                        false as segment_false
                    from (
                        SELECT
                            {feature},
                            {target_col},
                            count(*) as cnt
                        from
                            table1
                        group by
                            {feature},
                            {target_col}
                    ) pivot (
                        sum(cnt)
                        for target_bool in (true, false)
                    )
                """)

输入数据如下

+--------+-----------+
|col_cate|target_bool|
+--------+-----------+
|       A|       true|
|       A|      false|
|       B|       true|
|       B|      false|
|       A|       true|
|       A|      false|
|       B|       true|
|       B|      false|
+--------+-----------+

输出数据为

+--------+------------+-------------+
|col_cate|segment_true|segment_false|
+--------+------------+-------------+
|       A|        true|        false|
|       B|        true|        false|
+--------+------------+-------------+

但是,当我尝试在pyspark中执行相同的操作时,我不知道如何重命名 [col_cate, true, false][col_cate, segment_true segment_false] 我该怎么做?
我试过了

output_df.groupBy(["col_cate", "target_bool"]).\
  count().\
  groupBy("col_cate").\
  pivot("target_bool").\
  sum("count")

但似乎没有办法在代码中重命名列。我知道我可以给它改名,但感觉不那么优雅。

wwodge7n

wwodge7n1#

可以在旋转后使用agg和alias方法来完成。

import pyspark.sql.functions as F
tst = sqlContext.createDataFrame([('A','true',1),('A','false',2),('B','true',3),('B','false',4),('A','true',5),('A','false',6),('B','true',7),('B','false',8)],schema=['col_cate','target_bool','id'])

# %%

tst_res =tst.groupBy(["col_cate", "target_bool"]).count().groupBy("col_cate").pivot("target_bool").agg(F.sum("count").alias("segment"),F.sum("count").alias("dummy"))

结果:

+--------+-------------+-----------+------------+----------+
|col_cate|false_segment|false_dummy|true_segment|true_dummy|
+--------+-------------+-----------+------------+----------+
|       B|            2|          2|           2|         2|
|       A|            2|          2|           2|         2|
+--------+-------------+-----------+------------+----------+

第二次聚合的原因,我也不清楚。但是,只有当存在多个聚合时才会发生重命名。我正在调查此事。但这应该对你有用。
编辑:正如评论中所指出的,您不需要对它进行两次分组。以下代码将实现此目的: tst_res1=tst.groupby("col_cate").pivot("target_bool").agg(F.count("target_bool").alias('segment'),F.count("target_bool").alias('dummy'))

3phpmpom

3phpmpom2#

可以将列相应地转换为

df.withColumn('target_bool', when(col('target_bool')=='true',lit('segment_true')).otherwise(lit('segment_false'))).\
  groupBy(["col_cate", "target_bool"]).\
  count().\
  groupBy("col_cate").\
  pivot("target_bool").\
  sum("count").show()

+--------+-------------+------------+
|col_cate|segment_false|segment_true|
+--------+-------------+------------+
|       B|            2|           2|
|       A|            2|           2|
+--------+-------------+------------+

或者您的sql等效版本如下

output_df.groupBy(["col_cate", "target_bool"]).\
  count().\
  groupBy("col_cate").\
  pivot("target_bool").\
  sum("count").select(col('col_cate'),col('true').alias('segment_true'),col('false').alias('segment_false'))

相关问题