使用Spark DataFrame groupby时如何获取其他列?

Psy*_*vic 29 sql dataframe apache-spark apache-spark-sql

当我像这样使用DataFrame groupby时:

df.groupBy(df("age")).agg(Map("id"->"count"))
Run Code Online (Sandbox Code Playgroud)

我只会得到一个包含"age"和"count(id)"列的DataFrame,但是在df中,还有许多其他列,例如"name".

总而言之,我希望得到MySQL中的结果,

"按年龄从df组中选择姓名,年龄,计数(id)"

在Spark中使用groupby时我该怎么办?

zer*_*323 29

总的来说,一般来说,您必须将聚合结果与原始表连接起来.Spark SQL遵循与大多数主要数据库(PostgreSQL,Oracle,MS SQL Server)相同的pre-SQL:1999约定,它不允许在聚合查询中使用其他列.

因为对于像计数结果这样的聚合没有很好地定义,并且在支持这种类型的查询的系统中行为往往会有所不同,所以您可以使用任意聚合(如first或)来包含其他列last.

在某些情况下,您可以agg使用select窗口函数和后续替换,where但根据上下文,它可能非常昂贵.

  • 所以简短的答案就是简单地使用第一个/最后一个聚合: `df.groupBy(df("age")).agg(first("name"), first("some other col to includel"), ...)` (5认同)

Thi*_*ati 11

可能这个解决方案会有所帮助。

from pyspark.sql import SQLContext
from pyspark import SparkContext, SparkConf
from pyspark.sql import functions as F
from pyspark.sql import Window

    name_list = [(101, 'abc', 24), (102, 'cde', 24), (103, 'efg', 22), (104, 'ghi', 21),
                 (105, 'ijk', 20), (106, 'klm', 19), (107, 'mno', 18), (108, 'pqr', 18),
                 (109, 'rst', 26), (110, 'tuv', 27), (111, 'pqr', 18), (112, 'rst', 28), (113, 'tuv', 29)]

age_w = Window.partitionBy("age")
name_age_df = sqlContext.createDataFrame(name_list, ['id', 'name', 'age'])

name_age_count_df = name_age_df.withColumn("count", F.count("id").over(age_w)).orderBy("count")
name_age_count_df.show()
Run Code Online (Sandbox Code Playgroud)

输出:

+---+----+---+-----+
| id|name|age|count|
+---+----+---+-----+
|109| rst| 26|    1|
|113| tuv| 29|    1|
|110| tuv| 27|    1|
|106| klm| 19|    1|
|103| efg| 22|    1|
|104| ghi| 21|    1|
|105| ijk| 20|    1|
|112| rst| 28|    1|
|101| abc| 24|    2|
|102| cde| 24|    2|
|107| mno| 18|    3|
|111| pqr| 18|    3|
|108| pqr| 18|    3|
+---+----+---+-----+
Run Code Online (Sandbox Code Playgroud)


小智 10

在执行groupBy之后获取所有列的一种方法是使用join函数.

feature_group = ['name', 'age']
data_counts = df.groupBy(feature_group).count().alias("counts")
data_joined = df.join(data_counts, feature_group)
Run Code Online (Sandbox Code Playgroud)

data_joined现在将包含所有列,包括计数值.

  • 考虑这个`df.join(data_counts, feature_group).dropDuplicates()` (2认同)