Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Pyspark中将GroupBy对象转换为有序列表_Python_Apache Spark_Pyspark_Apache Spark Sql - Fatal编程技术网

Python 在Pyspark中将GroupBy对象转换为有序列表

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 |

我正在使用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 | 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中收集你的意思是?@eliash
collect.*
在Spark中不支持Spark<2.0中的原子。谢谢,
pivot
是我要找的
struct
在pyspark中收集你的意思是?@eliash
collect.*
在Spark中不支持Spark<2.0中的原子。