Plus propre, plus efficace syntaxe pour effectuer DataFrame auto-jointure dans Spark
Dans le standard SQL, lorsque vous rejoignez une table à elle-même, vous pouvez créer des alias pour les tables de garder une trace de colonnes que vous faites référence à:
SELECT a.column_name, b.column_name...
FROM table1 a, table1 b
WHERE a.common_field = b.common_field;
Il y a deux façons que je peux penser à obtenir la même chose en utilisant l'Étincelle DataFrame
API:
Solution #1: Renommer les colonnes
Il ya un couple de différentes méthodes pour cela en réponse à cette question. Juste renomme toutes les colonnes avec un suffixe spécifique:
df.toDF(df.columns.map(_ + "_R"):_*)
Par exemple, vous pouvez faire:
df.join(df.toDF(df.columns.map(_ + "_R"):_*), $"common_field" === $"common_field_R")
Solution #2: Copie de la référence à la DataFrame
Une solution simple est de simplement faire ceci:
val df: DataFrame = ....
val df_right = df
df.join(df_right, df("common_field") === df_right("common_field"))
Deux de ces solutions ne fonctionne, et je pouvais voir chaque être utile dans certaines situations. Existe-il des différences internes entre les deux, je devrais être au courant?
OriginalL'auteur David Griffin | 2016-03-27
Vous devez vous connecter pour publier un commentaire.
Il y a au moins deux façons différentes que vous pouvez aborder ce soit par aliasing:
ou à l'aide basée sur le nom de l'égalité des jointures:
En général renommer la colonne, tandis que la plus moche, la plus sûre est de la pratique dans toutes les versions. Il y a eu quelques bugs liés à la colonne de résolution (nous avons trouvé un sur DONC pas si longtemps) et certains détails peuvent différer entre les analyseurs (
HiveContext
/standardSQLContext
) si vous utilisez des premières expressions.Personnellement, je préfère utiliser l'alias à cause de leur ressemblance avec une idiomatiques SQL et la capacité à les utiliser en dehors du cadre de
DataFrame
objets.Ce qui concerne la performance, sauf si vous êtes intéressés à proximité-à-traitement en temps réel, il devrait y avoir aucune différence de performances que ce soit. Toutes ces mesures doivent générer le même plan d'exécution.
DataFrame.as
relativement nouveau?Non, il est là depuis au moins depuis la 1.3. Il n'est pas couramment utilisé. Il ne doit pas être confondu avec
as[U]
qui est utilisé avecDatasets
. Scala et Python ont une alternativealias
méthode qui réalise la même chose.Assez étrangement, je ne vois pas de référence dans le scaladocs, autres que dans l'index. Je vois
as[U]
, mais même quand je vais revenir à des versions antérieures, je ne vois pas deas
dansDataFrame
. Je voisas
dansColumn
, tout simplement pas dansDataFrame
.Vérifier Intégré à une Langue Requêtes section (8e position) ou la source github.com/apache/spark/blob/... 🙂
Pour beaucoup, DONC peut le faire pour vous 🙂
OriginalL'auteur zero323