Belajar PySpark - MapType pada DataFrame Schema

belajar-pyspark-maptype

PySpark MapType memungkinkan kita untuk menggambarkan kolom yang berisi data dalam format map atau dictionary. Pada seri Belajar PySpark kali 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

MapType adalah 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 Kolom MapType

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

Artikel seri Belajar PySpark sebelumnya: