it-roy-ru.com

Как получить другие столбцы при использовании Spark DataFrame groupby?

когда я использую DataFrame groupby, как это:

df.groupBy(df("age")).agg(Map("id"->"count"))

Я получу только DataFrame со столбцами «age» и «count (id)», но в df есть много других столбцов, таких как «name».

В целом, я хочу получить результат, как в MySQL,

"выберите имя, возраст, количество (id) из группы df по возрасту"

Что я должен делать при использовании groupby в Spark?

21
Psychevic

Короче говоря, как правило, вы должны объединить агрегированные результаты с исходной таблицей. Spark SQL придерживается того же соглашения, что и до SQL: 1999, что и большинство основных баз данных (PostgreSQL, Oracle, MS SQL Server), которые не допускают дополнительные столбцы в запросах агрегации. 

Поскольку для агрегатов, таких как результаты подсчета, не определены должным образом, а поведение, как правило, различается в системах, поддерживающих этот тип запросов, вы можете просто включить дополнительные столбцы, используя произвольные агрегаты, такие как first или last.

В некоторых случаях вы можете заменить agg, используя select, на оконные функции и последующие where, но в зависимости от контекста это может быть довольно дорого.

23
zero323

Один из способов получить все столбцы после выполнения groupBy - использовать функцию соединения.

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

data_joined теперь будет иметь все столбцы, включая значения количества. 

8
Swetha Kannan

Может быть, это решение будет полезным.

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()

Результат:

+---+----+---+-----+
| 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|
+---+----+---+-----+
0
Thirupathi Chavati