Data Manipulation with Pandas — Part 1

DQLab Career Track Module

Sharon Michelle Claudya Cindra
36 min readNov 14, 2020
Ilustrasi Python.

Halo teman-teman semuanya….. Kali ini, setelah kita membahas library serta fungsi-fungsi dasar yang digunakan dalam Python pada module sebelumnya, kali ini kita akan lanjut ke pembahasan yang lebih mendalam yaitu module Manipulation Data with Pandas — Part 1. Sama seperti pada module sebelumnya, kita akan tetap ditemani oleh Andra saat memperdalam pemahaman kita di module ini. Di sini, kita akan mempelajari langkah-langkah yang diperlukan untuk mengolah data menggunakan fungsi dari Pandas. Dan, di puncak module kali ini, kita akan mengerjakan project yang langsung diberikan Andra kepada kita. Wow, seru kan?

Meskipun pembahasannya lebih mendalam, kalian ngga perlu kuatir, karena materinya disajikan secara ringkas dan padat sehingga lebih mudah dimengerti. Selain itu, supaya kita ngga cepat lupa sama materi yang sudah diberikan, kita bisa langsung praktek lho, di code editor yang sudah disediakan. Penasaran kan, sama serunya module ini? Nah, daripada penasaran terus, yuk coba asah kemampuan Python-mu di DQLab, sebuah Platform online khusus untuk mengasah skill Data Scientist-mu. Ngga cuma belajar Python aja, di sana kita juga bakalan disediakan module R dan SQL yang mampu mempersiapkan kita untuk menganalisis data sesuai dengan kasus riil di bidang industri data.

Nah, kembali ke pembahasan kita tadi, pada pembahasan module ini kita akan mulai dengan:

Memanggil library Pandas

Pandas adalah library Python bersifat open source yang biasanya digunakan untuk kebutuhan data analisis. Pandas berperan penting dalam membantu Python agar kita dapat dengan cepat mengolah data, menggabungkan data, dan lain-lain fungsi yang ditawarkan oleh Pandas.

Sebelum memulai menggunakan Pandas ini, kita wajib mengimport dulu Pandas library di Python script yang telah tersedia.

Perintah untuk mengimport library Pandas.

Pada saat kita menggunakan library Pandas, biasanya library Numpy juga perlu diimport, sehingga perintahnya menjadi

Perintah untuk mengimport library NumPy.

Dataframe vs Series

Di Pandas, terdapat 2 kelas data yang umum digunakan sebagai struktur dari spreadsheet, yaitu series dan dataframe. Hmmm…. Seperti apa perbedaan dari kedua kelas data ini?

1) Series, berupa satu kolom bagian dari tabel dataframe dengan bentuk 1 dimensional numpy array sebagai basis data nya. Series ini terdiri dari 1 tipe data, bisa berupa integer, string, float, dan lain-lain.

2) Dataframe, merupakan gabungan dari Series serta berbentuk rectangular data yang merupakan tabel spreadsheet itu sendiri. Karena dibentuk dari banyak series, tiap seriesnya biasanya memiliki 1 tipe data. Itu berarti, 1 dataframe bisa memiliki banyak tipe data.

Seperti pada contoh berikut, kita akan mencoba membuat sebuah series bernama number_list yang terdiri dari 6 elemen.

Perintah untuk membuat series number_list.

Kemudian, kita akan mencoba membuat dataframe bernama matrix_list dari sebuah list_of_list yang bernama matrix. yang terdiri dari 4 kolom serta 3 baris. Di sini, kita masih belum mencantumkan nama index dan kolomnya sehingga yang akan ditampilkan adalah index dan kolom defaultnya saja.

Perintah untuk membuat dataframe matrix_list.

Atribut dataframe dan series

Dataframe dan Series memiliki sangat banyak atribut yang digunakan untuk transformasi data, tetapi ada beberapa attribute yang sering dipakai. Di sini, kita akan menggunakan series number_list dan dataframe matrix_list sebagai contoh dalam praktek kita seperti yang diilustrasikan dalam gambar berikut.

Ilustrasi number_list dan matrix_list yang akan kita gunakan dalam pembahasan kali ini.

Tampilan output yang ada di console untuk masing-masing penggunaan atribut di bawah ini merupakan hasil yang diperoleh setelah penulisan seluruh kode pada code editor.

1) Attribute .info()

Digunakan untuk mengecek kolom apa yang membentuk dataframe itu, mulai dari tipe data, jumlah data yang bernilai non null hingga tipe data pada setiap kolom. Atribut ini tidak dapat digunakan pada series, melainkan hanya pada dataframe saja.

Misalnya, kita akan menerapkan atribut ini terhadap dataframe matrix_list seperti pada potongan kode berikut.

Perintah untuk mengecek data info dari matrix_list.

Dari output yang dihasilkan, terlihat bahwa dataframe matrix_list sama sekali tidak memiliki nilai null di dalamnya. Hal tersebut terlihat dari jumlah nilai non-null pada setiap kolomnya yang jumlahnya sama seperti jumlah data entri yang masuk, yaitu 4. Adapun ketiga kolom yang ada dalam dataframe tersebut bertipe object semua.

Info dari matrix_list.

2) Attribute .shape

Digunakan untuk mengetahui jumlah baris dan kolom dari suatu dataframe atau list. Hasilnya berupa sebuah format tuple yang berturut-turut terdiri dari jumlah baris dan kolom (baris, kolom).

Seperti pada contoh berikut, kita akan mencoba mengecek jumlah baris dan kolom masing-masing dari series number_list dan dataframe matrix_list.

Perintah untuk mengecek jumlah baris dan kolom dari number_list dan matrix_list.

Dari output yang dihasilkan, terlihat bahwa jumlah baris dan kolom dari number_list adalah 6 dan 1, sementara jumlah baris dan kolom dari matrix_list masing-masing adalah 4 dan 3.

Output yang menjunjukkan jumlah baris dan kolom dari number_list dan matrix_list.

3) Attribute .dtypes

Atribut ini digunakan untuk mengetahui tipe data dari setiap kolom pada sebuah dataframe ataupun list. Buat sekedar pengingat saja, data bertipe object adalah kombinasi dari berbagai tipe data, entah itu number, text, dan sebagainya. Pada contoh berikut, kita akan menerapkan fungsi ini pada number_list dan matrix_list.

Perintah untuk mengecek tipe kolom dari number_list dan matrix_list.

Dari output yang dihasilkan, terlihat bahwa tipe data kolom pada number_list adalah int64, sementara itu tipe data pada semua kolom di matrix_list adalah object.

Output yang menunjukkan tipe kolom dari number_list dan matrix_list.

4) Attribute .astype(nama_tipe_data)

Atribut ini berperan dalam melakukan convert terhadap tipe data, seperti float, int, str, numpy.float, numpy.int ataupun numpy.datetime. Atribut ini dapat digunakan baik pada series maupun dataframe.

Seperti pada contoh berikut, kita akan menerapkan metode ini terhadap number_list dan matrix_list.

Perintah untuk convert number_list dan matrix_list menjadi string.

Maka, dari output yang dihasilkan, terlihat jelas bahwa kolom pada number_list telah berubah tipenya menjadi object. Karena matrix_list berbentuk dataframe, maka kita tidak bisa melihat secara langsung tipenya.

Hasil convert number_list dan matrix_list menjadi string.

5) Attribute .copy()

Digunakan untuk melakukan duplikat yang selanjutnya disimpan pada sebuah variable yang berbeda supaya kita tidak perlu lagi melakukan loading terhadap data tersebut.

Sebagai contoh, kita akan mencoba menggunakan atribut ini terhadap number_list serta matrix_list. Masing-masing hasil copy dari data tersebut akan disimpan dalam variabel num_list dan mtr_list.

Perintah untuk mengopy number_list dan matrix_list.

Maka, output yang dihasilkan adalah data-data dari number_list dan matrix_list yang telah dicopy persis seperti aslinya.

Hasil copy-an dari number_list dan matrix_list.

6) Attribute .to_list()

Digunakan untuk mengubah series menjadi list serta tidak dapat digunakan pada dataframe. Sebagai contoh, kita akan menerapkan fitur ini untuk mengubah series number_list menjadi sebuah list.

Perintah untuk mengubah number_list menjadi sebuah list.

Hasil yang didapat adalah sebuah list dari series number_list dimana data-datanya telah berubah menjadi elemen dalam list tersebut. Elemen-elemennya yang semula disusun dalam suatu baris kini telah dipisahkan dengan tanda koma (,) seperti seharusnya.

Hasil dari mengubah number_list menjadi sebuah list.

7) Attribute .unique()

Atribut ini berperan menghasilkan nilai unik dari suatu kolom yang dibungkus dalam bentuk numpy array. Atribut ini hanya digunakan pada series saja.

Misalnya, kita akan mencoba mencari nilai unik dari data-data pada number_list dengan menggunakan atribut ini.

Perintah untuk menampilkan nilai unik dari number_list.

Dari output yang dihasilkan, terlihat bahwa nilai unik dari series tersebut adalah 1, 2, 3, 4, 5, dan 6.

Output yang menunjukkan nilai unik dari number_list.

8) Attribute .index

Berperan dalam mengecek index/key dari sebuah series atau dataframe. Seperti pada contoh berikut, kita akan mengecek index masing-masing dari number_list dan matrix_list.

Perintah untuk mengecek number_list dan matrix_list.

Dari hasil yang didapat, terlihat bahwa number_list dan matrix_list memiliki index masing-masing sebanyak 6 dan 4. Karena index pada series dan dataframe tersebut masih dalam bentuk defaultnya, yang ditampilkan hanyalah index awal (start), index akhir (stop), serta banyaknya index (step) saja.

Output yang menunjukkan index dari number_list dan matrix_list.

9) Attribute .columns

Digunakan untuk mengecek kolom yang tersedia pada sebuah dataframe. Atribut ini hanya dapat digunakan pada dataframe saja.

Sebagai contoh, kita akan mencoba menerapkan atribut ini pada matrix_list seperti pada potongan kode berikut.

Perintah untuk mengecek kolom dari matrix_list.

Maka, dari output yang dihasilkan terlihat bahwa kolom dataframe ini dimulai dari kolom ke-0 hingga ke-3, dengan setiap kolom yang memenuhi 1 baris.

Output yang menunjukkan kolom dari matrix_list.

10) Attribute .loc[]

Atribut ini berguna dalam melakukan slice dataframe atau series berdasarkan nama kolom atau indexnya.

Misalnya, kita akan mencoba menerapkan fitur ini pada number_list dan matrix_list masing-masing untuk melakukan slice mulai dari baris ke-0 hingga baris ke-1.

Perintah untuk melakukan slice dengan .loc[].

Output yang dihasikan berupa number_list dan matrix_list yang sudah di-slice seperti pada gambar berikut.

Hasil slice number_list dan matrix_list dengan .loc[].

11) Attribute .iloc[]

Digunakan untuk melakukan slice terhadap dataframe atau series berdasarkan index dari kolom dan indexnya. Misalnya, kita akan melakukan slice menggunakan fitur ini hanya pada baris ke-0 saja, baik terhadap number_list ataupun matrix_list.

Perintah untuk melakukan slice dengan .iloc[].

Berbeda dengan .loc[], fungsi .iloc[] ini mengambil baris dari index tertentu hingga baris sebelum baris ke-n (dalam contoh ini sebelum baris ke-1), sehingga yang terlihat adalah baris ke-0 yang telah di-slice dari masing-masing data seperti pada gambar berikut.

Hasil slice number_list dan matrix_list dengan .iloc[].

Membuat series dan dataframe

Sebelum mulai melakukan analisa serta manipulasi pada data di Pandas, tentunya kita memerlukan sebuah data untuk menunjang keperluan tersebut. Data tersebut bisa kita buat sendiri ataupun dengan melakukan loading dari alamat url tertentu. Nah, pada tahap kali ini, kita akan terlebih dahulu mencoba membuat data sendiri yang berupa series dan dataframe. Untuk membuat series atau dataframe , kita bisa membuatnya dari berbagai macam tipe data container/mapping di Python, seperti list, dictionary, maupun numpy array.

1) Creating Series and DataFrame from List

Pada bagian ini, kita akan mencoba membuat series dan dataframe yang bersumber dari list. Sekedar buat pengingat saja, list merupakan sebuah kumpulan dari berbagai macam tipe data yang sifatnya mutable (dapat diganti).

Pada potongan kode di bawah ini, kita akan mencoba membuat series ex_series dan dataframe ex_df masing-masing dari list ex_list dan ex_list_of_list . Untuk dataframe yang dibuat dari ex_list_of_list, kita akan menambahkan indeks dan kolom masing-masing dalam bentuk list pada parameter index dan cols. Kedua list tersebut akan ditempatkan dalam parameter index dan columns pada fungsi pd.DataFrame() untuk membentuk indeks dan kolomnya.

Perintah untuk membuat ex_series dan ex_df dari list.

Di sini, karena kita belum menambahkan index apapun pada ex_series, maka yang ditampilkan adalah index defaultnya yang dimulai dari angka 0 hingga mengikuti jumlah baris series tersebut (5). Sementara itu, dataframe ex_df telah memiliki index dan kolom yang sesuai dengan yang dispesifikasikan di code editor.

Tampilan ex_series (atas) dan ex_df (bawah).

2) Creating Series and DataFrame from Dictionary

Setelah membuat series dan dictionary dari list, kali ini kita akan membuat kedua jenis data tersebut dari dictionary. Sekedar buat pengingat saja, dictionary merupakan kumpulan data yang strukturnya terdiri dari key dan value.

Pada potongan kode di bawah ini, kita akan mencoba membuat ex_series dari dict_series dengan indexnya ditempatkan pada key dari dictionary tersebut. Untuk dataframe ex_df , kita akan membuatnya dari df_series dengan nama kolomnya ditempatkan pada key dictionarynya. Berbeda dengan series, valuesnya berupa list yang masing-masing berjumlah 3 elemen list pada tiap key.

Perintah untuk membuat ex_series dan ex_df dari dictionary.

Di sini, terlihat bahwa index pada ex_series mengikuti key yang terdapat dalam dict_series. Berbeda dengan ex_series, pada ex_df, kolom yang ditampilkan mengikuti key yang terdapat di df_series.

Tampilan ex_series (atas) dan ex_df (bawah).

3) Creating Series and DataFrame from Numpy Array

Setelah list dan dictionary, pada bagian ini kita akan membuat series dan dataframe yang bersumber dari numpy array. Numpy array sendiri merupakan kumpulan data yang terdiri atas berbagai macam tipe data, mutable, tapi dibungkus dalam array oleh library Numpy.

Pada contoh di bawah ini, kita akan membuat ex_series dan ex_df masing-masing dari arr_series dan arr_df. Caranya sebenarnya hampir sama dengan list, hanya saja kita membungkusnya lagi dengan array dengan mengawali dan mengakhirinya dengan tanda kurung (()).

Perintah untuk membuat ex_series dan ex_df dari numpy array.

Dari output yang dihasilkan, dapat kita lihat bahwa index serta kolom yang terdapat pada ex_series serta ex_df diset ke dalam bentuk defaultnya (dimulai dari angka-0). Hal tersebut terjadi karena kita tidak menambahkan parameter index dan cols untuk menempatkan index dan kolomnya sehingga yang ditampilkan adalah bentuk defaultnya, sama halnya seperti saat membuat series dan dataframe dari list.

Tampilan ex_series (atas) dan ex_df (bawah).

About read dataset

Pandas menyediakan berbagai macam method untuk membaca berbagai tipe file. Hal yang dapat dilakukan untuk membaca adalah hanya dengan memanggil method tersebut dengan code yang lebih simple serta loading yang lebih. Di sini, tentu saja output yang dihasilkan tetaplah berupa series atau dataframe.

Terdapat sangat banyak tipe file yang dapat dibaca atau disimpan oleh Pandas, tapi ada beberapa file yang paling umum dan sering digunakan oleh praktisi-praktisi data seperti pada uraian berikut ini:

  1. CSV (Comma Separated Values), dalam satu baris antar datanya dipisahkan oleh comma, “,”.
  2. TSV (Tab Separated Values), dalam satu baris antar datanya dipisahkan oleh “Tab”.
  3. Excel
  4. Google BigQuery
  5. SQL Query
  6. JSON (Java Script Object Notation)

1) Read Dataset — CSV dan TSV

CSV dan TSV pada hakikatnya adalah tipe data text yang memiliki pemisah antar data dalam satu baris yang berbeda. Pada file CSV, antar data dalam satu baris dipisahkan oleh tanda coma( ,). Berbeda dengan CSV, pada file TSV antar data dalam satu barisnya dipisahkan oleh “Tab”.

Fungsi .read_csv() digunakan untuk membaca file yang value nya dipisahkan oleh comma secara defaultnya. Namun, fungsi ini juga bisa kok, digunakan untuk membaca file tsv. Caranya yaitu dengan menset pemisah valuenya menjadi ‘\t’ untuk file tsv (tab separated values).

· Membaca file CSV

Pada contoh kali ini, kita akan membaca data bertipe csv yang bersumber dari url https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_csv.csv dengan memasukkannya dahulu ke variabel df_csv. Untuk melihat isi datanya, kita akan menggunakan fungsi print() serta .head() untuk melihat 3 data teratasnya.

Perintah untuk loading dataset dengan format .csv.

Output yang dihasilkan berupa sebuah dataframe dengan variabel yang terlihat adalah order_id, order_date, customer_id, brand, quantity, dan item_price. Total jumlah kolom dari dataset tersebut adalah sebanyak 9 kolom.

Tampilan dataframe dengan format .csv.

· Membaca file TSV

Kemudian, kita akan membaca file bertipe tsv dengan tetap menggunakan .read_csv(). Di sini, supaya pemisah valuenya berupa tab, kita menggunakan parameter sep=’\t’ untuk mengganti separated valuenya menjadi tab. Dataset yang digunakan bersumber dari url https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_tsv.tsv.

Perintah untuk loading dataset dengan format .tsv.

Maka, output yang dihasilkan pun tetaplah sama seperti pada contoh sebelumnya.

Tampilan dataframe dengan format .tsv.

2) Read Dataset — Excel

File Excel dengan ekstensi *.xls atau *.xlsx ternyata cukup banyak lho digunakan dalam menyimpan data. Untuk file excel itu sendiri, Pandas juga memiliki fitur untuk membaca file tersebut.

Fungsi yang digunakan untuk membaca data tersebut adalah.read_excel(). Fungsi ini akan membaca file excel menjadi sebuah dataframe Pandas. Misalnya saja, kita akan menggunakan fungsi tersebut untuk membaca data yang bersumber dari https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_excel.xlsx. Pada fungsi tersebut, kita akan memberi nama pada sheet nya dengan parameter sheet_name=”test”. Selanjutnya, kita akan menampilkan 4 baris pertama dari data tersebut.

Perintah untuk loading dataset dengan format xlsx.

Jika diperhatikan baik-baik, output yang dihasilkan sebenarnya tetaplah sama dengan contoh-contoh sebelumnya. Hanya saja, tipe data tersebut berbeda dengan sebelumnya. Untuk itu, diperlukan fungsi yang tepat untuk membaca dataset tersebut menjadi sebuah dataframe.

Tampilan dataframe dengan format .xlsx.

3) Read Dataset — JSON

Metode ini digunakan untuk membaca URL API yang formatnya JSON dan merubahnya menjadi dataframe pandas. Fungsi yang digunakan dalam metode ini adalah .read_json(). Contoh dari penggunaan metode ini bisa kamu lihat pada potongan kode di bawah ini. Di sini, kita akan memasukkan alamat url dari sumber dataset dalam variabel url, kemudian kita menggunakan fungsi .read_json() untuk melakukan loading terhadap dataset tersebut. Dataset yang akan kita gunakan kali ini bernama covid2019-api-herokuapp-v2. Cara menampilkan 10 baris teratasnya pun tetaplah sama, yaitu dengan fungsi .head().

Perintah untuk melakukan loading terhadap dataset JSON.

Output yang dihasilkan berupa 10 baris pertama dataset Covid-19 seperti yang ditunjukkan di bawah ini.

Tampilan 10 baris pertama dataset Covid-19 yang berformat JSON.

4) Read Dataset — SQL

Dalam melakukan loading dataset dari SQL, kita bisa menggunakan 2 fungsi, yaitu .read_sql() atau .read_sql_query() untuk membaca query dari database serta mentranslatenya menjadi dataframe Pandas. Pada contoh case di bawah ini, kita akan menggunakan database dari salah satu produk SQL, yaitu SQLite.

Pertama-tama, kita akan mengimport library mysql.connector dan pandas, lalu membuat koneksi ke database tersebut dengan fungsi .connect() dari mysql.connector. Dalam membuat koneksi, kita perlu mencantumkan host, port, user, password, serta database yang digunakan. Untuk parameter use_pure nya, kita isi dengan nilai True. Selanjutnya, kita membuat query SQL untuk membaca datanya. Di sini, kita akan menggunakan sebuah dataset financial sebagai contohnya.

Perintah untuk membuat koneksi dan membuat perintah SQL.

Sama seperti yang sudah dijelaskan sebelumnya, kita bisa menggunakan 2 fungsi, yaitu .read_sql_query atau .read_sql. Jika menggunakan .read_sql_query, kita menggunakan 2 parameter, yaitu my_query serta my_conn yang masing-masing berisi query sql serta koneksi ke database yang sudah kita buat sebelumnya.

Perintah dengan .read_sql_query untuk loading dataset SQL.

Jika kita menggunakan .read_sql, cara penggunaannya pun sama seperti saat menggunakan .read_sql_query. Untuk menampilkan 5 baris teratasnya, kita tetap menggunakan .head() seperti biasa.

Perintah dengan .read_sql untuk loading dataset SQL.

Output yang dihasilkan dari kedua potongan kode tersebut adalah sama, yaitu sebuah dataset financial yang terdiri dari kolom loan_id, account_id, date, amount, duration, payments, dan status.

Tampilan dataframe yang dibaca dengan lakukan loading dari SQL.

5) Read Dataset — Google BigQuery

Untuk data berukuran besar (big data), umumnya kita menggunakan Google BigQuery. Layanan ini dapat digunakan jika kita telah memiliki akun Google BigQuery.

Adapun fungsi .read_gbq() dapat kita gunakan untuk membaca tabel dari Google BigQuery menjadi dataframe pandas. Misalnya saja, kita akan melakukan loading dataset “df_covid19_eu_summary” seperti pada contoh berikut. Di sini, kita akan membuat querynya terlebh dahulu untuk melakukan pengambilan seluruh data tersebut. Selanjutnya, kita melakukan pembacaan dataset tersebut dengan fungsi .read_gbq() menggunakan project_id dari dataset tersebut. Pada contoh berikut ini, project_id=”XXXXXXXX” adalah ID dari Google BigQuery account. Data yang akan kita loading adalah data Covid- 19 dengan nama covid19_jhu_csse_eu.summary. Selanjutnya, kita akan menampilkan seluruh isi data tersebut.

Perintah untuk membaca dataset Covid-19 dari Google BigQuery.

Output yang dihasilkan adalah dataset Covid-19. Di gambar ini, yang ditampilkan hanyalah kolom province_state, country_region, date, latitude, longitude, serta location_geom saja.

Gambaran dari dataset Covid-19 yang dibaca dari Google BigQuery.

Write dataset

Sebagai seorang data scientist ataupun data analist, kita perlu menyimpan data yang sudah melalui tahap cleansing ke dalam sebuah media penyimpanan. Nah, untuk mempermudah kita dalam tahap ini, Pandas telah menyediakan fitur tersebut secara ringkas melalui penerapan metode pada dataframe/series seperti yang ditunjukkan pada gambar tabel berikut.

Tampilan atas dari tabel fungsi write dataset.
Tampilan bawah dari tabel fungsi write dataset.

Back to head & tail

Dalam melakukan proses eksplorasi data, melakukan loading data saja tidaklah cukup. Untuk itu, kita perlu menampilkan sebagian baris dari data tersebut untuk melihat penampang dari sebagian data tersebut. Cara ini bisa ditempuh menggunakan fungsi .head() dan .tail() yang masing-masing berfungsi untuk menampilkan sejumlah baris pertama dan terakhir dari sebuah dataset. Untuk menggunakan kedua fungsi ini, kita bisa menggunakannya sesuai dengan kedua syntax berikut ini, yaitu:

Syntax untuk menampilkan baris teratas dari dataframe.

Untuk fungsi .head(), dan

Syntax untuk menampilkan baris terbawah dari dataframe.

Untuk fungsi .tail(), dengan n merupakan jumlah baris yang akan ditampilkan. Jika nilai n tidak disebutkan, yang ditampilkan adalah 5 baris sebagai nilai defaultnya.

Buat sekedar pengingat kita dalam menggunakan fungsi ini, kita akan mencoba menampilkan tiga data teratas dengan .head() dari dataframe df.

Perintah untuk menampilkan 3 baris teratas dari df.

Dari output yang dihasilkan, terlihat bahwa data dengan order_id 1612339 menempati 3 baris teratas dari dataframe df.

3 baris teratas dari dataframe df.

Kemudian, kita akan menampilkan 3 data terbawah dari dataframe df.

Perintah untuk menampilkan 3 baris teratas dari df.

Di sini, data dengan order_id 1612390 menempati 3 data terbawah dari dataframe tersebut.

3 baris terbawah dari dataframe df.

Indexing

Sebelum mengenal apa itu indexing, terlebih dahulu kita akan mengetahui apa itu yang dinamakan index. Index merupakan key identifier dari tiap row/column pada series atau dataframe. Index ini sifatnya tidak mutable untuk masing-masing value, akan tetapi, kita bisa menggantinya untuk semua value sekaligus. Jika indexnya tidak disediakan, Pandas akan membuat kolom index default secara otomatis sebagai bilangan bulat (integer) yang diurutkan mulai dari 0 hingga range dari jumlah baris data tersebut.

Kolom index ini umumnya dapat terdiri dari satu kolom (single index) atau multiple kolom yang juga bisa disebut sebagai hierarchical indexing. Index dengan multiple kolom ini dibuat karena unique identifier dari suatu data tidak dapat dicapai hanya dengan set index di 1 kolom saja sehingga dibutuhkan beberapa kolom supaya tiap row yang akan kita cek menjadi lebih unique. Secara default, index dari suatu dataframe selalu berupa single index setelah dibaca dari sebuah file dengan format tertentu.

Pada contoh di bawah ini, kita akan mencoba menggunakan dataframe df yang berformat .tsv. Untuk menentukan index dan kolom dari dataset tersebut, kita dapat menggunakan atribut .index dan .columns.

Perintah untuk mengecek rincian index dan kolom pada dataframe df.

Output yang dihasilkan berupa keterangan mengenai index dataset yang dimulai dari indeks ke-0 hingga ke-101. Untuk kolomnya, terlihat bahwa ada 9 kolom dalam dataset tersebut, yaitu order_id, order_date, customer_id, city, province, product_id, brand, quantity, dan item_price.

Output yang menampilkan rincian dari index dan kolom pada dataframe df.

Jika sebelumnya kita sudah mengetahui konsep dari single index, sekarang kita akan membahas bagaimana multiindex itu dibuat atau yang disebut sebagai hierarchical indexing.

Untuk membuat multi index (hierarchical indexing) dengan pandas, diperlukan kolom-kolom mana saja yang perlu disusun agar index dari suatu data frame dapat menjadi sebuah hirarki yang kemudian dapat dikenali. Ada 3 cara yang dapat kita lakukan dalam membuat multiindex ini, yaitu dengan menggunakan .set_index, .index, serta argumen index_col pada fungsi yang digunakian untuk membaca dataset.

Pada output yang dihasilkan dari potongan kode untuk menampilkan index dan kolom tadi, kita telah mengetahui nama-nama kolom dari dataframe df, yaitu order_id, order_date, hingga item_price. Sekarang, dengan tetap menggunakan dataframe tersebut, kita akan mencoba mempraktekkan ketiga cara yang telah kita sebutkan tadi untuk melakukan indexing.

1) .set_index

Pertama-tama, kita akan mencoba membuat multiindex dari kolom-kolom tersebut dengan menggunakan.set_index().Kolom-kolom yang akan kita gunakan adalah order_id, customer_id, product_id, dan order_date. Cara pengaplikasiannya bisa kalian lihat pada gambar di bawah ini.

Perintah untuk menggunakan .set_index() untuk melakukan set index terhadap kolom.

Sesuai dengan potongan kode yang telah dieksekusi, terlihat bahwa kolom order_id, customer_id, product_id, dan order_date, telah dikelompokkan sedemikian rupa membentuk index dari dataset tersebut.

Tampilan dataframe setelah diset indexnya dengan .set_index().

Untuk melihat rincian dari multiindex yang telah diset, kita dapat melakukannya dengan fungsi .index.

Perintah untuk melihat rincian index.

Pada output yang dihasilkan, terlihat adanya atribut yang ditampilkan, yaitu levels yang menampilkan unik data dari setiap kolom index, codes, serta names yang menunjukkan nama-nama kolom yang digunakan sebagai indeks.

Output yang menunjukkan atribut levels, codes, serta names untuk setiap kolom index.

Perlu untuk diketahui bahwa kumpulan index dari multiindex adalah list dari banyak tuples, sedangkan tuples nya sendiri merupakan kombinasi yang ada dari gabungan index-index tersebut. Dari multi index tersebut, kita juga dapat melihat adanya atribut levels yang menunjukkan urutan index, dalam case ini urutannya adalah ‘order_id’ > ‘customer_id’ > ‘product_id’ > ‘order_date’. Dengan menggunakan for loops, kita akan mencetak atribut names serta levels dari multiindex tersebut seperti pada potongan kode berikut.

Perintah untuk menampilkan nama kolom serta data unik dari setiap kolom.

Output yang dihasilkan berupa daftar nama kolom pada index yang ditampilkan bersama dengan unik data beserta tipenya untuk masing-masing kolom.

Tampilan yang menunjukkan nama kolom beserta data unik dan tipe untuk setiap kolom index.

2) .index

Selain dengan .set_index(), kita dapat menggunakan assignment dengan fungsi .index untuk menset index dari suatu data frame. Sebagai contoh, kita akan menset index dataset dari file sample_excel.xlsx dengan nama-nama hari dalam bahasa Inggris mulai dari Monday (“Mon”) hingga Sunday (“Sun”). Untuk nilai pada kolom week_type, kita akan mengisinya dengan “weekday” untuk hari Senin hingga Jumat serta “weekend” untuk hari Sabtu sampai dengan Minggu.

Perintah untuk membuat dataframe dengan set index menggunakan .index.

Output yang dihasilkan dapat kalian lihat pada gambar di bawah ini.

Tampilan dataframe yang dibuat dengan set index menggunakan .index.

Catatan:

· Cara yang ditunjukkan oleh baris ketujuh pada code editor di atas hanya berlaku jika index yang diassign tersebut memiliki panjang yang sama dengan jumlah baris dari dataframe.

· Jika ingin mengembalikan dataframe ke index defaultnya yaitu dari 0 hingga jumlah baris data ke-n, kita dapat menggunakan metode .reset_index() dengan argument drop=True yang bertujuan untuk menghapus index lama.

Dengan tetap menggunakan fungsi yang sama seperti pada contoh di atas, kita juga dapat menset indeks dari dataframe df dengan menggunakan nama “Pesanan ke-i” dengan i adalah bilangan bulat yang menyatakan baris ke-1 hingga baris ke-10. Sebagai perbandingan, kita juga akan menampilkan dataset sebelum diset indeksnya.

Perintah untuk memodifikasi index dengan .index.

Perhatikan dataframe awal dengan dataframe yang telah diberi index baru. Pada dataframe yang belum diberi index, indexnya masih berupa index default yang dimulai dari 0 hingga 9. Setelah kita set indexnya, indexnya telah berubah menjadi “Pesanan ke-1” hingga “Pesanan ke-10” sesuai yang kita mau.

Perbandingan tampilan dataframe sebelum dan sesudah dimodifikasi indexnya dengan .index.

3) index_col

Selain menggunakan cara di atas, kita sebenarnya juga dapat menset indeks dari sebuah dataset saat melakukan loading data, lho. Caranya yaitu dengan menggunakan argumen index_col pada fungsi yang digunakan untuk membaca dataset tersebut. Seperti pada contoh berikut, kita akan menggunakan argumen tersebut pada .read_csv() untuk menset kolom order_date dan order_id sebagai indeks dari dataframe df.

Perintah untuk lakukan set index dengan index_col.

Asumsikan kita sudah mengetahui bahwa dataset tersebut memiliki 9 kolom serta diawali dengan kolom order_id, baru kemudian order_date. Setelah diset indeksnya, dapat kita lihat pada outputnya bahwa kolom order_date serta order_id tersebut sudah menjadi indeks dari dataframe df dengan diawali oleh kolom order_date. Sementara itu, jumlah kolom dataset df telah berkurang menjadi 7 kolom.

Tampilan dataframe setelah diset indexnya dengan index_col.

Slicing

Sama seperti artinya, slicing adalah suatu cara untuk melakukan filter ke dataframe/series berdasarkan kriteria tertentu dari nilai kolomnya ataupun kriteria dari index-nya.

Terdapat 2 cara yang paling sering digunakan untuk slicing dataframe, yaitu dengan menggunakan method .loc[] dan .iloc[] pada variabel bertipe pandas DataFrame/Series. Method .iloc[] ditujukan untuk proses slicing berdasarkan index berupa nilai integer tertentu. Akan tetapi, metode .loc[] lebih sering digunakan karena lebih fleksibel. Dalam menggunakan metode .loc[] ini, kita dapat melakukan slicing berdasarkan kolom dan index dari suatu dataframe.

1) Slicing berdasarkan kolom

Asumsikan kita belum melakukan indexing pada dataset. Karena belum dilakukan indexing, kita akan melakukan slicing berdasarkan nilai kolomnya. Untuk itu kita akan menggunakan metode .loc[] untuk mengambil dataset sample_csv.csv yang bertanggal 1 Januari 2019 dari order_date serta memiliki product_id P2154 dan P2556.

Perintah untuk melakukan slicing terhadap kolom.

Dari output yang dihasilkan, terlihat bahwa data yang sesuai dengan kriteria yang diminta hanya sebanyak 2 baris saja.

Tampilan dataframe setelah dilakukan slicing terhadap kolomnya.

Berbeda dengan hasil sebelumnya, jika kita melakukan filter data dengan customer_id 18055 serta product_id P0029, P0040, P0041, P0116, dan P0117, kita akan mendapati output berupa Empty Dataframe karena data dengan kriteria yang dimaksud tidak terdapat di dataset tersebut.

Perintah untuk melakukan slice berdasarkan kolom.

Hasil:

Tampilan yang menunjukkan hasil slice yang tidak sesuai dengan kriteria.

2) Slicing berdasarkan index

Teknik slicing/filtering dataset tidak hanya bisa dilakukan berdasarkan kolom, tetapi juga berdasarkan indexnya. Ada 2 cara yang dapat dilakukan, yaitu dengan menggunakan .set_index() ataupun dengan pd.IndexSlice.

· Dengan .set_index

Tak jauh berbeda dengan teknik slicing berdasarkan kolom, kita akan menggunakan metode .loc untuk melakukan filtering terhadap order_date serta product_id seperti yang terlihat pada contoh berikut. Sebelumnya, kita perlu melakukan set_index terhadap kedua kolom tersebut untuk menentukan urutan kolom yang akan ditentukan slicing datanya.

Perintah untuk melakukan slice terhadap index dengan .set_ index().

Output yang dihasilkan sesuai dengan kriteria yang dimaksud, yaitu order_id dengan nilai 2019–01–01 serta product_id yaitu P2556 dan P2154.

Tampilan dataframe setelah slice terhadap indexnya dengan .set_index().

· Dengan pd.IndexSlice

Hampir sama seperti cara sebelumnya, kita tetap menggunakan.loc[] untuk filtering data, hanya saja kita menggunakan fitur tambahan lain yaitu pd.IndexSlice. Seperti pada contoh berikut, kita menggunakan fitur tersebut dengan memasukkannya ke variabel idx terlebih dahulu supaya lebih singkat. Di sini, data yang difilter adalah yang memiliki tanggal (order_id) 2019–01–01 serta product_id P2154 hingga P25556.

Perintah untuk menggunakan pd.IndexSlice.

Output yang dihasilkan akan terlihat seperti pada gambar di bawah ini. Di sini, product_id yang termasuk dalam kriteria yang kita cantumkan dalam kode yang kita eksekusi meliputi P2154, P2159, P2325, P2494, serta P2556.

Tampilan dataframe setelah slice dtaframe dengan pd.IndexSlice.

Transforming

Transform adalah proses mengubah dataset yang ada menjadi entitas baru, yang dapat dilakukan dengan:

  1. konversi dari satu data type ke data type yang lain,
  2. transpose dataframe
  3. atau dengan cara lainnya.

Hal yang wajib dilakukan pertama kali sebelum melakukan proses transforming adalah membaca sebuah data adalah mengecek tipe data di setiap kolomnya apakah sesuai dengan representasinya atau belum. Untuk itu, kita dapat menggunakan attribut .dtypes pada dataframe yang kita baca tadi seperti pada syntax berikut.

Syntax untuk mengecek tipe semua kolom pada dataframe.

Dalam proses konversi tipe data, secara default sistem akan mendeteksi data yang tidak bisa di render sebagai date type atau numeric type menjadi basically string object. Hal tersebut bisa terjadi karena berbagai hal, salah satunya adalah formatnya yang asing serta tidak dikenali oleh Python secara umum. Nah, dalam melakukan konversi tipe ini, ada 3 macam bentuk konversi yang umum digunakan dalam Python, yaitu dengan menggunakan:

1) pd.to_datetime()

Fitur ini umumnya digunakan untuk mengonversi kolom tanggal dari suatu data yang dirender menjadi basically string object. Misalnya, data dengan format ‘2019Jan01’ yang tidak bisa di render menjadi date type di Python karena memiliki bentuk yang tidak lazim seperti dataframe Python pada umumnya. Jika seluruh data pada kolom di order_date sudah tertulis dalam bentuk ‘YYYY-MM-DD’ , kolom order_date tersebut sudah langsung bisa dinyatakan dalam bentuk datetime saat dibaca.

Untuk merubah kolom order_date yang sebelumnya bertipe object menjadi kolom bertipe datetime, kita dapat melakukannya dengan syntax:

Syntax dasar pd.to_datetime()

dimana argumen adalah isi kolom dari dataframe yang akan dirubah tipe datanya yang umumnya disajikan dalam format:

Syntax yang menunjukkan detail dari argmen pada pd.to_datetime().

Sehingga, syntax lengkapnya bisa ditulis seperti di bawah ini.

Syntax untuk mengubah tipe kolom menjadi datetime.

Misalnya, kita akan mengubah tipe data di kolom order_date yang semula bertipe object menjadi bertipe datetime. Sebagai perbandingannya, kita akan mencetak terlebih dahulu dataframe df yang belum diubah tipe datanya.

Perintah untuk mengubah kolom order_date menjadi datetime.

Perhatikan baik-baik, kolom order_date yang semula bertipe object, kini telah berubah menjadi datetime64[ns].

Perbandingan tipe kolom order_date sebelum dan sesudah ditransformasi.

2) pd.to_numeric() dan .astype()

Setelah kita mengetahui cara mengubah tipe data sebuah kolom menjadi datetime, kali ini kita akan mencoba mengubah tipe data pada kolom dataframe yang telah dibaca menjadi tipe data float dan tipe category.

Umumnya, kolom yang akan dirubah menjadi tipe numerik adalah kolom yang memiliki data berupa angka. Untuk merubah tipe kolom tersebut menjadi numerik, kita dapat menggunakan pd.to_numeric() seperti pada syntax berikut.

Syntax untuk mengubah tipe kolom jadi numerik.

Berbeda dengan pd.to_numeric, sebuah kolom dapat dirubah tipenya menjadi category apabila kolom-kolom tersebut bertipe object. Untuk merubah tipe kolom tersebut menjadi category, kita dapat menggunakan fitur .astype() seperti yang ditunjukkan pada syntax di bawah ini.

Syntax untuk mengubah tipe kolom jadi category.

Misalnya, kita ingin mengubah tipe data kolom quantity dan city yang masing-masing bertipe bertipe int64 dan object menjadi bertipe float32 dan category pada dataframe df seperti pada potongan kode di bawah ini. Di sini, kita cukup menggunakan float sebagai tipe data baru para parameter downcast dalam fungsi pd.to_numeric(). Seperti biasa, kita akan menampilkan dataframe df yang belum dan sudah diubah tipe datanya sebagai perbandingan.

Perintah untuk mengubah kolom quantity dan city menjadi float dan category.

Di sini, dapat kita lihat pada outputnya bahwa kolom city dan quantity yang mula-mula bertipe object dan int64 kini telah berubah tipenya menjadi category dan float32 sesuai dengan perintah yang kita eksekusi pada code editor.

Output untuk membandingkan tipe kolom city dan quantity sebelum dan sesudah ditransformasi.

Proses transformasi suatu data tidak hanya meliputi pengubahan tipe data saja. Seperti pada bagian sebelumnya, kita telah mengetahui bahwa selain pengubahan data, terdapat juga bentuk transformasi lain, yaitu dengan melakukan proses transpose isi suatu dataframe dengan menerapkan fungsi tertentu di dalamnya. Untuk melakukan proses transpose tersebut, kita dapat menggunakan fitur .apply(), .map(), serta .applymap() pada dataframe tersebut.

1) Metode .apply() dapat digunakan untuk menerapkan suatu fungsi Python, entah yang dibuat dengan bantuan def atau anonymous dengan bantuan lambda. Metode ini dapat diterapkan pada dataframe/series atau hanya pada kolom tertentu saja dari sebuah dataframe.

Misalnya, kita akan mengubah semua huruf pada data kolom brand dari dataframe df menjadi huruf kecil semua dengan bantuan fungsi .lower(). Asumsikan bahwa semua huruf di data kolom brand terdiri dari huruf kapital semua seperti pada gambar berikut.

Kolom brand awal sebelum ditransformasi.

Di sini, kita juga menggunakan lambda x untuk menerapkan fungsi lower pada semua data pada kolom tersebut.

Perintah untuk menerapkan fungsi.lower() dengan metode apply.

Maka, output yang dihasilkan berupa daftar 5 nama brand teratas yang sudah dirubah formatnya menjadi huruf kecil. Misalnya, nama BRAND_C yang semula terdiri dari huruf kapital telah diubah menjadi brand_c yang berformat huruf kecil.

Tampilan kolom brand setelah diubah semua karakternya menjadi huruf kecil.

2) Metode .map() hanya dapat diterapkan pada sebuah series atau dataframe yang diakses dari satu kolom saja. Metode ini berguna untuk mensubstitusikan suatu nilai ke dalam tiap baris datanya.

Perintah untuk mengambil karakter terakhir dari kolom brand.

Maka, dari output yang ditampilkan hanya terdapat satu karakter terakhir saja dari data kolom brand. Misalnya, data brand_c yang diambil satu karakter terakhirnya saja, yaitu c, sehingga yang ditampilkan hanya huruf c saja.

Tampilan kolom brand setelah diambil sebagian karakternya.

3) Metode .applymap(). Jika fungsi .map() hanya terbatas pada series serta satu kolom dari dataframe saja, berbeda halnya dengan .applymap(). Di sini, kita dapat melakukan transformasi pada seluruh kolom dari dataframe dengan menggunakan fungsi .applymap() .

Misalnya, kita akan membuat sebuah matriks random berukuran 3x4 dengan menggunakan seed random1234 serta dengan bantuan fungsi .random.rand dari library numpy untuk menentukan ukuran matriksnya. Untuk number generatornya, kita bisa melakukan set terhadap angka seed menjadi suatu angka atau bisa dengan menggunakan semua angka supaya hasil randomnya selalu sama ketika dijalankan. Asumsikan matrix random yang kita hasilkan berbentuk dataframe seperti pada gambar di bawah ini.

Tampilan matrix random sebelum diterapkan fungsi kuadrat pada semua kolomnya.

Kemudian, kita akan menerapkan fungsi .applymap() untuk mengubah seluruh isi kolom dataframe tersebut dengan fungsi kuadrat x**2 + 3*x + 2. Ada dua cara yang bisa kita tempuh, yaitu:

· Cara 1, yaitu tanpa define function di bagian awalnya dengan langsung memasukkan rumusnya dalam fungsi anonymous lambda x di .applymap().

Perintah dengan menggunakan anonymous lambda x.

· Cara 2, yaitu dengan define function. Di sini, kita akan mendefinisikan fungsi quadratic_fun() dengan parameter x serta memanggil fungsi tersebut di .applymap().

Perintah dengan menggunakan define function.

Kedua cara tersebut akan menghasilkan output yang sama yang terlihat seperti pada gambar berikut.

Tampilan dataframe dengan fungsi kuadrat yang sudah diterapkan pada semua kolomnya.

Inspeksi missing value, bagaimana caranya?

Adanya value yang hilang/tidak lengkap dari sebuah dataframe akan membuat analisis atau model prediksi yang dibuat menjadi tidak akurat serta mengakibatkan keputusan yang diambil menjadi tidak valid. Untuk itu, ada beberapa cara yang dapat dilakukan untuk mengatasi data yang hilang/tidak lengkap tersebut. Akan tetapi, sebelum mengetahui cara-cara tersebut, kita akan membahas terlebih dahulu cara untuk mengetahui adanya missing values/data yang hilang dari suatu data.

Ada dua cara yang bisa kalian pilih untuk mengetahui keberadaan missing values tersebut, yaitu dengan menggunakan metode .info() atau dengan chaining method pada dataframe, yaitu menggunakan fungsi .isna().sum(). Untuk lebih jelasnya, perhatikan case berikut.

Misalnya, kita akan mendeteksi keberadaan missing values dari data Covid-19 bernama public data covid19 jhu csse eu.csv yang akan kita loading menjadi dataframe df berformat csv seperti pada potongan kode berikut.

Perintah untuk melakukan loading terhadap daatset Covid-19.

Umumnya, data yang hilang ini direpresentasikan oleh Pandas dalam bentuk NaN. Kita akan menerapkan dua cara tersebut untuk mengetahui keberadaan missing values tersebut.

1) Cara 1, yaitu dengan menerapkan method .info() pada dataframe sesuai dengan potongan kode berikut ini.

Maka, output yang dihasilkan adalah rincian dari masing-masing kolom pada dataframe df, yaitu jumlah data yang tidak bernilai null hingga tipe data dari masing-masing kolom. Di sini, kita dapat mengetahui jumlah nilai null dari setiap kolom dengan mengurangi total entri data yang masuk dengan jumlah data yang tidak null dari masing-masing kolom. Misalnya, jika kita ingin menghitung jumlah data bernilai null dari province_state, maka kita harus mengurangi total entri data (1000) dengan jumlah data yang tidak bernilai null (960) terlebih dahulu, sehingga total data bernilai null dari kolom tersebut adalah sebanyak 40 data.

2) Cara 2, yaitu dengan mengetahui banyaknya missing value dari tiap kolom di sebuah dataset dengan menerapkan chaining method pada dataframe, yaitu .isna().sum(). Berbeda dengan metode sebelumnya, di sini kita dapat langsung mengetahui banyaknya data yang bernilai null dengan langsung menjumlahkannya secara default dengan menggunakan .sum(). Sebelumnya, kita mengecek keberadaan nilai NaN dengan menggunakan .isna().Dengan menggunakan dataframe yang sama, yaitu df, kita akan mengecek keberadaan missing values tersebut dengan metode ini.

Maka, kita dapat langsung melihat banyaknya nilai null dari setiap kolom pada output yang dihasilkan seperti pada gambar berikut.

Bagaimana dengan treatment untuk missing value?

Ada beberapa cara yang umum digunakan untuk mengatasi missing value, yaitu:

1. membiarkannya saja,

2. menghapus value tersebut, atau

3. mengisi value tersebut dengan value yang lain

Sebelum melakukan action terhadap missing value pada sebuah dataset, ada baiknya jika kita menampilkan beberapa row teratasnya terlebih dahulu. Seperti pada contoh di bawah ini, kita akan menampilkan 10 data teratas dari dataset Covid-19 yang diloading menjadi dataframe df pada contoh sebelumnya seperti pada gambar berikut. Dari sini, sudah jelas terlihat bahwa kolom province_state, latitude, longitude, location_geom, deaths, recovered, active, fips, admin2, serta combined_key memiliki nilai NaN.

Ilustrasi tampilan dataset Covid-19.

Kembali pada hasil pengecekkan missing value dengan .isna().sum() pada pembahasan sebelumnya. Dari situ, terlihat jelas jumlah missing values dari setiap kolomnya. Hanya kolom combined_key saja yang memiliki missing value pada keseluruhan barisnya (1000 data), sementara kolom country_region, date, dan confirmed sama sekali tidak memiliki missing value. Untuk kolom lainnya, terdapat missing value dengan jumlah yang beragam. Selanjutnya, apa yang dapat kita lakukan?

Nah, supaya kita dapat memahami kolom mana yang akan ditreatment, terlebih dahulu kita harus mengetahui nature dari masing-masing data. Misalnya, kolom death dan recovered yang hanya memiliki satu missing values saja. Kemungkinan besar, hal ini bisa disebabkan karena tidak ada yang meninggal atau sembuh pada hari tersebut. Untuk kolom combined_key yang memiliki missing values pada seluruh kolomnya, kita dapat membuang kolom tersebut karena tidak ada data yang dapat diketahui dari kolom tersebut.

Jika kolom-kolom tersebut mendapat perlakuan demikian, bagaimana dengan kolom yang lainnya? Kita dapat mengisinya dengan nilai yang lain. Misalnya, kolom province_stat yang memiliki missing values pada sebagian datanya. Asumsikan saja bahwa missing values tersebut terjadi karena tidak dilaporkannya asal dari daerah yang bersangkutan. Di sini kita dapat mengisinya dengan string “unknown” karena kolom tersebut bertipe string.

Setelah mengetahui nature dari data tersebut, sekarang kita dapat menerapkan dua aksi terhadap missing values tersebut, yaitu dengan

1) Membiarkannya saja

Treatment ini dapat dilakukan pada kolom confirmed, death, dan recovered yang rata-rata memiliki satu nilai mssing values saja. Akan tetapi, jika tidak ada yang terkonfirmasi, meninggal dan sembuh, sebenarnya kita dapat menukar value ini dengan angka nol. Meskipun ini lebih make sense dalam representasi datanya, tetapi kita dapat mengasumsikan kedua kolom tersebut dibiarkan memiliki nilai missing value.

2) Menghapus kolom

Treatment ini dapat digunakan jika seluruh baris dari sebuah kolom dataset adalah missing value. Untuk itu, kita dapat menerapkan fitur .dropna() pada dataframe. Bagaimana caranya? Kita dapat menggunakannya sesuai syntax berikut.

Syntax yang umum digunakan untuk menghapus missing value dari dataframe.

Pada metode tersebut, ada dua keyword argumen yang harus diisi, yaitu axis dan how. Keyword axis digunakan untuk menentukan arah dataframe yang akan dibuang. Untuk mewakili arah kolom (column-based), kita dapat menggunakan angka 1 atau string “column”. Sedangkan, untuk menyatakan arah index (row-based), kita dapat menggunakan angka 0 atau string “index”.

Sementara itu, keyword how digunakan untuk menyatakan bagaimana cara membuang kolom tersebut. Opsi dalam bentuk string yang dapat diterima adalah:

· “all” jika seluruh data di satu/beberapa kolom atau di satu/beberapa baris adalah missing value.

· “any” jika hanya terdapat 1 data saja yang hilang dari baris/kolom tersebut.

Pada contoh di bawah ini, kita akan menerapkan metode menghapus kolom ini pada dataframe df. Asumsikan jumlah kolom dan baris dari dataframe df mula-mula adalah sebanyak 100 baris dan 13 kolom.

Output yang menunjukkan jumlah baris dan kolom pada df mula-mula.

Pertama-tama, kita akan mencoba meggunakan opsi “all” untuk menghapus kolom dari dataframe tersebut.

Perintah untuk menghapus kolom dengan “all”.

Setelah kita menjalankan perintah tersebut, terlihat bahwa jumlah kolom telah berkurang satu sehingga yang tersisa kini ada 12 kolom.

Output yang menunjukkan jumlah kolom pada df setelah dihapus nilai nullnya.

Selanjutnya, kita akan menggunakan opsi “any” untuk menghapus baris yang bernilai null seperti pada contoh kode berikut.

Perintah untuk menghapus baris dengan “any”.

Dari output yang dihasilkan, terlihat bahwa jumlah baris yang semula ada 1000 kini telah berkurang menjadi 746 baris saja.

Output yang menunjukkan jumlah baris pada df yang berkurang.

3) Mengisi missing value dengan nilai lain

Selain kedua cara yang telah kita bahas tadi, masih terdapat cara lain yang dapat kita lakukan untuk treatment missing value, yaitu dengan cara mengisi missing value dengan nilai lain yang bisa berupa teks tertentu, nilai statistik seperti mean atau median, serta interpolasi data

Kita akan mulai dengan kolom yang bertipe object. Misalnya, pada dataframe df yang kita gunakan tadi, kolom tersebut adalah province_state. Karena kita tidak tahu persis province_state mana yang dimaksud, kita bisa menempatkan string “unknown_province_state” untuk menggantikan missing value tersebut. Meskipun kedua nilai tersebut sama-sama tidak diketahui, akan tetapi kedua data tersebut memiliki representasi yang berbeda.

Untuk dapat melakukannya, kita bisa menggunakan method .fillna() pada kolom dataframe yang dimaksud. Sebagai perbandingan, kita akan mencetak nilai unik dari province_state sebelum dan sesudah diisi missing valuenya.

Perintah untuk mengisi missing value dengan string serta membandingkan kedua hasil.

Dari output yang dihasilkan, bisa dilihat bahwa nilai unik “nan” pada kolom province_state telah disubtitusi menjadi “unknown_province_state”.

Output yang menunjukkan nilai “nan” yang telah diganti oleh “unknown_province_state”.

Selain dengan menggunakan string, kita juga bisa mengganti missing value dengan nilai statistik dari kolom bersangkutan, baik itu median atau mean (nilai rata-rata). Umumnya, cara ini digunakan pada kolom yang bertipe numerik. Seperti pada contoh yang akan kita gunakan ini, kita akan mensubtitusi missing value pada kolom active dari dataframe df. Dengan mengabaikan sebarannya berdasarkan negara (univariate), kita harus melihat terlebih dahulu apakah dataset tersebut memiliki outliers atau tidak. Jika ada outliers, maka kita tidak bisa menggantinya dengan nilai mean. Sebagai gantinya, kita akan menggunakan nilai tengah (median) data supaya lebih safe.

Cara cepat mengetahui adanya outliers atau tidak yaitu dengan mengecek nilai median, mean, max, serta min dari kolom active. Jika data pada kolom tersebut terdistribusi normal, nilai mean dan median yang ditampilkan akan memiliki jumlah yang hampir sama.

Nilai min, mean, median, dan max yang perlu diketahui sebelum mengisi missing value.

Ternyata, data tersebut memiliki distribusi yang skewness. Hal ini dibuktikan dengan perbandingan nilai mean dan mediannya yang cukup jauh serta range data yang cukup lebar. Bisa dikatakan bahwa kolom active memiliki outliers, sehingga kita akan mengisi missing valuenya dengan median. Sebagai perbandingan, kita juga akan mencoba mengisi nilai missing valuesnya dengan nilai mean. Selanjutnya, kita akan mengecek kembali nilai mean dan mediannya setelah diisi oleh nilai-nilai tersebut.

Perintah untuk membandingka nilai mean dan median setelah mengisi missing value dengan median dan mean.

Bandingkan kedua hasil yang diperoleh. Jika kita mengisi nilai kolom active dengan nilai median, maka nilai meannya menjadi 184.8 (lebih mendekati nilai median) sementara itu nilai mediannya tetap 41. Hasilnya akan berbeda jika kita mengisinya dengan nilai mean, dimana nilai meannya tetap seperti semula sedangkan nilai mediannya berubah menjadi 49.

Disamping kedua cara tersebut, terdapat teknik lain yang bisa kita gunakan, yaitu teknik interpolasi untuk mengisi missing value pada suatu kolom dataset yang bertipe time series data. Seperti pada contoh berikut, kita akan mengisi nilai missing value (np.nan) pada dataframe ts yang kita definisikan ini dengan interpolasi linier menggunakan fungsi .interpolate().

Perintah untuk mengisi nilai np.nan dengan interpolasi linier.

Setelah diisi missing valuenya, dapat kita lihat bahwa nilai yang digunakan untuk subtitusi missing value memiliki jumlah yang berurutan serta bersesuaian dengan nilai dari dataframe yang ada.

Tampilan dataframe ts setelah diisi dengan interpolasi linier.

Project dari Andra!

Pada proyek kali ini, kita akan melakukan ETL sebelum melakukan analisis data, karena data yang dibutuhkan masih belum bersih sehingga tidak bisa dilakukan analisis lebih lanjut. Data yang dibutuhkan adalah data cabang dari sebuah perusahaan ritel, yaitu dataset retail_raw_test.csv. Rincian proyeknya adalah sebagai berikut.

1. Membaca dataset. Karena datanya memiliki format csv, di sini kita akan menggunakan fungsi .read_csv() untuk membaca dataset tersebut. Supaya kita mengetahui tampilan sebagian data serta jumlah missing value dan tipe data dari setiap kolom, kita akan menerapkan fungsi .head() serta .info() pada dataset tersebut.

Perintah untuk membaca dataset serta mengecek barisan teratas dan info dataset.

Di sini, dapat kita lihat bahwa kolom order_date memiliki tipe object, sementara itu kolom customer_id, quantity, serta item_price masih bertipe string. Di samping itu, terdapat nilai null pada beberapa kolomnya, yaitu kolom city, province, brand, serta product_value. Untuk itu, kita akan melakukan transformasi pada tipe data terlebih dahulu.

Tampilan dataset retail_raw_test.csv mula-mula sebelum dialkukan pengolahan lebih lanjut.

2. Langkah berikutnya, kita akan mengubah tipe kolom yang ada menjadi tipe yang seharusnya, yaitu customer_id dari string menjadi int64, quantity serta item_price yang mula-mula bertipe string menjadi int64.

Supaya kita dapat memastikan apakah kolom-kolom tersebut telah diubah tipenya, kita akan mengeceknya dengan menggunakan .dtypes untuk mengecek tipe masing-masing kolom.

Perintah untuk mengubah tipe kolom. pada dataset.

Di sini, dapat kita lihat bahwa tipe kolom customer_id, quantity, serta item_price telah berubah menjadi int64. Dengan begitu, kita akan siap menggunakan data-data ini untuk proses selanjutnya.

Output yang menunjukkan tampilan tipe kolom mula-mula sebelum diolah lebih lanjut.

3. Supaya format pada kolom product_value seragam, kita akan melakukan transform, lalu melakukan assign pada kolom tersebut ke kolom baru bernama product_id, serta melakukan drop terhadap kolom product_value. Akan tetapi, sebelum memulai proses ini, kita akan membuat fungsi impute_product_value untuk mendeteksi keberadaan missing value serta menggantinya dengan “unknown” pada kolom product_value. Mengapa tidak langsung convert menjadi string? Jika kita langsung melakukan convert, nilai null yang bernilai NaN akan berubah menjadi string ‘nan’, sehingga jika kita menambahkan nilai 0 di depannya serta meng-concatnya dengan string ‘P’, hasilnya akan menjadi ‘P0nan’ yang aneh sekali serta susah untuk dimengerti.

Perintah untuk melakukan transform terhadap kolom product_value.

Dari output yang dihasilkan, terlihat bahwa kolom product_value sudah tidak ada lagi, sementara itu susunan nilai yang terdapat pada product_id telah berubah menjadi lebih teratur setelah kita rubah formatnya.

Tampilan dataset retail_raw_test.csv setelah dilakukan transfrm pada kolom product_value.

4. Selanjutnya, kita akan melakukan transform terhadap kolom order_date menjadi value dengan format YYYY-mm-dd dengan menambahkan tanda (-) diantara tahun, bulan, serta hari yang tercantum di dalamnya. Untuk melakukan transform ini, kita akan membuat sebuah dictonary bernama months_dict untuk melakukan translate terhadap data-data yang ada dalam kolom tersebut. Mengapa kita tidak langsung menggunakan kolom yang ada? Seperti yang kita lihat pada output langkah 1 dan 3, formatnya masih belum ideal untuk dibaca di lingkungan Pandas sehingga harus ditranslate terlebih dahulu. Untuk memastikan apakah kolomnya sudah dirubah formatnya atau belum, kita akan mengeceknya kembali dengan .dtypes.

Perintah untuk melakukan transform terhadap kolom order_date.

Kolom order_date kini sudah berubah tipenya menjadi datetime64. Format yang telah berubah tersebut akan lebih mempermudah apabila kita ingin menampilkan kolom order_date berdasarkan hari, bulan, tanggal, atau satuan waktu yang lainnya.

Output yang menunjukkan kolom order_date yang sudah dirubah tipenya.

5. Kolom city dan province masih memiliki missing value. Untuk itu, kita akan mengisi missing value tersebut pada:

· Kolom province dengan “unknown”, dan

· Kolom brand dengan “no_brand”

Setelah itu, kita akan mengecek keberadaan missing value di kolom city dan province setelah diisi missing valuenya.

Perintah untuk melakukan handling terhadap missing value.

Di sini, kita dapat melihat bahwa semua kolom sudah tidak memiliki missing value lagi, termasuk kolom province dan brand. Dengan begitu, kita akan siap untuk melakukan pengolahan data pada proses selanjutnya.

Output yang menunjukkan bahwa sudah tidak ada missing value lagi dalam dataset.

6. Berikutnya, kita akan membuat kolom city/province yang merupakan gabungan dari kolom city dan province. Supaya lebih efektif, kita akan menghapus kolom city dan province lalu mengecek 5 data teratasnya.

Perintah untuk membuat kolom city/province, pengganti kolom city dan province.

Di sini, dapat kita lihat bahwa data yang telah kita olah sudah menjadi lebih rapi susunannya. Bandingkan hasilnya dengan dataset yang telah dicek sebelumnya, jumlah kolomnya yang semula berjumlah 9 kini telah berubah menjadi 8 kolom.

Tampilan output setelah diberi kolom city/province dengan menghapus kolom city dan province.

7. Selanjutnya, kita akan membuat index dari kolom city_provice, order_date, customer_id, order_id, dan product_id, lalu kita akan mengurutkannya berdasarkan yang terbaru. Supaya kita dapat mengetahui susunan dari index-index tersebut, kita akan mengecek 5 baris data teratasnya.

Perintah untuk membuat hierarchical index.

Setelah kita set indexnya, terlihat kolom-kolom yang ada sudah jauh lebih sedikit, yaitu sebanyak 3 kolom saja. Sementara itu, index yang ditampilkan sudah sesuai dengan urutan pada kode yang kita eksekusi, yaitu dimulai dari order_date di sebelah kiri hingga product_id di sebelah kanan.

Tampilan dataset retail_raw_test.csv yang sudah diset indexnya.

8. Supaya lebih efektif penyajiannya, kita perlu membuat kolom total_price yang merupakan hasil perkalian dari kolom quantity dengan item_price. Jangan lupa untuk selalu mengecek 5 baris teratasnya, ya.

Perintah untuk membuat kolom total_price.

Pada output ini, data yang ditampilkan sudah jauh lebih rapi dari sebelumnya. Kolomnya kini telah bertambah satu dengan adanya penambahan kolom total_price pada data tersebut. Akan tetapi, jika kita ingin membaca data tersebut hanya untuk jangka waktu tertentu saja, kita harus melakukan slice data terlebih dahulu. Langkah tersebut akan kita lakukan pada tahap selanjutnya.

Tampilan dataset retail_raw_test.csv yang sudah diolah lebih lanjut.

9. Pada tahap akhir ini, kita akan melakukan slice data untuk menyaring tampilan data untuk bulan Januari saja. Supaya kita dapat melihat keseluruhan datanya, kita akan menampilkan seluruh data tersebut tanpa menggunakan .head().

Perintah untuk slice dataset hanya untuk bulan Januari saja.

Nah, sekarang, data tersebut sudah jauh lebih rapi dari tampilannya semula sebelum diolah. Dengan begitu, kita dapat langsung menyajikannya kepada atasan untuk bisa diteliti lebih lagi.

Penampang dataset retail_raw_test.csv untuk bulan Januari saja.

Ok, sekian dulu ya, pembahasan kita kali ini. Semoga pembahasan module kita kali ini bisa semakin memperdalam ilmu kita mengenai Pandas. Next, kita bakalan ketemu lagi sama module Manipulation Data with Pandas — Part 2. Akan ada hal-hal seru yang menanti kalian, lho! See you!

Referensi:

https://academy.dqlab.id/main/package/practice/178?pf=0

--

--