LoginSignup
24
12

More than 3 years have passed since last update.

pysparkのJoin個人的まとめ

Last updated at Posted at 2018-12-21

はじめに

Pysparkでデータをいじくっている際にjoinをする事があるのですが、joinの内容を毎回確認するので確認用のページを作成しようかと思い立ち。
SQLが頭に入っていれば問題ないのでしょうが、都度調べれば良いと思ってるので
pythonは3系、pysparkは2.0系(2.4あたり)を想定しています。

やること

以下のコードで作成したdf_1df_2について、df_1に対してidでdf_2をjoinします。
片方だけにidがあったり、重複してたり、など考慮してjoinの種類全パターンでの動作を確認できるようなDataFrameにしているつもりです。

sample.py
df_1 = spark.createDataFrame(
    [('a', "1_a1",), 
     ('a', "1_a2", ), 
     ('b', "1_b1", ),
     ('b', "1_b2", ), 
     ('c', "1_c1", ),
     ('d', "1_d1", ),
     ('e', "1_e1", ),],
    ['id', 'data',])

df_2 = spark.createDataFrame(
    [('a', "2_a1",), 
     ('b', "2_b1", ),
     ('b', "2_b2", ), 
     ('c', "2_c1", ),
     ('d', "2_d1", ),
     ('d', "2_d2", ),
     ('f', "2_f1", ),],
    ['id', 'data',])

作成されるDataframeはこんな感じ

df_1のDataframe
id data
a 1_a1
a 1_a2
b 1_b1
b 1_b2
c 1_c1
d 1_d1
e 1_e1
df_2のDataframe
id data
a 2_a1
b 2_b1
b 2_b2
c 2_c1
d 2_d1
d 2_d2
f 2_f1

以下コードの"how"の部分を変えて実行した際に出来上がるDataFrameを纏めていきます。

sample.py

# howの種類はこれだけあり、同じ行のものは同じ動作をする(はず)
# inner
# cross, 
# outer, full, full_outer
# left, left_outer
# right, right_outer
# left_semi
# left_anti
result = df_1.join(df_2, df_1.id == df_2.id, "how")

結果

inner

一言メモ

  • とりあえず共通のものを残したい時に使う
  • 両方のdfに共通のidが残る
  • 該当行の組み合わせ分、データが増える
    • df_1のa(2行) x df_2のa(1行) → aが2行
    • df_1のb(2行) x df_2のb(2行) → bが4行
    • df_1のd(1行) x df_2のd(2行) → dが2行
id data id data
a 1_a1 a 2_a1
a 1_a2 a 2_a1
b 1_b1 b 2_b1
b 1_b1 b 2_b2
b 1_b2 b 2_b1
b 1_b2 b 2_b2
c 1_c1 c 2_c1
d 1_d1 d 2_d1
d 1_d1 d 2_d2

cross

一言メモ

  • innerと同じ(データ不備?)
id data id data
a 1_a1 a 2_a1
a 1_a2 a 2_a1
b 1_b1 b 2_b1
b 1_b1 b 2_b2
b 1_b2 b 2_b1
b 1_b2 b 2_b2
c 1_c1 c 2_c1
d 1_d1 d 2_d1
d 1_d1 d 2_d2

outer, full, full_outer

一言メモ

  • とりあえず全て残したい時に使う
  • 対応が無いものも残る
  • inner + 対応の無いもの
    • df_1のみe、df_2のみfがある → 対応の無いところはNoneで残る
id data id data
None None f 2_f1
a 1_a1 a 2_a1
a 1_a2 a 2_a1
b 1_b1 b 2_b1
b 1_b1 b 2_b2
b 1_b2 b 2_b1
b 1_b2 b 2_b2
c 1_c1 c 2_c1
d 1_d1 d 2_d1
d 1_d1 d 2_d2
e 1_e1 None None

left, left_outer

一言メモ

  • 左(df_1、joinされる方)を残したい時に使う
  • 左を基準にjoin
  • inner + 左で対応の無いもの
    • df_1のみeがある → 対応の無いところはNoneで残る
id data id data
a 1_a1 a 2_a1
a 1_a2 a 2_a1
b 1_b1 b 2_b1
b 1_b1 b 2_b2
b 1_b2 b 2_b1
b 1_b2 b 2_b2
c 1_c1 c 2_c1
d 1_d1 d 2_d1
d 1_d1 d 2_d2
e 1_e1 None None

right, right_outer

一言メモ

  • 右(df_2、joinする方)を残したい時に使う
  • 右を基準にjoin
  • inner + 右で対応の無いもの
    • df_2のみfがある → 対応の無いところはNoneで残る
id data id data
None None f 2_f1
a 1_a1 a 2_a1
a 1_a2 a 2_a1
b 1_b1 b 2_b1
b 1_b2 b 2_b1
b 1_b1 b 2_b2
b 1_b2 b 2_b2
c 1_c1 c 2_c1
d 1_d1 d 2_d1
d 1_d1 d 2_d2

left_semi

一言メモ

  • 左の共通部のみ残したい場合に使う
  • 左を基準に、左と右とで共通のものが残る
  • 右のデータは残らない
    • df_1のid、data列が1つずつ残る
  • idに重複があってもなくても動作は変わらない
    • df_1のa(2行) x df_2のa(1行) → aが2行
    • df_1のb(2行) x df_2のb(2行) → bが2行
id data
a 1_a1
a 1_a2
b 1_b1
b 1_b2
c 1_c1
d 1_d1

left_anti

一言メモ

  • 左の非共通部のみ残したい場合に使う
  • 左を基準に、左と右とで共通ではないものが残る
  • 右のデータは残らない
    • df_1のid、data列が1つずつ残る
id data
e 1_e1

  • pysparkのバージョンによってhowが増えたり動作が変わってくる(と思われる)ので注意
  • SQLと微妙に動作が異なる(innerとかでidが重複して残るとか)ので注意
24
12
2

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
24
12