Belajar PySpark - MapType pada DataFrame Schema
PySpark MapType memungkinkan kita untuk menggambarkan kolom yang berisi data dalam format map atau dictionary. Dalam artikel ini, kita akan membahas cara mendefinisikan MapType, cara mengakses elemennya, dan beberapa fungsi terkait seperti explode(), map_keys(), dan map_values().
Sebelumnya, seperti biasa kita import package yang akan digunakan dan kita buat dahulu spark session.
import pyspark
from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StructField, ArrayType, MapType, StringType, IntegerType
from pyspark.sql.functions import array_contains, explode, split, array
spark = SparkSession.builder.appName("Belajar PySpark - MapType").getOrCreate()
Mendefinisikan PySpark MapType
MapTypeadalah tipe data kompleks yang memungkinkan kita menyimpan pasangan kunci-nilai dalam satu kolom DataFrame. Ini sangat berguna untuk menyimpan data yang memiliki struktur yang tidak teratur atau dapat berubah, seperti misalnya pada format JSON.
Contoh definisi MapType dalam skema DataFrame : mySchema = StructType([
StructField("nama", StringType(), True), StructField("jurusan", StringType(), True),
StructField("nilai", MapType(StringType(), IntegerType()), True) ])
Dalam contoh ini kita mendefinisikan kolom bertipe key:value mapping, di mana key-nya bertipe string, dan value bertipe integer
Data yang digunakan adalah
data = [['Agus Supono','F',{"uts":100,"uas":150,"tugas":150}], ['Budi Sumardi','B',{"uts":200,"uas":100,"tugas":150}], ['Dina Mariana','F',{"uts":150,"uas":150,"tugas":130}], ['Dedi Setiadi','B',
{"uts":50,"uas":100,"tugas":100,"remedial":100}]]
Untuk menggunakan skema di atas dalam DataFrame : df = spark.createDataFrame(data, mySchema) df.show(truncate=False)
df.printSchema()
+---+---+---+
|nama |jurusan|nilai |
+---+---+---+
|Agus Supono |F |{tugas -> 150, uts -> 100, uas -> 150} |
|Budi Sumardi|B |{tugas -> 150, uts -> 200, uas -> 100} |
|Dina Mariana|F |{tugas -> 130, uts -> 150, uas -> 150} |
|Dedi Setiadi|B |{tugas -> 100, remedial -> 100, uts -> 50, uas -> 100}|
+---+---+---+
root
|-- nama: string (nullable = true)
|-- jurusan: string (nullable = true)
|-- nilai: map (nullable = true)
| |-- key: string
| |-- value: integer (valueContainsNull = true)
Mengakses MapType kolom
Ada beberapa cara untuk mengakses value dari kolom bertipe map.
Yang pertama kita dapat mengakses kolom bertipe map dengan menggunakan fungsi DataFrame.Column.getItem(keyname), dan menggunakan alias() untuk memberikan nama kolom hasil query.
df.select(df.nama, df.jurusan,
df.nilai.getItem("uts").alias("UTS"), df.nilai.getItem("uas").alias("UAS"),
df.nilai.getItem("tugas").alias("TUGAS")).show()
+---+---+---+---+---+
| nama|jurusan|UTS|UAS|TUGAS|
+---+---+---+---+---+
| Agus Supono| F|100|150| 150|
|Budi Sumardi| B|200|100| 150|
|Dina Mariana| F|150|150| 130|
|Dedi Setiadi| B| 50|100| 100|
+---+---+---+---+---+
Kita juga dapat mengakses value dengan menggunakan key sebagai indeks, yaitu dengan sintaks DataFrame.Column[keyname]
df.select(df.nama, df.jurusan,
df.nilai["uts"].alias("UTS"), df.nilai["uas"].alias("UAS"),
df.nilai["tugas"].alias("TUGAS")).show() +---+---+---+---+---+
| nama|jurusan|UTS|UAS|TUGAS|
+---+---+---+---+---+
| Agus Supono| F|100|150| 150|
|Budi Sumardi| B|200|100| 150|
|Dina Mariana| F|150|150| 130|
|Dedi Setiadi| B| 50|100| 100|
+---+---+---+---+---+
Fungsi-fungsi MapType
Beberapa fungsi terkait MapType yaitu map_keys(), map_values(), dan explode()
Fungsi map_keys()
Fungsi ini mengembalikan array yang berisi semua key dari map.
from pyspark.sql.functions import map_keys
df.select(df.nama,df.jurusan,map_keys(df.nilai)) \ .show(truncate=False)
+---+---+---+
|nama |jurusan|map_keys(nilai) |
+---+---+---+
|Agus Supono |F |[tugas, uts, uas] |
|Budi Sumardi|B |[tugas, uts, uas] |
|Dina Mariana|F |[tugas, uts, uas] |
|Dedi Setiadi|B |[tugas, remedial, uts, uas]|
+---+---+---+
Fungsi map_values()
Fungsi ini mengembalikan array yang berisi semua value dari map from pyspark.sql.functions import map_values
df.select(df.nama,df.jurusan,map_values(df.nilai)) \ .show(truncate=False)
+---+---+---+
|nama |jurusan|map_values(nilai) | +---+---+---+
|Agus Supono |F |[150, 100, 150] |
|Budi Sumardi|B |[150, 200, 100] |
|Dina Mariana|F |[130, 150, 150] |
|Dedi Setiadi|B |[100, 100, 50, 100]|
+---+---+---+
Fungsi explode
Fungsi explode digunakan untuk mengubah setiap pasangan key-value menjadi satu baris atau record tersendiri. Misalnya untuk contoh di atas :
from pyspark.sql.functions import explode
df.select(df.nama,df.jurusan,explode(df.nilai)) \ .show(truncate=False)
+---+---+---+---+
|nama |jurusan|key |value|
+---+---+---+---+
|Agus Supono |F |tugas |150 |
|Agus Supono |F |uts |100 |
|Agus Supono |F |uas |150 |
|Budi Sumardi|B |tugas |150 |
|Budi Sumardi|B |uts |200 |
|Budi Sumardi|B |uas |100 |
|Dina Mariana|F |tugas |130 |
|Dina Mariana|F |uts |150 |
|Dina Mariana|F |uas |150 |
|Dedi Setiadi|B |tugas |100 |
|Dedi Setiadi|B |remedial|100 |
|Dedi Setiadi|B |uts |50 |
|Dedi Setiadi|B |uas |100 | +---+---+---+---+
Wrapping Up
MapType merupakan tipe data yang berfungsi sebagai struktur penyimpanan pasangan key-value, menyerupai konsep Kamus (Dictionary) pada Python. Dalam MapType, key dan value haruslah merupakan tipe data yang mengikuti atau diperluas dari DataType yang spesifik.
Key dalam MapType tidak akan menerima nilai yang kosong (null/None), sementara value dari key map bisa memiliki nilai yang kosong (None/Null).
Penggunaan mapType memberikan keunggulan dalam penyederhanaan dan penyesuaian data.
Fungsi ini memungkinkan penyederhanaan struktur data map, yang kadang-kadang kompleks, untuk memfasilitasi analisis data yang lebih efektif.
Notebook untuk tutorial ini dapat diakses di sini
https://github.com/urfie/Seri-Belajar-PySpark/blob/main/Belajar_PySpark_MapType_pada_Ske ma_DataFrame.ipynb
Artikel sebelumnya
● ArrayType pada DataFrame Schema
● Nested Schema pada DataFrame
● Definisi Skema pada DataFrame
● Membaca File JSON
● Membaca File csv ke DataFrame
● Memproses Dataframe dengan Temporary View dan SQL