LoginSignup
2
1

More than 1 year has passed since last update.

PySparkでこういう場合はどうしたらいいのかをまとめた逆引きPySparkシリーズの結合編です。
(随時更新予定です。)

  • 原則としてApache Spark 3.3のPySparkのAPIに準拠していますが、一部、便利なDatabricks限定の機能も利用しています(利用しているところはその旨記載しています)。
  • Databricks Runtime 11.3 上で動作することを確認しています。
  • ノートブックをこちらのリポジトリ からReposにてご使用のDatabricksの環境にダウンロードできます。
  • 逆引きPySparkの他の章については、こちらの記事をご覧ください。

5-1 Join

5-1-1 内部結合 (INNER JOIN)

内部結合 (INNER JOIN)は、結合のキーとなる列の値がマッチする行同士を連結することで2つのデータフレームを結合します。キーの列の値が片方のデータフレームにしか存在しない場合は、その行は出力されません

データフレームのjoin()メソッドを使い、最初の引数として内部結合をしたい相手のデータフレームを指定します。

以下のデータフレーム1、データフレーム2をramen_idという列を結合のキーとして内部結合するとした場合について説明します。

データフレーム1(df_ramen)
ramen_id name price
1 醤油ラーメン 600
2 塩ラーメン 700
3 豚骨醤油ラーメン 900
4 味噌ラーメン 800
データフレーム2(df_topping)
ramen_id name
1 チャーシュー
2 味玉
3 チャーシュー
3 ニンニク

結合のキーとなる列名が両方のデータフレームで共通している場合、構文1のように列名を第2引数で指定します。

# 構文1
df_1.join( df_2, <結合のキーとなる列>, "inner" )

# 例文1
df_ramen.join( df_topping, "ramen_id", "inner" )

構文2のように、それぞれのデータフレームの列名を指定し、結合のための条件式を第2引数にすることもできます。

# 構文2
df_1.join( df_2, <結合の条件>, "inner" )

# 例文2
df_ramen.join( df_topping, df_ramen.ramen_id == df_topping.ramen_id, "inner" )

構文1の場合の出力例は以下になります。

内部結合されたデータフレーム
ramen_id name price name
1 醤油ラーメン 600 チャーシュー
2 塩ラーメン 700 味玉
3 豚骨醤油ラーメン 900 チャーシュー
3 豚骨醤油ラーメン 900 ニンニク

5-1-2 左外部結合 (LEFT OUTER JOIN)

左外部結合 (LEFT OUTER JOIN)は、結合の基準となる左側のデータフレームの行に、キーとなる列の値がマッチする右側のデータフレームの行を連結することで2つのデータフレームを結合します。左側のデータフレームのキーとなる列の値が右側のデータフレームに存在しない場合でも、左側のデータフレームの該当行は出力されます(右側のデータフレームの該当の情報はnullとして出力されます)。

左外部結合の基準となる左側のデータフレームのjoin()メソッドを使い、最初の引数として相手の(右側の)データフレームを指定します。

以下のデータフレーム1、データフレーム2をramen_idという列を結合のキーとして左外部結合するとした場合について説明します。

データフレーム1(df_ramen)
ramen_id name price
1 醤油ラーメン 600
2 塩ラーメン 700
3 豚骨醤油ラーメン 900
4 味噌ラーメン 800
データフレーム2(df_topping)
ramen_id name
1 チャーシュー
2 味玉
3 チャーシュー
3 ニンニク

結合のキーとなる列名が両方のデータフレームで共通している場合、構文1のように列名を第2引数で指定します。

# 構文1
df_1.join( df_2, <結合のキーとなる列>, "left" )

# 例文1
df_ramen.join( df_topping, "ramen_id", "left" )

構文2のように、それぞれのデータフレームの列名を指定し、結合のための条件式を第2引数にすることもできます。

# 構文2
df_1.join( df_2, <結合の条件>, "left" )

# 例文2
df_ramen.join( df_topping, df_ramen.ramen_id == df_topping.ramen_id, "left" )

構文1の場合の出力例は以下になります。

左外部結合されたデータフレーム
ramen_id name price name
1 醤油ラーメン 600 チャーシュー
2 塩ラーメン 700 味玉
3 豚骨醤油ラーメン 900 ニンニク
3 豚骨醤油ラーメン 900 チャーシュー
4 味噌ラーメン 800 null

5-1-3 クロス結合 (CROSS JOIN)

クロス結合 (CROSS JOIN)は、結合する両方のデータフレームの全ての行の組み合わせを出力します。結果として、両側のデータフレームそれぞれの行数を掛け合わせた数の行が出力されます。

データフレームのcrossJoin()メソッドを使い、引数としてクロス結合の相手のデータフレームを指定します。結合のキーは不要なため、引数は1つだけです。

以下、データフレーム1、データフレーム2をクロス結合するとした場合について説明します。

データフレーム1(df_ramen)
ramen_id name price
1 醤油ラーメン 600
2 塩ラーメン 700
3 豚骨醤油ラーメン 900
4 味噌ラーメン 800
データフレーム2(df_topping)
ramen_id name
1 チャーシュー
2 味玉
3 チャーシュー
3 ニンニク

結合のキーとなる列名が両方のデータフレームで共通している場合、構文1のように列名を第2引数で指定します。

# 構文1
df_1.crossJoin( df_2 )

# 例文1
df_ramen.crossJoin( df_topping )
クロス結合されたデータフレーム
ramen_id name price ramen_id name
1 醤油ラーメン 600 1 チャーシュー
1 醤油ラーメン 600 2 味玉
1 醤油ラーメン 600 3 チャーシュー
1 醤油ラーメン 600 3 ニンニク
2 塩ラーメン 700 1 チャーシュー
2 塩ラーメン 700 2 味玉
2 塩ラーメン 700 3 チャーシュー
2 塩ラーメン 700 3 ニンニク
3 豚骨醤油ラーメン 900 1 チャーシュー
3 豚骨醤油ラーメン 900 2 味玉
3 豚骨醤油ラーメン 900 3 チャーシュー
3 豚骨醤油ラーメン 900 3 ニンニク
4 味噌ラーメン 800 1 チャーシュー
4 味噌ラーメン 800 2 味玉
4 味噌ラーメン 800 3 チャーシュー
4 味噌ラーメン 800 3 ニンニク

5-2 Union

5-2-1 Union データフレームを縦方向に結合する

2つのデータフレームを縦方向に結合(Union結合)します。SQLのUNION ALLとは異なり重複行がある場合でも許容されます。そのため、結合結果から重複を削除したい場合はUnion結合したデータフレームに対してさらにdistinct()を実行する必要があります。また、列の結合は、列の順番のみが考慮されます。列名が同じもの同士をUnion結合したい場合はunionByName()を使う必要があります。

データフレームのunion()メソッドを使い、最初の引数としてUnion結合をしたい相手のデータフレームを指定します。

以下のデータフレーム1、データフレーム2をUnion結合するとした場合について説明します。

データフレーム1(df_ramen)
ramen_id name price
1 醤油ラーメン 600
2 塩ラーメン 700
3 豚骨醤油ラーメン 900
4 味噌ラーメン 800
データフレーム2(df_topping)
ramen_id price name
5 700 鶏白湯ラーメン
6 800 濃厚とんこつラーメン
7 600 塩つけめん
# 構文
df_1.union( df_2 )

# 例文
df_ramen.union( df_ramen_2 )
Union(ByName)結合されたデータフレーム
ramen_id name price
1 醤油ラーメン 600
2 塩ラーメン 700
3 豚骨醤油ラーメン 900
4 味噌ラーメン 800
5 700 鶏白湯ラーメン
6 800 濃厚とんこつラーメン
7 600 塩つけめん

5-2-2 列名を考慮してUnion (データフレームを縦方向に結合する)

2つのデータフレームを縦方向に結合(Union結合)します。5-2-1とは異なり、列の順番に関わらず、結合相手のデータフレームで同じ列名の列をUnion結合します。SQLのUNION ALLとは異なり重複行がある場合でも許容されます。そのため、結合結果から重複を削除したい場合はUnion結合したデータフレームに対してさらにdistinct()を実行する必要があります。

データフレームのunionByName()メソッドを使い、最初の引数としてUnion結合をしたい相手のデータフレームを指定します。

以下のデータフレーム1、データフレーム2をUnion結合するとした場合について説明します。

データフレーム1(df_ramen)
ramen_id name price
1 醤油ラーメン 600
2 塩ラーメン 700
3 豚骨醤油ラーメン 900
4 味噌ラーメン 800
データフレーム2(df_topping)
ramen_id price name
5 700 鶏白湯ラーメン
6 800 濃厚とんこつラーメン
7 600 塩つけめん
# 構文
df_1.unionByName( df_2 )

# 例文
df_ramen.unionByName( df_ramen_2 )
Union(ByName)結合されたデータフレーム
ramen_id name price
1 醤油ラーメン 600
2 塩ラーメン 700
3 豚骨醤油ラーメン 900
4 味噌ラーメン 800
5 鶏白湯ラーメン 700
6 濃厚とんこつラーメン 800
7 塩つけめん 600
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1