このトピックでは、Alibaba Cloud MaxCompute SDK for Python (PyODPS) DataFrameでサポートされている、テーブル内のデータをマージする結合および結合操作について説明します。
前提条件
テーブルデータがインポートされます。 入門の「データの準備」セクションの指示に基づいてデータをダウンロードできます。 次のコードは、テーブルの構造を示しています。
>>> from odps.df import DataFrame
>>> movies = DataFrame(o.get_table('pyodps_ml_100k_movies'))
>>> ratings = DataFrame(o.get_table('pyodps_ml_100k_ratings'))
>>> 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
}
結合操作
PyODPS DataFrameでは、2つのコレクションオブジェクトを結合
できます。
join
条件を指定しない場合、DataFrame APIは同じ名前の列を使用してCollectionオブジェクトを結合
します。>>> 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
join
条件を明示的に指定できます。join
操作の場合、2つのDataFrameオブジェクトのon
conditionで指定された列名が同じ場合、システムは新しいテーブルの2つのテーブルのいずれかで指定された列を使用します。>>> 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
left join
などの他のタイプのjoin
操作の場合、2つのCollectionオブジェクトのon条件で指定された列名が同じ場合、システムは新しいテーブルの指定された列の名前を変更します。>>> 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
上記のサンプルコードでは、2つの
movie_id
列の名前がmovie_id_x
およびmovie_id_y
に変更されています。 名前変更ルールは、suffixes
パラメーターによって異なります。 サフィックスパラメーターのデフォルト値は('_x', '_y')
です。 同じ名前の列が見つかった場合、システムは指定されたサフィックスを使用して列の名前を変更します。>>> 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
また、新しいテーブルの列の名前を変更するため
on
、条件の等しい演算子を使用する式を指定することもできます。>>> 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
self join
操作を実行する場合は、view
メソッドを呼び出して、左右のテーブルから列を取得できます。>>> 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
PyODPS DataFrameは、
join
操作に加えて、left join
、right join
、およびouter join
操作をサポートします。 左結合、右結合、および外側結合操作では、名前が変更された列の末尾にデフォルトで_x
または_y
が付いています。 2tuple
を使用して、suffixes
パラメーターのサフィックスを定義できます。left join、right join、またはouter join操作を実行すると、
merge_columns
パラメーターをTrueに設定して、新しいテーブルで列が重複しないようにすることができます。 次に、システムは、重複列からnull以外の値を新しい列の値として選択します。>>> movies.left_join(ratings, on='movie_id', merge_columns=True)
mapjoin
操作を実行する場合は、mapjoin
をTrueに設定します。 次に、システムは右側のテーブルに対してmapjoin
操作を実行します。 PyODPSコレクションとPandasコレクションに対して別々にjoin
操作を実行できます。 PyODPSコレクションとデータベースコレクションでjoin
操作を別々に実行することもできます。 この場合、計算はPyODPSで行われる。
組合作戦
2つのテーブルのフィールドとフィールドタイプが同じである場合、2つのテーブルのフィールドシーケンスが同じであるかどうかに関係なく、union
またはconcat
を使用して2つのテーブルを1つのテーブルにマージできます。
>>> 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コレクションとPandasコレクションに対して別々にunion
操作を実行できます。 PyODPSコレクションとデータベースコレクションでunion
操作を別々に実行することもできます。 この場合、計算はPyODPSで行われる。