PyODPS DataFrame permet de combiner des tables à l'aide des opérations join et union. Utilisez join pour faire correspondre les lignes de deux Collections sur une clé partagée ; utilisez union ou concat pour empiler deux Collections ayant le même schéma en une seule.
Opérations couvertes dans cette rubrique :
| Opération | Description |
|---|---|
join |
Jointure interne de deux Collections sur la base de valeurs de colonne correspondantes |
left_join, right_join, outer_join |
Jointures externes ; les colonnes dupliquées sont renommées avec des suffixes |
| Auto-jointure | Jointure d'une Collection avec elle-même à l'aide de view() |
mapjoin |
Exécution d'une opération mapjoin sur la table de droite |
union / concat |
Empilement de deux Collections aux schémas identiques en une seule |
Prérequis
Avant de commencer, assurez-vous d'avoir :
Importé les tables d'exemple dans MaxCompute. Suivez la section « Prepare data » de la rubrique Prise en main
Initialisé les DataFrames
moviesetratingscomme indiqué ci-dessous
from odps.df import DataFrame
movies = DataFrame(o.get_table('pyodps_ml_100k_movies'))
ratings = DataFrame(o.get_table('pyodps_ml_100k_ratings'))
Les deux tables présentent les schémas suivants :
>>> movies.dtypes
odps.Schema {
movie_id int64
title string
release_date string
video_release_date string
_url string
}
>>> ratings.dtypes
odps.Schema {
user_id int64
movie_id int64
rating int64
unix_timestamp int64
}
Opérations de jointure
PyODPS DataFrame joint deux objets Collection et renvoie une nouvelle Collection. Le type de jointure et la formulation de la condition de jointure déterminent conjointement l'apparence des noms de colonne dupliqués dans le résultat.
Jointure interne sur des colonnes portant le même nom
Pour une jointure interne (join), transmettez le nom de la colonne partagée sous forme de chaîne au paramètre on. Le résultat ne conserve qu'une seule copie de la colonne de jointure :
>>> movies.join(ratings, on='movie_id').head(3)
movie_id title release_date video_release_date url user_id rating unix_timestamp
0 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 49 3 888068877
1 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 621 5 881444887
2 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 291 3 874833936
L'omission totale du paramètre on produit le même effet : PyODPS effectue automatiquement la jointure sur toutes les colonnes partageant le même nom.
>>> movies.join(ratings).head(3)
movie_id title release_date video_release_date url user_id rating unix_timestamp
0 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 49 3 888068877
1 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 621 5 881444887
2 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 291 3 874833936
Ce comportement de copie unique s'applique uniquement aux jointures internes. Pour les opérationsleft_join,right_joinetouter_join, les colonnes dupliquées sont toujours renommées avec des suffixes. Consultez la section Jointures externes .
Jointure sur des colonnes portant des noms différents
Lorsque la clé de jointure porte un nom différent dans chaque table, transmettez une liste de tuples (left_col, right_col) au paramètre on :
>>> ratings2 = ratings[ratings.exclude('movie_id'), ratings.movie_id.rename('movie_id2')]
>>> ratings2.dtypes
odps.Schema {
user_id int64
rating int64
unix_timestamp int64
movie_id2 int64
}
>>> movies.join(ratings2, on=[('movie_id', 'movie_id2')]).head(3)
movie_id title release_date video_release_date url user_id rating unix_timestamp movie_id2
0 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 49 3 888068877 3
1 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 621 5 881444887 3
2 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 291 3 874833936 3
Vous pouvez également transmettre directement une expression d'égalité : le résultat est identique.
>>> movies.join(ratings2, on=[movies.movie_id == ratings2.movie_id2]).head(3)
movie_id title release_date video_release_date url user_id rating unix_timestamp movie_id2
0 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 49 3 888068877 3
1 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 621 5 881444887 3
2 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 291 3 874833936 3
Jointures externes
Pour les opérations left_join, right_join et outer_join, PyODPS renomme systématiquement les colonnes dupliquées avec des suffixes afin de préserver les deux valeurs. Les suffixes par défaut sont _x (table de gauche) et _y (table de droite) :
>>> movies.left_join(ratings, on='movie_id').head(3)
movie_id_x title release_date video_release_date url user_id movie_id_y rating unix_timestamp
0 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 49 3 3 888068877
1 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 621 3 5 881444887
2 3 Four Rooms (1995) 01-Jan-1995 http://example.aliyundoc.com/M/title-exact?Four%20Rooms%... 291 3 3 874833936
Étant donné que movie_id apparaît dans les deux tables, le résultat contient movie_id_x (provenant de movies) et movie_id_y (provenant de ratings).
Suffixes personnalisés : Transmettez un tuple de deux éléments au paramètre suffixes pour remplacer les valeurs par défaut :
movies.left_join(ratings, on='movie_id', suffixes=('_movie', '_rating'))
Suppression des colonnes dupliquées : Définissez merge_columns=True pour ne conserver qu'une seule copie de chaque colonne dupliquée. PyODPS sélectionne la valeur non nulle provenant de l'un ou l'autre côté :
movies.left_join(ratings, on='movie_id', merge_columns=True)
Auto-jointure
Pour joindre une Collection à elle-même, créez d'abord une vue à l'aide de view() afin que PyODPS puisse distinguer les côtés gauche et droit :
>>> movies2 = movies.view()
>>> movies.join(movies2, movies.movie_id == movies2.movie_id)[movies, movies2.movie_id.rename('movie_id2')].head(3)
movie_id title_x release_date_x video_release_date_x \
0 2 GoldenEye (1995) 01-Jan-1995 True
1 3 Four Rooms (1995) 01-Jan-1995 True
2 4 Get Shorty (1995) 01-Jan-1995 True
url_x movie_id2
0 http://example.aliyundoc.com/M/title-exact?GoldenEye%20(... 2
1 http://example.aliyundoc.comtitle-exact?Four%20Rooms%... 3
2 http://example.aliyundoc.com/M/title-exact?Get%20Shorty%... 4
Map join
Pour exécuter une opération mapjoin, définissez le paramètre mapjoin sur True. Le système exécute alors l'opération mapjoin sur la table de droite :
movies.join(ratings, on='movie_id', mapjoin=True)
PyODPS prend également en charge la jointure d'une Collection PyODPS avec un DataFrame pandas ou une Collection de base de données. Dans ce cas, la jointure s'exécute sur PyODPS.
Opérations d'union
Utilisez union ou concat pour empiler verticalement deux tables en une seule. Les deux tables doivent posséder les mêmes noms de colonne et types de données. L'ordre des colonnes n'a pas besoin de correspondre : PyODPS aligne les colonnes par nom.
>>> mov1 = movies[movies.movie_id < 3]['movie_id', 'title']
>>> mov2 = movies[(movies.movie_id > 3) & (movies.movie_id < 6)]['title', 'movie_id']
>>> mov1.union(mov2)
movie_id title
0 1 Toy Story (1995)
1 2 GoldenEye (1995)
2 4 Get Shorty (1995)
3 5 Copycat (1995)
PyODPS prend également en charge l'union entre une Collection PyODPS et un DataFrame pandas ou une Collection de base de données. Dans ce cas, l'opération s'exécute sur PyODPS.