Data Manipulation with Pandas-Part 1

Rinto Prio Rizaldi
16 min readJan 28, 2021

--

Data Manipulation with Pandas

Halo, semuanya. Kali ini saya akan membahas Data Manipulation with Pandas-Part 1 di DQLab.

Pertama, library yang digunakan harus di-import terlebih dahulu. Library yang digunakan adalah Pandas. Penjelasan mengenai library Pandas ini pernah saya tulis di sini.

import pandas as pd

Introduction to Pandas

Dataframe & Series

Sedikit penjelasan mengenai dataframe dan series dapat dilihat di sini. Series adalah satu kolom bagian dari tabel dataframe yang merupakan 1 dimensional numpy array sebagai basis data nya, terdiri dari 1 tipe data (integer, string, float, dll). Dataframe adalah gabungan dari Series, berbentuk rectangular data yang merupakan tabel spreadsheet itu sendiri (karena dibentuk dari banyak Series, tiap Series biasanya punya 1 tipe data, yang artinya 1 dataframe bisa memiliki banyak tipe data).

import pandas as pd# Seriesnumber_list = pd.Series([1,2,3,4,5,6])print("Series:")print(number_list)# DataFramematrix = [[1,2,3],['a','b','c'],[3,4,5],['d',4,6]]matrix_list = pd.DataFrame(matrix)print("DataFrame:")print(matrix_list)
Perbedaan Series dan Dataframe

Atribut Dataframe dan Series

  1. Atribut .info()

Attribut .info() digunakan untuk mengecek kolom apa yang membentuk dataframe itu, tipe data, berapa yang non-null, dll. Attribut ini hanya dapat digunakan pada dataframe saja.

# [1] attribute .info()print("[1] attribute .info()")print(matrix_list.info())
Output dari atribut .info()

Output tersebut memberikan informasi bahwa dataframe tersebut memiliki 3 kolom dengan tipe data object dan 4 data dari setiap kolom bernilai non-null.

2. Atribut .shape

Atribut .shape digunakan untuk mengetahui berapa baris dan kolom, hasilnya dalam format tuple (baris, kolom).

# [2] attribute .shapeprint("\n[2] attribute .shape")print("    Shape dari number_list:", number_list.shape)print("    Shape dari matrix_list:", matrix_list.shape)
Output dari atribut .shape

Atribut .shape memberikan informasi mengenai jumlah baris dari series number_list yang berjumlah 6 baris dan jumlah baris dan kolom dari dataframe matrix_list yang berjumlah 4 baris dan 3 kolom.

3. Atribut .dtypes

Atribut .dtypes digunakan untuk mengetahui tipe data di tiap kolom.

# [3] attribute .dtypesprint("\n[3] attribute .dtypes")print("    Tipe data number_list:", number_list.dtypes)print("    Tipe data matrix_list:", matrix_list.dtypes)
Output dari atribut .dtypes

Hasil dari atribut .dtypes pada number_list adalah int64. Sedangkan, hasil pada matrix_list adalah semua kolom bertipe object. Tipe data object adalah kombinasi untuk berbagai tipe data dalam satu kolom.

4. Atribut .astype()

Atribut .astype() untuk convert tipe data berdasarkan tipe data seperti: float, int, str, numpy.float, numpy.int ataupun numpy.datetime.

# [4] attribute .astype()print("\n[4] attribute .astype()")print("    Konversi number_list ke str:", number_list.astype("str"))print("    Konversi matrix_list ke str:", matrix_list.astype("str"))
Output dari atribut .astype()

Pada syntax di atas, perubahan yang dilakukan adalah mengubah tipe data menjadi string. Sehingga, hasilnya sesuai dengan gambar di atas.

5. Atribut .copy()

Atribut .copy() digunakan melakukan duplikat, untuk disimpan di variabel yang berbeda mungkin supaya tidak loading data lagi.

# [5] attribute .copy()print("[5] attribute .copy()")num_list = number_list.copy()print("    Copy number_list ke num_list:", num_list)mtr_list = matrix_list.copy()print("    Copy matrix_list ke mtr_list:", mtr_list)
Output dari atribut .copy()

Series number_list diduplikat ke num_list dan dataframe matrix_list diduplikasi ke mtr_list

6. Atribut .to_list()

Attribute .to_list() digunakan untuk mengubah series menjadi list dan tidak dapat digunakan untuk dataframe.

# [6] attribute .to_list()print("\n[6] attribute .to_list()")print(number_list.to_list())
Output dari atribut .to_list()

7. Atribut .unique()

Atribut .unique() digunakan menghasilkan nilai unik dari suatu kolom, hasilnya dalam bentuk numpy array. Atribut ini hanya digunakan pada series saja.

# [7] attribute .unique()print("\n[7] attribute .unique()")print(number_list.unique())
Output dari atribut .unique()

Hasil syntax tersebut menyebutkan semau data dari number_list karena data number_list memiliki data yang berbeda satu dengan yang lainnya.

8. Atribut .index

Atribut .index digunakan untuk mencari index/key dari series atau dataframe.

# [8] attribute .indexprint("[8] attribute .index")print("    Index number_list:", number_list.index)print("    Index matrix_list:", matrix_list.index)
Output dari atribut .index

Index dari number_list adalah angka berurutan dari 0 sampai 5. Sedangkan, index dari matrix_list adalah angka berurutan dari 0 sampai 3.

9. Atribut .columns

Atribut .columns digunakan untuk mengetahui apa saja kolom yang tersedia di dataframe tersebut (hanya digunakan untuk dataframe saja).

# [9] attribute .columnsprint("\n[9] attribute .columns")print("    Column matrix_list:", matrix_list.columns)
Output dari atribut .colums

Column dari dataframe matrix_list adalah angka berurutan dari 0 sampai 2.

10. Atribut .loc

Atribut .loc digunakan slice dataframe atau series berdasarkan nama kolom dan/atau nama index.

# [10] attribute .locprint("\n[10] attribute .loc")print("    .loc[0:1] pada number_list:", number_list.loc[0:1])print("    .loc[0:1] pada matrix_list:", matrix_list.loc[0:1])
Output dari atribut .loc

Syntax di atas menghasilkan baris pertama dan kedua dari series number_list dan dataframe matrix_list.

11. Atribut .iloc

Atribute .iloc digunakan untuk slice dataframe atau series berdasarkan index kolom dan/atau index.

# [11] attribute .ilocprint("\n[11] attribute .iloc")print("    iloc[0:1] pada number_list:", number_list.iloc[0:1])print("    iloc[0:1] pada matrix_list:", matrix_list.iloc[0:1])
Output dari atribut .iloc

Hasil output dari atribut .iloc berbeda dengan output dari atribut .loc. Output dari atribut .iloc menghasilkan baris pertama saja. Sedangkan, output dari atribut .loc menghasilkan baris pertama dan kedua.

Creating Series & Dataframe from List

List merupakan sebuah kumpulan data berbagai macam tipe data, yang mutable (dapat diganti).

import pandas as pd# Creating series from listex_list = ['a',1,3,5,'c','d']ex_series = pd.Series(ex_list)print(ex_series)# Creating dataframe from list of listex_list_of_list = [[1  ,'a','b' ,'c'],[2.5,'d','e' ,'f'],[5  ,'g','h' ,'i'],[7.5,'j',10.5,'l']]index = ['dq','lab','kar','lan']cols = ['float','char','obj','char']ex_df = pd.DataFrame(ex_list_of_list, index=index, columns=cols)print(ex_df)
Series dan Dataframe dari List

Creating Series & Dataframe from Dictionary

Dictionary merupakan kumpulan data yang strukturnya terdiri dari key dan value.

import pandas as pd# Creating series from dictionarydict_series = {'1':'a','2':'b','3':'c'}ex_series = pd.Series(dict_series)print(ex_series)# Creating dataframe from dictionarydf_series = {'1':['a','b','c'],'2':['b','c','d'],'4':[2,3,'z']}ex_df = pd.DataFrame(df_series)print(ex_df)
Series dan Dataframe dari Dictionary

Creating Series & Dataframe from Numpy Array

Numpy array kumpulan data yang terdiri atas berbagai macam tipe data, mutable, tapi dibungkus dalam array oleh library Numpy.

import pandas as pdimport numpy as np# Creating series from numpy array (1D)arr_series = np.array([1,2,3,4,5,6,6,7])ex_series = pd.Series(arr_series)print(ex_series)# Creating dataframe from numpy array (2D)arr_df = np.array([[1 ,2 ,3 ,5],[5 ,6 ,7 ,8],['a','b','c',10]])ex_df = pd.DataFrame(arr_df)print(ex_df)
Series dan Dataframe dari Numpy Array

Dataset I/O

Pandas menyediakan berbagai metode untuk membaca file hanya dengan memanggil metode itu, tentu saja output-nya dapat berupa series atau dataframe. Terdapat sangat banyak file yang dapat dibaca/dapat disimpan oleh Pandas, tapi ada beberapa file yang paling umum dan sering digunakan:

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

Read Dataset — CSV dan TSV

CSV dan TSV pada hakikatnya adalah tipe data text dengan perbedaan terletak pada pemisah antar data dalam satu baris. Pada file CSV, antar data dalam satu baris dipisahkan oleh comma, “,”. Namun, pada file TSV antar data dalam satu baris dipisahkan oleh “Tab”.

Fungsi .read_csv() digunakan untuk membaca file yang nilainya dipisahkan oleh comma (default), terkadang pemisah nilainya bisa di-set ‘\t’ untuk file TSV (Tab Separated Values).

import pandas as pd# File CSVdf_csv = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_csv.csv")print(df_csv.head(3)) # Menampilkan 3 data teratas# File TSVdf_tsv = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_tsv.tsv", sep='\t')print(df_tsv.head(3)) # Menampilkan 3 data teratas
3 Data Teratas dari File CSV dan TSV

Read Dataset — Excel

File Excel dengan ekstensi *.xls atau *.xlsx cukup banyak digunakan dalam menyimpan data.

import pandas as pd# File xlsx dengan data di sheet "test"df_excel = pd.read_excel("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_excel.xlsx", sheet_name="test")print(df_excel.head(4)) # Menampilkan 4 data teratas
4 Data Teratas dari File Excel

Read Dataset — JSON

Metode .read_json() digunakan untuk membaca URL API yang formatnya JSON dan merubahnya menjadi dataframe Pandas.

import pandas as pd# File JSONurl = "https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/covid2019-api-herokuapp-v2.json"df_json = pd.read_json(url)print(df_json.head(10)) # Menampilkan 10 data teratas
10 Data Teratas dari File JSON

Read Dataset — SQL

Fungsi .read_sql() atau .read_sql_query() digunakan untuk membaca query dari database dan translate menjadi Pandas dataframe.

Syntax menggunakan fungsi .read_sql_query()
Syntax menggunakan fungsi .read_sql()
Output dari Fungsi .read_sql_query()
Output dari Fungsi .read_sql()

Read Dataset — Google BigQuery

Untuk data yang besar (big data), umumnya digunakan Google BigQuery. Layanan ini dapat digunakan jika telah memiliki Google BigQuery account.

Syntax Menggunakan Fungsi .read_gbq()
Output dari fungsi .read_bgq()

Write Dataset

Pandas menyediakan fitur demikian secara ringkas melalui penerapan method pada dataframe/series yang ditabelkan berikut ini.

Head & Tail

Penjelasan head dan tail pernah saya jelaskan di sini. Metode .head ditujukan untuk membatasi tampilan jumlah baris teratas dari dataset. Sementara itu, metode .tail ditujukan untuk membatasi jumlah baris terbawah dari dataset.

import pandas as pd# Baca file sample_csv.csvdf = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_csv.csv")# Tampilkan 3 data teratasprint("Tiga data teratas:\n", df.head(3))# Tampilkan 3 data terbawahprint("Tiga data terbawah:\n", df.tail(3))
Data 3 Teratas dan 3 Terbawah

Indexing, Slicing, dan Transforming

Indexing

Index merupakan key identifier dari tiap row/column untuk series atau dataframe (sifatnya tidak mutable untuk masing-masing value tapi bisa diganti untuk semua value sekaligus). Nilai default dari index ini adalah bilangan bulat (integer) dari 0 sampai range jumlah baris data tersebut.

Kolom index dapat terdiri dari:

  1. satu kolom (single index), atau
  2. multiple kolom (disebut dengan hierarchical indexing).

Index dengan multiple kolom ini terjadi karena unique identifier tidak dapat dicapai hanya dengan set index di 1 kolom saja sehingga membutuhkan beberapa kolom yang menjadikan tiap row menjadi unique.

Secara default setelah suatu dataframe dibaca dari file dengan format tertentu, index-nya merupakan single index.

import pandas as pd# Baca file TSV sample_tsv.tsv
df = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_tsv.tsv", sep="\t")
# Index dari df
print("Index:", df.index)
# Column dari df
print("Columns:", df.columns)
Index dan Kolom dari Dataframe df

Index baris dari df adalah bilangan berurutan dari 0 sampai 100 dan kolomnya berjumlah 9 dengan nama yang berbeda-beda

Untuk membuat hierarchical indexing dengan Pandas diperlukan kolom-kolom mana saja yang perlu disusun agar index dari dataframe menjadi sebuah hirarki yang kemudian dapat dikenali.

# Set multi index df
df_x = df.set_index(['order_date', 'city', 'customer_id'])
# Print nama dan level dari multi index
for name, level in zip(df_x.index.names, df_x.index.levels):
print(name,':',level)
Index dari Dataframe df_x

Index dari df_x adalah order_date, city, dan customer_id. Pada order_date, hanya ada satu data. Pada city dan customer_id, ada 8 data berbeda dan 10 data berbeda.

Terdapat beberapa cara untuk membuat index, salah satunya dengan menggunakan metode .set_index().

# Cetak data frame awal
print("Dataframe awal:\n", df)
# Set index baru
df.index = ["Pesanan ke-" + str(i) for i in range(1,11)]
# Cetak data frame dengan index baru
print("Dataframe dengan index baru:\n", df)
Index Terbaru dari Dataframe df

Index dapat diatur ketika file dibaca oleh Pandas, dengan menggunakan argumen index_col.

# Baca file sample_tsv.tsv dan set lah index_col sesuai instruksi
df = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_tsv.tsv", sep="\t", index_col=["order_date", "order_id"])
# Cetak data frame untuk 8 data teratas
print("Dataframe:\n", df.head(8))
Set Index Menggunakan Argumen index_col

Slicing

Slicing adalah cara untuk melakukan filter ke dataframe/series berdasarkan kriteria tertentu dari nilai kolomnya ataupun kriteria index-nya. Terdapat 2 cara yang paling biasa dilakukan untuk slicing dataframe, yaitu dengan menggunakan fungsi .loc dan .iloc. .iloc ditujukan untuk proses slicing berdasarkan index berupa nilai integer tertentu. Akan tetapi akan lebih sering menggunakan .loc karena lebih fleksibel.

import pandas as pd# Baca file sample_csv.csv
df = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_csv.csv")
# Slice langsung berdasarkan kolom
df_slice = df.loc[(df["customer_id"] == "18055") & (df["product_id"].isin(["P0029","P0040","P0041","P0116","P0117"]))]
print("Slice langsung berdasarkan kolom:\n", df_slice)
Hasil Slicing

Hasil slicing dari dataframe df di atas adalah empty dataframe.

Selanjutnya, slicing berdasarkan index. Tentu syaratnya adalah dataset sudah dilakukan indexing terlebih dahulu melalui penerapan metode .set_index.

# Set index dari df sesuai instruksi
df = df.set_index(["order_date","order_id","product_id"])
# Slice sesuai intruksi
df_slice = df.loc[("2019-01-01",1612339,["P2154","P2159"]),:]
print("Slice df:\n", df_slice)
Hasil Slicing Berdasarkan Index

Index dari hasil slicing di atas adalah order_date, order_id, dan product_id. Kemudian, slicing dilakukan dengan menggunakan data dari index tersebut.

Transforming

Transforming adalah ketika mengubah dataset yang ada menjadi entitas baru, dapat dilakukan dengan konversi dari satu data type ke data type yang lain, transpose dataframe, atau yang lainnya.

Untuk konversi tipe data, secara default sistem akan mendeteksi data yang tidak bisa di-render sebagai date type atau numeric type sebagai object yang basically string. Tidak bisa di render oleh system ini karena berbagai hal, mungkin karena formatnya asing dan tidak dikenali oleh Python secara umum (misal: date type data → ‘2019Jan01’).

Data contoh tersebut tidak bisa di render karena bulannya Jan tidak bisa di translate menjadi in form of number (00–12) dan tidak ada ‘-’ di antara tahun, bulan dan harinya. Jika seluruh data pada kolom di order_date sudah tertulis dalam bentuk ‘YYYY-MM-DD’ maka ketika dibaca, kolom order_date sudah langsung dinyatakan bertipe data datetime.

Untuk merubah kolom date_order yang sebelumnya bertipe object menjadi kolom bertipe datetime, cara pertama yang dapat dilakukan adalah menggunakan pd.to_datetime(argumen)

import pandas as pd# Baca file sample_csv.csvdf = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_csv.csv")# Tampilkan tipe dataprint("Tipe data df:\n", df.dtypes)# Ubah tipe data kolom order_date menjadi datetimedf["order_date"] = pd.to_datetime(df["order_date"])# Tampilkan tipe data df setelah transformasiprint("\nTipe data df setelah transformasi:\n", df.dtypes)
Perubahan Tipe Data Menjadi Datetime

Kolom order_date yang awalnya bertipe data object dapat diubah menjadi datetime.

Secara umum, untuk merubah ke numerik dapat menggunakan pd.to_numeric(). Sedangkan, untuk mengubah suatu kolom menjadi category dapat menggunakan metode .astype() pada dataframe.

# Tampilkan tipe dataprint("Tipe data df:\n", df.dtypes)# Ubah tipe data kolom quantity menjadi tipe data numerik floatdf["quantity"] = pd.to_numeric(df["quantity"], downcast="float")# Ubah tipe data kolom city menjadi tipe data categorydf["city"] = df["city"].astype("category")# Tampilkan tipe data df setelah transformasiprint("\nTipe data df setelah transformasi:\n", df.dtypes)
Perubahan Tipe Data Menjadi Category dan Float

Kolom city dan kolom quantity yang awalnya bertipe object dan integer berubah menjadi category dan float.

Metode .apply() digunakan untuk menerapkan suatu fungsi Python (yang dibuat dengan def atau anonymous dengan lambda) pada dataframe/series atau hanya kolom tertentu dari dataframe.

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

import pandas as pd# Baca file sample_csv.csvdf = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/sample_csv.csv")# Cetak 5 baris teratas kolom brandprint("Kolom brand awal:\n", df["brand"].head())# Gunakan method apply untuk merubah isi kolom menjadi lower casedf["brand"] = df["brand"].apply(lambda x: x.lower())# Cetak 5 baris teratas kolom brandprint("Kolom brand setelah apply:\n", df["brand"].head())# Gunakan method map untuk mengambil kode brand yaitu karakter terakhirnyadf["brand"] = df["brand"].map(lambda x: x[-1])# Cetak 5 baris teratas kolom brandprint("Kolom brand setelah map:\n", df["brand"].head())
Hasil Penggunaan .apply() dan .map()

Penggunaan .apply() pada syntax di atas adalah untuk membuat semua huruf pada data di kolom brand menjadi kecil. Sedangkan, penggunaan .map() ditujukan untuk memilih satu huruf terakhir dari data di kolom brand.

import numpy as npimport pandas as pd# number generator, set angka seed menjadi suatu angka, bisa semua angka, supaya hasil random nya selalu sama ketika kita runnp.random.seed(1234)# create dataframe 3 baris dan 4 kolom dengan angka randomdf_tr = pd.DataFrame(np.random.rand(3,4))# Cetak dataframeprint("Dataframe:\n", df_tr)# Cara 1 dengan tanpa define function awalnya, langsung pake fungsi anonymous lambda xdf_tr1 = df_tr.applymap(lambda x: x**2+3*x+2)print("\nDataframe - cara 1:\n", df_tr1)# Cara 2 dengan define functiondef qudratic_fun(x):return x**2+3*x+2df_tr2 = df_tr.applymap(qudratic_fun)print("\nDataframe - cara 2:\n", df_tr2)
Penggunaan .applymap()

Handling Missing Values

Value yang hilang/tidak lengkap dari dataframe akan membuat analisis atau model prediksi yang dibuat menjadi tidak akurat dan mengakibatkan keputusan yang diambil salah. Di Pandas, data yang hilang umumnya direpresentasikan dengan NaN. Terdapat beberapa cara untuk mengatasi data yang hilang/tidak lengkap tersebut.

Untuk mengetahui nilai Nan pada data, dapat menerapkan metode .info() pada dataframe. Selain itu, mengetahui berapa banyak nilai hilang dari tiap kolom di dataset tersebut dengan menerapkan chaining method pada dataframe yaitu .isna().sum(). Method .isna() digunakan untuk mengecek berapa data yang bernilai NaN dan .sum() menjumlahkannya secara default untuk masing-masing kolom dataframe.

import pandas as pd# Baca file "public data covid19 jhu csse eu.csv"df = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/CHAPTER+4+-+missing+value+-+public+data+covid19+.csv")# Cetak info dari dfprint(df.info())# Cetak jumlah missing value di setiap kolommv = df.isna().sum()print("\nJumlah missing value per kolom:\n", mv)
Info Dataframe df dan julah data yang bernilai NaN.

Terdapat beberapa cara untuk mengatasi missing value, antara lain:

  1. dibiarkan saja,
  2. hapus value itu, atau
  3. isi value tersebut dengan value yang lain (biasanya interpolasi, mean, median, etc)

Treatment pertama (membiarkannya saja) seperti pada kolom confirmed, death, dan recovered. Akan tetapi jika tidak ada yang terkonfirmasi, meninggal dan sembuh sebenarnya dapat menukar value ini dengan angka nol. Meskipun ini lebih make sense dalam representasi datanya, tetapi ketiga kolom tersebut diasumsikan dibiarkan memiliki nilai missing value.

Treatment kedua yaitu dengan menghapus kolom, yang mana ini digunakan jika seluruh kolom dari dataset yang dipunyai semua barisnya adalah missing value.

import pandas as pd# Baca file "public data covid19 jhu csse eu.csv"df = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/CHAPTER+4+-+missing+value+-+public+data+covid19+.csv")# Cetak ukuran awal dataframeprint("Ukuran awal df: %d baris, %d kolom." % df.shape)# Drop kolom yang seluruhnya missing value dan cetak ukurannyadf = df.dropna(axis=1, how="all")print("Ukuran df setelah buang kolom dengan seluruh data missing: %d baris, %d kolom." % df.shape)# Drop baris jika ada satu saja data yang missing dan cetak ukurannyadf = df.dropna(axis=0, how="any")print("Ukuran df setelah dibuang baris yang memiliki sekurangnya 1 missing value: %d baris, %d kolom." % df.shape)
Jumlah Baris dan Kolom Sebelum dan Sesudah Menghapus Mising Value

Pada .dropna(), terdapat argumen axis dan how. Axis dapat diisi dengan memilih angka 0 yang menyatakan kolom dan angka 1 yang menyatakan baris. How digunakan untuk bagaimana cara membuangnya. Opsi dari how adalah all yang artinya jika seluruh data di satu/beberapa kolom atau di satu/beberapa baris adalah missing value dan any yang artinya jika memiliki 1 saja data yang hilang maka buanglah baris/kolom tersebut.

Treatment ketiga untuk menghandle missing value pada dataframe dilakukan dengan cara mengisi missing value dengan nilai lain, yang dapat berupa :

  • nilai statistik seperti mean atau median
  • interpolasi data
  • text tertentu

Kolom province_state, karena tidak tahu secara persis province_state mana yang dimaksud, bisa menempatkan string “unknown” sebagai substitusi missing value. Meskipun keduanya berarti sama-sama tidak tahu tetapi berbeda dalam representasi datanya.

import pandas as pd# Baca file "public data covid19 jhu csse eu.csv"df = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/CHAPTER+4+-+missing+value+-+public+data+covid19+.csv")# Cetak unique value pada kolom province_stateprint("Unique value awal:\n", df["province_state"].unique())# Ganti missing value dengan string "unknown_province_state"df["province_state"] = df["province_state"].fillna("unknown_province_State")# Cetak kembali unique value pada kolom province_stateprint("Unique value setelah fillna:\n", df["province_state"].unique())
Nilai nan yang Diubah Menjadi unknown_province_state

Dengan mengabaikan terlebih dahulu sebaran berdasarkan negara (univariate), jika mengisi kolom active dengan nilai rata-rata maka harus melihat terlebih dahulu data apakah memiliki ouliers atau tidak. Jika ada outliers dari data maka menggunakan nilai tengah (median) data adalah cara yang lebih safe.

Untuk itu diputuskan dengan mengecek nilai median dan nilai mean kolom active juga nilai min dan max-nya. Jika data pada kolom active terdistribusi normal maka nilai mean dan median akan hampir sama.

Nilai Min, Mean, Median, dan Max dari Kolom Active

Mean dan median dari kolom active memiliki perbedaan yang besar. Sehingga, pasti ada outliers. Oleh karena itu, median dipilih untuk mengisi missing value.

import pandas as pd# Baca file "https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/CHAPTER+4+-+missing+value+-+public+data+covid19+.csv"df = pd.read_csv("https://dqlab-dataset.s3-ap-southeast-1.amazonaws.com/CHAPTER+4+-+missing+value+-+public+data+covid19+.csv")# Cetak nilai mean dan median awalprint("Awal: mean = %f, median = %f." % (df["active"].mean(), df["active"].median()))# Isi missing value kolom active dengan mediandf_median = df["active"].fillna(df["active"].median())# Cetak nilai mean dan median awal setelah diisi dengan medianprint("Fillna median: mean = %f, median = %f." % (df_median.mean(), df_median.median()))# Isi missing value kolom active dengan meandf_mean = df["active"].fillna(df["active"].mean())# Cetak nilai mean dan median awal setelah diisi dengan meanprint("Fillna mean: mean = %f, median = %f." % (df_mean.mean(), df_mean.median()))
Nilai Mean dan Median Awal dan Akhir

Data yang menggunakan interpolasi untuk mengisi data yang hilang adalah time series data, yang secara default akan diisi dengan interpolasi linear.

import numpy as np
import pandas as pd
# Data
ts = pd.Series({
"2020-01-01":9,
"2020-01-02":np.nan,
"2020-01-05":np.nan,
"2020-01-07":24,
"2020-01-10":np.nan,
"2020-01-12":np.nan,
"2020-01-15":33,
"2020-01-17":np.nan,
"2020-01-16":40,
"2020-01-20":45,
"2020-01-22":52,
"2020-01-25":75,
"2020-01-28":np.nan,
"2020-01-30":np.nan
})
# Isi missing value menggunakan interpolasi linier
ts = ts.interpolate()
# Cetak time series setelah interpolasi linier
print("Setelah diisi missing valuenya:\n", ts)
Setelah Mising Value dari Series Diisi

Itu semua adalah hasil belajar saya pada modul Data Manipulation with Pandas — Part 1 di DQLab.

Terima kasih telah membaca.

--

--