Basic Data Science Library¶
Aktivitas yang paling sering dilakukan oleh data scientist adalah eksplorasi data. Bahkan, IBM menyebutkan bahwa 80% waktu data scientist habis untuk mengeksplor dan memahami data. Untuk melakukannya, data scientist umumnya tidak cukup hanya menggunakan built-in library dari Python, diperlukan third-party library yang lebih efisien dalam mengolah dan memproses data yang biasanya sangat besar. Beberapa library yang umum digunakan seperti:
NumPy
Pandas
Matplotlib
Seaborn
Oleh karena itu, kita akan berkenalan dengan 4 library di atas dan mencoba melakukan data eksplorasi pada dataset publik.
Persiapan¶
Sebelum kita mulai menggunakan ke-4 library ini, pastikan semuanya sudah terpasang. Kita bisa cek menjalankan perintah berikut pada cell baru:
# uncomment below code to check installed packages
#!pip list | grep -E "numpy|matplotlib|pandas|seaborn"
Perintah di atas akan menampilkan nama library beserta angka version yang terpasang. Jika ternyata salah satu atau bahkan semua library belum terpasang, kita harus install terlebih dahulu menggunakan perintah:
# uncomment below code to install necessary packages, if you haven't
#!pip install numpy matplotlib pandas seaborn
Setelah semuanya siap, kita bisa lansung import 4 library tersebut.
# import things
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
The Power of NumPy¶
Apa Itu NumPy?
NumPy is an open source project aiming to enable numerical computing with Python. It was created in 2005, building on the early work of the Numerical and Numarray libraries - numpy official site
Dari definisi resmi di atas, kita sudah paham bahwa NumPy adalah sebuah package yang digunakan untuk komputasi numerik.
Why NumPy (instead of built-in List)?¶
Dengan menggunakan NumPy array, kita bisa melakukan operasi matematika yang tidak bisa dilakukan oleh List. Selain itu, NumPy array lebih cepat daripada List (referensi).
Array¶

Fig. 1 NumPy Array¶
Array adalah struktur data utama dalam NumPy. NumPy array juga mengonsumsi lebih sedikit memori dan mempunyai mekanisme menentukan tipe data (referensi).
arr_1d = np.array([1, 2, 3])
arr_1d
type(arr_1d)
Note
numpy.ndarray
adalah sebuah class yang merepresentasikan vektor dan juga matriks
# dimensi array
arr_1d.shape
Apa perbedaan array, vektor, dan matriks?
Vektor adalah array berdimensi satu (vektor baris = vektor kolom), sedangkan matriks adalah array berdimensi dua. Sehingga, array merupakan sebuah representasi data dalam n
-dimensi.
arr_2d = np.array([[1, 2], [3, 4], [5, 6]])
arr_2d
arr_2d.shape
arr_3d = np.array([[[0, 1, 2], [1, 2, 3]], [[10, 11, 12], [11, 12, 13]]])
arr_3d
arr_3d.shape
Pembuatan Array Otomatis¶
Selain dengan np.array
, kita juga bisa membuat array secara otomatis dengan nilai dan pola tertentu.
arr_zeros = np.zeros((3, 3))
arr_zeros
arr_ones = np.ones((2, 2))
arr_ones
arr_empty = np.empty(2)
arr_empty
arr_arange = np.arange(start=-3, stop=4, step=1)
arr_arange
arr_space = np.linspace(start=1, stop=2)
arr_space
arr_identity = np.eye(4)
arr_identity
arr_full = np.full((4, 4), 5)
arr_full
Indexing dan Slicing¶
NumPy array juga memberikan kita keleluasaan untuk mengambil sebagian nilai dalam suatu array. Hampir mirip dengan list
yang juga membolehkan kita untuk indexing dan slicing, akan tetapi dengan cara yang lebih elegan.

Fig. 2 Indexing in 2-Dimensional NumPy Array¶
List vs NumPy
Misal kita gunakan arr_2d
. Kita ingin menampilkan nilai pada:
Baris pertama dan kolom kedua
Baris kedua dan ketiga dan kolom kedua
List
list_arr_2d[0][1]
list_arr_2d[-2:][1]
NumPy
arr_2d[0, 1]
arr_2d[-2:, 1]
Penomoran indeks pada NumPy array sama dengan indeks pada list.

Fig. 3 Penomoran indeks pada array¶
arr_2d
print("row 0:", arr_2d[2, :])
print("row 0:", arr_2d[0, ...])
print("row 1:", arr_2d[1, :])
Eksplorasi
Dengan menggunakan arr_3d
:
Tampilkan array 2-dimensi dengan nilai [[0, 1, 2], [11, 12, 13]]
Tampilkan array 2-dimensi dengan nilai [[3, 2], [13, 12]]
# TODO: [[0, 1, 2], [11, 12, 13]]
# TODO: [[3, 2], [13, 12]]
Fungsi yang Sering Digunakan dalam NumPy¶
Beberapa fungsi yang sering digunakan saat eksplorasi data.
Pengambilan sampel acak: np.random
arr_random = np.random.rand(5, 5) # bilangan acak berdistribusi uniform dengan ukuran 5x5
arr_random
arr_randn = np.random.randn(4, 10)
arr_randn
arr_randint = np.random.randint(low=-10, high=10, size=(2, 3))
arr_randint
Warning
Sebagai catatan, versi terbaru NumPy menyarankan untuk menggunakan np.random.default_rng()
setiap kali kita ingin membangkitkan bilangan acak.
generator = np.random.default_rng(41)
y = generator.random((1, 10))
print(y)
yhat = generator.random((1, 10))
print(yhat)
Pengubahan ukuran array: np.reshape
, arr.flatten
print("ukuran array:", arr_randn.shape)
arr_randn_2 = arr_randn.reshape(5, 8) # atau dengan np.reshape
print("ukuran array baru:", arr_randn_2.shape)
print(arr_randn_2)
arr_flatten = arr_randn.flatten()
print("ukuran array flatten:", arr_flatten.shape)
print(arr_flatten)
Penggabungan array: np.concatenate
arr_randint_2 = np.concatenate([arr_randint, arr_randint[-1].reshape(1, arr_randint.shape[1])*-1])
arr_randint_2
arr_ero = np.concatenate([np.eye(arr_randint_2.shape[0]), arr_randint_2], axis=1)
arr_ero
Pengurutan: np.sort
np.sort(arr_2d) # mengurutkan nilai column-wise (default)
np.sort(arr_2d, axis=0)
Mathematical Formula¶
Salah satu keunggulan NumPy array adalah kemampuannya untuk melakukan komputasi numerik dengan cepat. Mari kita coba menghitung nilai MSE dengan NumPy array.
Tip
Bisa menggunakan numpy.sum
atau built-in function sum
dari Python.
# TODO: hitung nilai MSE dengan fungsi numpy
Pandas Is All You Need¶
Apa Itu Pandas
Pandas is a software library written for the Python programming language for data manipulation and analysis. In particular, it offers data structures and operations for manipulating numerical tables and time series - wikipedia
Pandas (dari panel data) berfungsi sebagai pondasi dasar tingkat tinggi untuk melakukan analisis data secara praktis (source). Perbedaan dengan NumPy adalah pandas didesain untuk bekerja dengan data tabular atau heterogen, sedangkan NumPy didesain untuk bekerja dengan data numerik homogen.
Series¶
Series adalah struktur data berdimensi satu (seperti array 1 dimensi pada NumPy) yang memiliki sebuah label yang biasa disebut index.
series_1 = pd.Series([-3, -2, -1, 0, 1, 2, 3])
series_1
series_1.name = "integers"
series_1
print("index:", series_1.index)
# ubah index dengan alfabet
series_1.index = ["a", "b", "c", "d", "e", "f", "g"]
print("index baru:", series_1.index)
series_1
dict_population = {"Texas": 71000, "Oregon": 16000, "Ohio": 35000, "Utah": 500}
states = ["California", "Texas", "Ohio", "Utah"]
s_population = pd.Series(dict_population, index=states, name="population")
DataFrame¶
DataFrame merepresentasikan sebuah data berbentuk tabel yang terdiri dari beberapa kolom dengan tipe data tertentu dan baris dengan index-nya.
Seperti halnya NumPy array, kita bisa mendapatkan ukuran dari sebuah DataFrame/Series dengan variabel shape
.
df_marvel = pd.DataFrame({
"Name": ["Tony Stark", "Strange", "Peter Parker", "Natasha"],
"Age": [35, 34, 22, 30],
"Sex": ["Male", "Male", "Male", "Female"]
})
df_marvel
df_array = pd.DataFrame(arr_ero)
df_array
print("Nama kolom:", df_array.columns)
print("Nama index:", df_array.index)
n_row, n_col = df_array.shape
print("Jumlah baris:", n_row)
print("Jumlah kolom:", n_col)
Membaca File¶
Salah satu keunggulan Pandas adalah kemampuan untuk membaca sebuah file data dan menampilkannya dalam format DataFrame. Pandas menyediakan beberapa function untuk membaca file sesuai dengan formatnya, read_csv
untuk file .csv
, read_excel
untuk file Excel, read_gbq
untuk membaca tabel dari Google BigQuery, dan lainnya.
Sebagai contoh, kita coba baca sebuah data konten akun perusahaan-perusahaan dari LinkedIn. Terlebih dahulu kita harus unduh datanya melalui link ini. Kemudian, simpan data tersebut di dalam sebuah folder data
.
df_company = pd.read_csv("data/company_data.csv")
df_company.head() # menampilkan pratinjau 5 baris pertama data
df_company.tail() # menampilkan pratinjau 5 baris terakhir data
Jika data berhasil dibaca dengan benar, kita akan temui beberapa kolom dengan nilai NaN
atau singkatan dari Not a number. Jenis nilai ini diturunkan dari NumPy array (np.nan
) yang juga digunakan dalam Pandas. Salah satu method yang bisa kita gunakann untuk mendapatkan pratinjau keseluruhan tipe data tiap kolom pada DataFrame adalah info
.
Ringkasan DataFrame¶
df_company.info()
Informasi di atas menjelaskan beberapa hal:
RangeIndex: 11654 entries, 0 to 11653
menjelaskan bahwa terdapat 11654 baris dengann indeks 0 sampai 11653.Data columns (total 19 columns):
menjelaskan terdapat total 19 kolom yang diikuti informasi tiap kolom di bawahnyaPada tabel di atas, kolom paling kanan,
Dtype
menjelaskan tipe data yang ada pada masing-masing kolom. Beberapa tipe data yang didukung oleh Pandas bisa dilihat di sini.Kolom kedua dari kanan merepresentasikan jumlah nilai
non-null
atau nilai yang bukanNaN
atauNaT
(nilai N/A untuk tipe datadatetime
).Dua kolom paling kiri menjelaskan nama kolom serta indeks kolom.
Dari informasi yang disediakan oleh method info
di atas, kita sudah bisa membuat pertanyaan-pertanyaan awal seperti:
Kolom mana saja yang memiliki missing value? …
Berapa persentase missing value pada masing-masing kolom? …
Apakah semua kolom sudah berasosiasi dengan tipe data yang benar? …
cols_with_missing = df_company.columns[df_company.isna().any()].tolist()
cols_without_missing = df_company.columns[df_company.notna().all()].tolist()
print("Kolom dengan missing value:", cols_with_missing)
print("Kolom tanpa missing value:", cols_without_missing)
Eksplorasi
Berapa persentasi missing value tiap kolom?
Untuk menjawab pertanyaan di atas, kita bisa secara sederhana menghitung jumlah missing value pada setiap kolom yang memiliki missing value, kemudian bagi dengan jumlah barisnya.
# TODO: hitung persentase missing value tiap kolom
Selain method info
, Pandas juga menyediakan function untuk menunjukkan statistics summary sesuai dengan tipe data tiap kolom, yaitu describe
.
df_company.describe() # stats summary untuk kolom bertipe data numerik
df_company.describe(exclude="number") # stats summary untuk kolom-kolom selain kolom numerik
Dari ringkasan statistik di atas, ada 2 kolom dengan persentase missing value yang sangat besar, yaitu views
dan votes
. Ada 2 cara untuk menangani missing value pada suatu data, yaitu kita bisa drop kolom atau baris dengan missing value tersebut atau kita bisa beri nilai berdasarkan rata-rata, median, modus, atau cara lain, sesuai dengan kebutuhan. Untuk kali ini, karena tujuan kita adalah eksplorasi data, kita bisa “buang” 2 kolom tersebut dengan method drop
atau dropna
.
Tip
drop
mengizinkan kita untuk membuang data dengan menentukan baris atau kolom yang hendak dibuang. Sedangkan, dropna
akan membuang baris atau kolom berdasarkan kondisi ada atau tidaknnya missing value pada baris atau kolom tersebut.
df_company.drop(columns=["views", "votes", "Unnamed: 0"])
Eksplorasi
Ada berapa jenis
media_type
yang di-post oleh perusahaan-perusahaan tersebut?Tampilkan ragam kategori media tersebut!
Tampilkan frekuensi penggunaan kategori media secara keseluruhan!
Terdapat kolom Kategori
yang berisi nilai dengan tipe data object
. Kita bisa mendapatkan ragam nilai dalam kolom tersebut dengan menggunakan method nunique
, unique
, dan value_counts
.
# TODO: jumlah kategori `media_type`
# TODO: ragam kategori media
# TODO: frekuensi penggunaan media berdasarkan kategorinya
Sekarang, misalkan kita ingin mengetahui statistik keseluruhan dari masing-masing perusahaan dalam hal jumlah koneksi (connections), jumlah pengikut (followers), jumlah reaksi terhadap post (reactions), dan jumlah komentar (comments). Langkah pertama mungkin kita ingin melihat beberapa contoh perusahaan satu per satu. Kita bisa gunakan atribut .loc
ataupun .iloc
untuk melakukan indexing dan juga slicing.
df_company.loc[df_company.name == "Pfizer"]
df_company.loc[df_company.name == "AT&T"].head()
Kita tidak mungkin untuk menghitung satu per satu statistik perusahaan karena frekuensi post tiap perusahaan yang sangat banyak. Untuk itu, kita bisa menggunakan fitur pandas, yaitu gruopby
, yang akan mengelompokkan data berdasarkan suatu kolom yang diberikan, kemudian melakukan operasi atau agregasi apapun yang kita hendaki.
df_company.groupby("name").agg({"reactions": sum, "comments": sum})
Jika kita ingin menghasilkan data agregasi yang lebih rapi dan representatif, kita bisa tambahkan beberapa fungsi bawaan pandas seperti berikut.
df_company.groupby("name").agg({"reactions": sum, "comments": sum}).rename(columns={"reactions": "sum_reactions", "comments": "sum_comments"}).rename_axis(None)
Visualizing Data with Matplotlib & Seaborn¶
Visualisasi data sebenanrya sebagian seni dan sebagian lagi sains. Tantangannya adalah bagaimana menghasilkan visual (seni) yang benar tanpa merusak sains dalam data dan sebaliknya. Visualisasi bisa kita bagi menjadi just right, ugly, bad, dan wrong (referensi).

Fig. 6 Contoh visualisasi yang cenderung ugly, bad, dan wrong.¶
Apa Itu Matplotlib?
Matplotlib is a Python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. Matplotlib can be used in Python scripts, the Python and IPython shells, the Jupyter notebook, web application servers, and four graphical user interface toolkits. - TDS
Sebagai latihan untuk visualisasi data, kita akan menggunakan data dari Food Demand Forecasting. Pertama, kita coba baca data dari file data/food-demand-forecasting/
. Ada 3 data yang akan kita muat:
fulfilment_center_info.csv
: informasi tentang dapur kota (fulfilment center)meal_info.csv
: informasi tentang makanan yang disediakanfood_demand.csv
: histori data permintaan makanan
Perlu diketahui, tujuan kita bukan untuk membuat model machine learning, tapi eksplorasi data yang dibantu dengan visualisasi.
df_center = pd.read_csv("data/food-demand-forecasting/fulfilment_center_info.csv")
df_center.head()
df_meal = pd.read_csv("data/food-demand-forecasting/meal_info.csv")
df_meal.head()
df_demand = pd.read_csv("data/food-demand-forecasting/food_demand.csv")
df_demand.head()
Pada df_demand
, kolom center_id
dan meal_id
berturut-turut merepresentasikan identifier pada df_center
dan df_meal
. Daripada kita harus melihat 3 tabel sepanjang melakukan eksplorasi, kita bisa menggabungkan ketiga data ini menjadi satu tabel berdasarkan center_id
dan meal_id
menggunakan method merge
dari Pandas.
df = pd.merge(df_demand, df_center, on="center_id")
df.head()
df = pd.merge(df, df_meal, on="meal_id")
df.head()
What to Visualize¶
Ada beberapa jenis visualisasi yang bisa dibuat sesuai dengan jenis data dan tujuan yang ingin disampaikan.
Kuantitas: Bentuk visualisasi yang sering digunakan untuk menunjukkan sebuah jumlah/kuantitas dalam suatu kategori adalah bar plot (vertikal atau horizontal)
Jika terdapat beberapa grup kategori yang ditampilkan nilai jumlahnya, kita bisa membuat grouped bar atau stacked bar.
Distribusi: Bentuk visualisasi yang sering digunakan untuk menunjukkan distribusi dari suatu kolom adalah histogram atau density plot.
Jika kita ingin menampilkan beberapa distribusi untuk dibandingkan satu sama lain, kita bisa menggunakan visualisasi seperti boxplot, violins, dan lainnya seperti contoh di bawah ini.
Proporsi: Untuk tujuan proporsi, kita bisa menggunakan beberapa bentuk visualisasi seperti di bawah ini.
Relasi x-y: Untuk tujuan ini, kita bisa menggunakan visualisasi seperti scatter plot, line plot, ataupun juga bubble chart (3 variabel). Berikut beberapa contoh visualisasinya.
Bar Plot¶
Misal kita ingin menunjukkan kategori makanan terpopuler dari semua permintaan makanan pada tiap kota. Kita harus menghitung jumlah permintaan untuk setiap kategori terlebih dahulu menggunakan method groupby
.
Selanjutnya, untuk membuat bar plot, kita gunakan function plt.bar
.
grouped_category = df.groupby(by="category")
sum_category_orders = grouped_category.aggregate({
"num_orders": np.sum
})
plt.bar(sum_category_orders.index, sum_category_orders["num_orders"])
plt.show()
# ukuran canvas
plt.figure(figsize=(12, 6))
plt.bar(sum_category_orders.index, sum_category_orders["num_orders"])
# konfigurasi di x-axis
plt.xticks(rotation=75)
plt.xlabel("Food Category")
# konfigurasi di y-axis
plt.ylabel("Quantity Sold")
# judul plot
plt.title("Most Popular Food")
plt.show()
plt.figure(figsize=(12, 6))
sns.barplot(sum_category_orders.index, sum_category_orders["num_orders"])
plt.xticks(rotation=75)
plt.xlabel("Food Category")
plt.ylabel("Quantity Sold")
plt.title("Most Popular Food")
plt.show()
Pie Chart¶
Mari kita lihat presentase pesanan untuk setiiap cuisine.
total_orders = df["num_orders"].sum()
dict_cuisine = {
cuisine: df.loc[df['cuisine']==cuisine, "num_orders"].sum() / total_orders
for cuisine in df["cuisine"].unique()
}
plt.figure(figsize=(12, 6))
plt.pie(
dict_cuisine.values(),
labels=dict_cuisine.keys(),
autopct="%.1f",
explode=[0., 0., .1, 0.]
)
plt.title("Cuisine Share %")
plt.show()
Histogram¶
Histogram digunakan untuk menampilkan distribusi dari suatu data numerik.
plt.hist(df["base_price"])
plt.show()
plt.figure(figsize=(15, 6))
plt.hist(
df["base_price"],
bins=15,
rwidth=.9,
color="#F57C01",
edgecolor="blue"
)
plt.show()
plt.figure(figsize=(15, 6))
sns.distplot(df["base_price"])
plt.show()
Line Plot¶
Line plot sering digunakan untuk menampilkan data tren. Dalam kasus ini, kita akan menggunakan data food demand.
avg_weekly_food_demand = df.groupby("week")[["checkout_price", "num_orders", "base_price"]].mean()
plt.figure(figsize=(15, 6))
plt.plot(avg_weekly_food_demand.index, avg_weekly_food_demand["base_price"], label="base_price")
plt.plot(avg_weekly_food_demand.index, avg_weekly_food_demand["checkout_price"], label="checkout_price")
plt.legend()
plt.show()
plt.figure(figsize=(18, 9))
sns.lineplot(x=avg_weekly_food_demand.index, y="base_price", data=avg_weekly_food_demand)
sns.lineplot(x=avg_weekly_food_demand.index, y="checkout_price", data=avg_weekly_food_demand)
plt.show()