Python 在Pyspark中将GroupBy对象转换为有序列表
我正在使用Spark 2.0.0和dataframe。 这是我的输入数据框Python 在Pyspark中将GroupBy对象转换为有序列表,python,apache-spark,pyspark,apache-spark-sql,Python,Apache Spark,Pyspark,Apache Spark Sql,我正在使用Spark 2.0.0和dataframe。 这是我的输入数据框 | id |年份|数量| |----|-------------|--------| |a | 2012 | 10| |b | 2012 | 12| |c | 2013 | 5| |b | 2014 | 7| |c | 2012 | 3| 我想要的是 | id | 2012年| 2013年| 2014年|| |----|-----------|-----------|-----------| |a | 10 | 0 |
| id |年份|数量|
|----|-------------|--------|
|a | 2012 | 10|
|b | 2012 | 12|
|c | 2013 | 5|
|b | 2014 | 7|
|c | 2012 | 3|
我想要的是
| id | 2012年| 2013年| 2014年||
|----|-----------|-----------|-----------|
|a | 10 | 0 | 0|
|b | 12 | 0 | 7|
|c | 3 | 5 | 0|
或
| id |年|数量|
|----|---------------|
|a |[10,0,0]|
|b |[12,0,7]|
|c |[3,5,0]|
我找到的最接近的解决方案是collect\u list()
,但此函数不提供列表的顺序。在我看来,解决方案应该是:
data.groupBy('id').agg(collect_函数)
有没有一种方法可以在不使用循环过滤每个id的情况下生成此信息?第一种方法可以使用
pivot
轻松实现:
from itertools import chain
years = sorted(chain(*df.select("year").distinct().collect()))
df.groupBy("id").pivot("year", years).sum("qty")
可以进一步转换为数组形式:
from pyspark.sql.functions import array, col
(...
.na.fill(0)
.select("id", array(*[col(str(x)) for x in years]).alias("yearly_qty")))
直接获得第二个可能不值得大惊小怪,因为你必须先填补空白。不过,您可以尝试:
from pyspark.sql.functions import collect_list, struct, sort_array, broadcast
years_df = sc.parallelize([(x, ) for x in years], 1).toDF(["year"])
(broadcast(years_df)
.join(df.select("id").distinct())
.join(df, ["year", "id"], "leftouter")
.na.fill(0)
.groupBy("id")
.agg(sort_array(collect_list(struct("year", "qty"))).qty.alias("qty")))
它还需要Spark 2.0+来获得对
struct
收集的支持
这两种方法都很昂贵,所以在使用时要小心。根据经验,长的比宽的好。第一种方法可以通过使用
pivot
轻松实现:
from itertools import chain
years = sorted(chain(*df.select("year").distinct().collect()))
df.groupBy("id").pivot("year", years).sum("qty")
可以进一步转换为数组形式:
from pyspark.sql.functions import array, col
(...
.na.fill(0)
.select("id", array(*[col(str(x)) for x in years]).alias("yearly_qty")))
直接获得第二个可能不值得大惊小怪,因为你必须先填补空白。不过,您可以尝试:
from pyspark.sql.functions import collect_list, struct, sort_array, broadcast
years_df = sc.parallelize([(x, ) for x in years], 1).toDF(["year"])
(broadcast(years_df)
.join(df.select("id").distinct())
.join(df, ["year", "id"], "leftouter")
.na.fill(0)
.groupBy("id")
.agg(sort_array(collect_list(struct("year", "qty"))).qty.alias("qty")))
它还需要Spark 2.0+来获得对
struct
收集的支持
这两种方法都很昂贵,所以在使用时要小心。根据经验,长比宽好。谢谢,
pivot
是我要找的struct
在pyspark中收集你的意思是?@eliashcollect.*
在Spark中不支持Spark<2.0中的原子。谢谢,pivot
是我要找的struct
在pyspark中收集你的意思是?@eliashcollect.*
在Spark中不支持Spark<2.0中的原子。