web-dev-qa-db-fra.com

Comment obtenir d'autres colonnes lors de l'utilisation de Spark DataFrame groupby?

quand j'utilise DataFrame groupby comme ceci:

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

J'obtiendrai seulement un DataFrame avec les colonnes "age" et "count (id)", mais en df, il y a beaucoup d'autres colonnes comme "name".

En tout, je veux obtenir le résultat comme dans MySQL,

"sélectionner le nom, l'âge, le nombre (id) du groupe df par l'âge"

Que dois-je faire lorsque j'utilise groupby dans Spark?

21
Psychevic

En bref, en général, vous devez joindre les résultats agrégés à la table d'origine. Spark SQL suit la même convention pré-SQL: 1999 que la plupart des bases de données majeures (PostgreSQL, Oracle, MS SQL Server), qui n'autorise pas de colonnes supplémentaires dans les requêtes d'agrégation. 

Comme les agrégations telles que les résultats de comptage ne sont pas bien définies et que le comportement a tendance à varier dans les systèmes prenant en charge ce type de requête, vous pouvez simplement inclure des colonnes supplémentaires à l'aide d'agrégats arbitraires comme first ou last.

Dans certains cas, vous pouvez remplacer agg à l'aide de select par des fonctions de fenêtre et de where suivant, mais cela peut coûter très cher, en fonction du contexte.

23
zero323

Une façon d'obtenir toutes les colonnes après avoir effectué un groupBy consiste à utiliser la fonction de jointure.

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

data_joined aura désormais toutes les colonnes, y compris les valeurs de comptage. 

8
Swetha Kannan

Peut-être que cette solution vous sera utile.

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

Sortie:

+---+----+---+-----+
| 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