Operasi join pada pyspark dataframe dilakukan dengan menggunakan fungsi spark.sql.DataFrame.join().
Jika mengacu pada klausa join dalam SQL statement berikut
SELECT *
FROM Table1 INNER JOIN Table2 ON Table1.field1 = Table2.field2
Pada pyspark join, dataframe pemilik fungsi join akan menjadi dataframe kiri atau dataframe pertama (Table1 pada contoh di atas).
Fungsi join menerima 3 parameter :
- other : dataframe yang akan di-join. Dataframe ini akan menjadi dataframe kanan (Table2 dalam contoh di atas).
- on : Field yang akan menjadi join key
- how : Jenis join, yaitu salah satu dari : inner, outer, cross, left_outer (bisa juga left atau leftouter), right_outer (bisa juga right atau rightouter), full, semi, anti
Data yang akan kita gunakan adalah dua dataframe, masing-masing berisi data mahasiswa dan data jurusan.
data1 = [['Agus','Fisika',130],
['Budi','Biologi',200],
['Bayu','Manajemen',180],
['Dedi','Akuntansi',50]]
kolom1 = ["nama","jurusan","nilai"]
df1 = spark.createDataFrame(data1,kolom1)
df1.show()
data2 = [['Fisika','FIS','MIPA'],
['Biologi','BIO','MIPA'],
['Manajemen','MAN','Ekonomi'],
['Bisnis','BIS','Ekonomi']]
kolom2 = ["jurusan","kode_jurusan","fakultas"]
df2 = spark.createDataFrame(data2,kolom2)
df2.show()
Inner Join
Secara default, pilihan tipe pada pyspark join adalah inner join. Kita bisa melakukan inner join dengan mengisi parameter dataframe kanan dan key join saja, seperti berikut ini. Perhatikan tanda yang digunakan untuk “sama dengan” adalah “==”
inner = df1.join(df2,df1.jurusan==df2.jurusan)
inner.show()
Perhatikan bahwa dataframe hasil join akan menyertakan semua kolom dari dataframe kiri dan kanan, sehingga pasti akan terjadi duplikasi kolom yang menjadi key join. Jika terdapat nama kolom yang sama dari tabel kiri dan kanan, akan terjadi duplikasi kolom dengan nama yang sama.
Hal ini dapat mengakibatkan error ketika kita mencoba mengakses kolom tersebut.
inner["nama","jurusan"].show()
Untuk menyertakan satu saja dari kolom key join, kita dapat menggunakan sintaks list untuk menyatakan parameter join key-nya.
Catatan : hal ini hanya dapat digunakan jika nama join key di kedua dataframe sama.
df1.join(df2, ["jurusan"], "inner").show()
Join Dengan Lebih Dari 1 Key
Untuk melakukan join dengan lebih dari 1 key, gunakan & untuk ‘and’ dan | untuk ‘or’ untuk menggabungkan beberapa kondisi. Masing-masing kondisi dilingkupi tanda kurung.
data1 = [['Agus','Fisika','MIPA',130],
['Budi','Kimia','MIPA',200],
['Bayu','Mesin','Teknik',180],
['Dedi','Kimia','Teknik',50]]
kolom1 = ["nama","jurusan","fakultas", "nilai"]
data2 = [['Kimia','KIM','MIPA'],
['Fisika','FIS','MIPA'],
['Kimia','TKIM','Teknik'],
['Mesin','TMSN','Teknik']]
kolom2 = ["jurusan","kode_jurusan","fakultas"]
dfa = spark.createDataFrame(data1,kolom1)
dfb = spark.createDataFrame(data2,kolom2)
dfa.join(dfb,(dfa.jurusan==dfb.jurusan) &
(dfa.fakultas==dfb.fakultas),"inner").show()
Jika nama kolom key di kedua dataframe sama, dapat digunakan list untuk menghindari duplikasi kolom output.
dfa.join(dfb, ["jurusan","fakultas"]).show()
Left Outer Join
Left outer join atau left join mengembalikan semua baris dan kolom dari dataframe kiri, dan semua kolom dari dataframe kanan yang match. Untuk baris-baris dataframe kiri yang tidak menemukan pasangannya di dataframe kanan, kolom dataframe kanan akan diset null.
Untuk left join kita bisa menggunakan option “left”, “leftjoin”, atau “left_join”
df1.join(df2, ["jurusan"],"left").show()
Right Outer Join
Right outer join atau right join mengembalikan semua baris dan kolom dari dataframe kanan, dan semua kolom dari dataframe kiri yang match. Untuk baris-baris dataframe kanan yang tidak menemukan pasangannya di dataframe kiri, kolom dataframe kiri akan diset null.
Untuk right outer join kita bisa menggunakan option “right”, “rightjoin”, atau “right_join”
df1.join(df2, ["jurusan"],"right").show()
Full Outer Join
Full outer join atau full join mengembalikan semua baris dari dataframe kiri maupun kanan, baik ditemukan pasangannya maupun tidak.
Untuk record di dataframe kiri maupun kanan yang tidak ditemukan pasangannya, kolom yang bersesuaian akan diisi dengan null.
Nilai parameter yang dapat digunakan untuk full outer join adalah “full”, “fullouter”, atau “full_outer”
df1.join(df2, ["jurusan"],"full").show()
Cross Join
Cross join menghasilkan cartesian product atau semua pasangan dari semua baris di dataframe kiri dan kanan, tanpa memperhatikan nilai kolomnya.
Jika kita memiliki 4 baris di dataframe kiri dan 4 di kanan, hasilnya adalah 4x4 = 16 baris.
Pada fungsi join di pyspark dataframe terdapat opsi “cross”, akan tetapi ternyata opsi ini tidak berfungsi sebagaimana mestinya. Untuk menggunakan opsi ini kita perlu mengisi parameter join key. Akan tetapi join dengan cara ini tidak menghasilkan cartesian product dari dua dataframe.
df1.join(df2, ["jurusan"],"cross").show()
Untuk mendapatkan hasil cartesian product dari kedua dataframe dengan fungsi join, kita hanya perlu mengisi nama dataframe kanan saja tanpa parameter on dan how seperti berikut ini :
df1.join(df2).show()
Atau kita bisa melakukannya dengan fungsi crossJoin()
df1.crossJoin(df2).show()
Mutating Join vs Filtering Join
Jika melihat dari duplikasi hasilnya, maka operasi join dapat dibagi menjadi dua jenis, yaitu mutating dan filtering.
Jenis-jenis join sebelumnya, yaitu inner, left, right, dan full join merupakan tipe mutating join. Yaitu operasi join yang akan menghasilkan satu record untuk setiap pasangan yang ditemukan. Ketika terjadi lebih dari 1 pasangan, maka join akan menghasilkan lebih dari 1 baris juga.
Ketika 1 baris dataframe kiri menemukan 2 baris pasangan di dataframe kanan, join akan mengembalikan 2 baris (duplikasi record kiri). Demikian juga jika 1 baris dataframe kanan menemukan 2 baris pasangan di dataframe kanan, akan dikembalikan 2 baris (duplikasi record kanan).
Misalnya untuk dataframe berikut ini
data_dup = [['Agus','Fisika',130],
['Budi','Biologi',200],
['Bayu','Manajemen',180],
['Dedi','Akuntansi',50],
['Andi','Manajemen',80]]
kolom = ["nama","jurusan","nilai"]
df_dup = spark.createDataFrame(data_dup,kolom)
df_dup.show()
dataref_dup = [['Biologi','BIO','MIPA'],
['Fisika','FIS','MIPA'],
['Bisnis','BIS','Ekonomi'],
['Manajemen','MAN','Ekonomi'],
['Manajemen','MNG','Ekonomi']]
kolom = ["jurusan","kode_jurusan","fakultas"]
ref_dup = spark.createDataFrame(dataref_dup,kolom)
ref_dup.show()
Inner, left, right, maupun full join akan mengembalikan 4 baris data jurusan Manajemen.
Secara default mutating join juga mengembalikan semua kolom dari dataframe kiri maupun kanan.
df_dup.join(ref_dup, ["jurusan"], "inner").show()
Pada filtering join, jika ditemukan lebih dari 1 match maka hanya akan dikembalikan 1 record saja. Filtering join hanya akan mengembalikan kolom dari satu dataframe saja. Terdapat 2 jenis filtering join yang biasa digunakan, yaitu (left) semi join dan (left) anti join.
Semi Join
Semi join atau disebut juga left semi join, adalah operasi join yang mengembalikan record-record dari dataframe kiri yang ditemukan pasangannya di dataframe kanan. Semi join juga hanya akan mengembalikan kolom-kolom dari dataframe kiri saja.
df_dup.join(ref_dup, ["jurusan"], "semi").show()
Perhatikan bahwa meskipun terdapat dua record untuk jurusan Manajemen di dataframe kanan, semi join tidak menduplikasi hasil joinnya.
Jika dataframe kiri berupa data transaksi dan dataframe kanan berupa data reference, proses ini semacam filtering record-record transaksi yang sesuai dengan data reference.
Anti Join
Anti join atau left anti join mengembalikan record-record dataframe kiri yang tidak ditemukan di dataframe kanan.
df_dup.join(ref_dup, ["jurusan"], "anti").show()
Jika dataframe kiri berupa data transaksi dan dataframe kanan berupa data reference, proses ini semacam filtering record-record transaksi yang tidak ditemukan referencenya.
Notebook untuk artikel ini dapat diakses di sini
Artikel sebelumnya: