Pengolahan Data dengan Pandas
Pada chapter ini, kita akan belajar menggunakan module eksternal Pandas untuk melakukan pengolahan data. Untuk melakukan instalasi pandas
, buka program CMD.exe Prompt
lewat Anaconda Navigator, lalu jalankan perintah di bawah ini:
conda install pandas
Setelah itu, jalankan aplikasi Spyder dari Anaconda Navigator dan tulis kode di bawah ini untuk melakukan impor module Pandas:
import pandas as pd
Mengenal DataFrame
Pandas memiliki konsep DataFrame
yang merepresentasikan sebuah data structure tabular atau data berbentuk tabel yang terdiri dari row dan column. Contoh di bawah ini memperlihatkan cara untuk membuat variable DataFrame
:
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
print(df)
# Output:
# name nationality age
# 0 Christiano Ronaldo Portugal 39
# 1 Lionel Messi Argentina 36
# 2 Kylian Mbappé France 25
Apabila dijalankan, variable df
akan menyimpan DataFrame
dengan 3 column (ânameâ, ânationalityâ, dan âageâ) dan 3 row.
Untuk mendapatkan semua nilai pada column tertentu, kita dapat menulis kode seperti contoh berikut:
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
print(df['name'])
# Output:
# 0 Christiano Ronaldo
# 1 Lionel Messi
# 2 Kylian Mbappé
# Name: name, dtype: object
print(df['age'])
# Output:
# 0 39
# 1 36
# 2 25
# Name: age, dtype: int64
Apabila ingin melakukan seleksi pada beberapa column sekaligus, kita dapat mengikuti contoh di bawah ini:
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
print(df[['name', 'age']])
# Output:
# name age
# 0 Christiano Ronaldo 39
# 1 Lionel Messi 36
# 2 Kylian Mbappé 25
Setiap row pada DataFrame
akan otomatis mendapatkan index, mulai dari index 0 sampai n-1
(n
adalah jumlah baris pada DataFrame
). Untuk mengakses data pada row tertentu, kita dapat menggunakan fungsi loc
dan index seperti pada contoh berikut:
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
print(df.loc[1])
# Output:
# name Lionel Messi
# nationality Argentina
# age 36
# Name: 1, dtype: object
Untuk mendapatkan tepat satu nilai pada DataFrame
dari posisi row dan column tertentu, kita dapat mengikuti contoh di bawah ini:
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
print(df['age'][0])
# Output:
# 39
Pandas juga memiliki fungsi untuk membaca data dari file di komputer dengan format .csv
. Hasil dari pembacaan data tersebut akan dikonversi menjadi DataFrame
oleh Pandas.
# Parameter delimiter bisa diganti dengan karakter lain seperti ';' dsb.
df = pd.read_csv('data/contoh.csv', delimiter = ',')
Selain membaca dari file .csv
di komputer, Pandas juga bisa membaca file .csv
yang diakses dari internet. Cara penggunaannya seperti kode di bawah ini:
# Parameter berupa alamat URL yang aksesnya publik
df = pd.read_csv('https://raw.githubusercontent.com/pandas-dev/pandas/main/doc/data/titanic.csv', delimiter = ',')
Modifikasi nilai pada DataFrame
Kita bisa mengubah nilai pada DataFrame
seperti halnya list
dan dictionary
. Di bawah ini adalah contoh modifikasi nilai dengan menggunakan nama column dan index row:
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
df['age'][0] = df['age'][0] - 10
print(df)
# Output:
# name nationality age
# 0 Christiano Ronaldo Portugal 29
# 1 Lionel Messi Argentina 36
# 2 Kylian Mbappé France 25
Untuk mengganti beberapa nilai sekaligus pada satu row, kita bisa menggunakan fungsi loc
seperti di bawah ini:
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
df.loc[2] = ['Harry Kane', 'England', 30]
print(df)
# Output:
# name nationality age
# 0 Christiano Ronaldo Portugal 39
# 1 Lionel Messi Argentina 36
# 2 Harry Kane England 30
List baru yang kita set ke suatu row harus memiliki panjang yang sama dengan jumlah column. Apabila berbeda, Pandas akan mengeluarkan error seperti berikut:
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
df.loc[2] = ['Harry Kane', 'England']
# Output:
# raise ValueError(
# ValueError: Must have equal len keys and value when setting with an iterable
Kita juga bisa mengubah beberapa nilai pada satu column seperti berikut:
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
df['age'] = [29, 29, 29]
print(df)
# Output:
# name nationality age
# 0 Christiano Ronaldo Portugal 29
# 1 Lionel Messi Argentina 29
# 2 Kylian Mbappé France 29
List baru yang kita set ke suatu column harus memiliki panjang yang sama dengan jumlah row. Apabila berbeda, Pandas akan mengeluarkan error seperti berikut:
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
df['age'] = [29, 29]
# Output:
# ...
# raise ValueError(
# ValueError: Length of values (2) does not match length of index (3)
Untuk menambah column baru, kita bisa membuat key baru pada variable DataFrame
, lalu set sebuah list menjadi nilai dari column tersebut. Pastikan panjang list sama dengan jumlah row pada DataFrame
.
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
df['club'] = ['Al-Nassr FC', 'Inter Miami CF', 'Paris Saint-Germain F.C.']
print(df)
# Output:
# name nationality age club
# 0 Christiano Ronaldo Portugal 39 Al-Nassr FC
# 1 Lionel Messi Argentina 36 Inter Miami CF
# 2 Kylian Mbappé France 25 Paris Saint-Germain F.C.
Untuk menambah row baru, kita bisa membuat index row baru pada variable DataFrame
, lalu set sebuah list menjadi nilai dari row tersebut. Pastikan panjang list sama dengan jumlah column pada DataFrame
.
df = pd.DataFrame({
'name': ['Christiano Ronaldo', 'Lionel Messi', 'Kylian Mbappé'],
'nationality': ['Portugal', 'Argentina', 'France'],
'age': [39, 36, 25]
})
df.loc[len(df)] = ['Harry Kane', 'England', 30]
print(df)
# Output:
# name nationality age
# 0 Christiano Ronaldo Portugal 39
# 1 Lionel Messi Argentina 36
# 2 Kylian Mbappé France 25
# 3 Harry Kane England 30
Untuk mempelajari Pandas lebih lanjut, kita membutuhkan data yang lebih banyak. Data yang akan kita gunakan adalah data penumpang kapal Titanic yang dapat diunduh di sini. Setelah di unduh, copy file titanic.csv
ke dalam folder/directory projek kamu. Buat file Python baru, lalu tulis kode berikut untuk membaca file:
import pandas as pd
df_titanic = pd.read_csv('titanic.csv', delimiter = ',')
print(df_titanic.head())
# Output:
# PassengerId Survived Pclass ... Fare Cabin Embarked
# 0 1 0 3 ... 7.2500 NaN S
# 1 2 1 1 ... 71.2833 C85 C
# 2 3 1 3 ... 7.9250 NaN S
# 3 4 1 1 ... 53.1000 C123 S
# 4 5 0 3 ... 8.0500 NaN S
#
# [5 rows x 12 columns]
print(df_titanic.columns)
# Output:
# Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',
# 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'],
# dtype='object')
Pada contoh, kita menggunakan fungsi head
untuk melihat sampel data dari DataFrame
dan property columns
untuk mendapatkan informasi column apa saja yang ada di DataFrame
.
Filtering dan sorting pada DataFrame
Karena DataFrame
memiliki bentuk tabular, filtering dan sorting dapat dilakukan dengan mudah. Untuk filtering, kita bisa sekreatif mungkin membuat filter dengan merumuskan sebuah kondisi pada DataFrame
di dalam dua kurung siku.
Sebagai contoh, kode di bawah ini akan memfilter penumpang Titanic yang berumur di bawah 17 tahun:
df_young = df_titanic[df_titanic['Age'] < 17]
print(df_young)
Hasil filtering akan mengembalikan nilai berupa DataFrame
baru. Row pada DataFrame
baru hanya row yang masuk dalam kondisi yang telah diset.
Kita juga bisa memfilter penumpang yang selamat (Survived=1
) seperti kode di bawah ini:
df_survived = df_titanic[df_titanic['Survived'] == 1]
print(df_survived)
Selain itu, kita juga bisa memfilter penumpang kelas tertentu seperti kode di bawah ini:
df_class = df_titanic[df_titanic['Pclass'].isin([1, 2])]
print(df_class)
Apabila perlu melakukan filtering untuk beberapa kondisi sekaligus, kita dapat menulis kode seperti di bawah ini:
df_survived_and_class_1 = df_titanic[(df_titanic['Survived'] == 1) & (df_titanic['Pclass'] == 1)]
print(df_survived_and_class_1)
Untuk melakukan sorting, kita dapat menggunakan fungsi sort_values
seperti contoh di bawah ini:
df_sorted_age = df_titanic.sort_values(by='Age')
print(df_sorted_age)
Seperti halnya filtering, hasil sorting akan mengembalikan nilai berupa DataFrame
baru. Row pada DataFrame
baru akan mengalami perubahan urutan sesuai dengan column yang kita set.
Secara default, nilai akan diurutkan secara menaik. Apabila kita ingin mengurutkan secara menurun, kita perlu mengeset parameter ascending=False
pada fungsi sort_values
.
df_sorted_age = df_titanic.sort_values(by='Age', ascending=False)
print(df_sorted_age)
Ringkasan statistik
Pandas memudahkan kita untuk mendapatkan statistik dari sebuah column pada DataFrame
dengan beberapa fungsi statistik dasar seperti count
, mean
, median
, std
(standar deviasi), min
, max
dan quantile
.
print(df_titanic['Age'].count()) # Output: 714
print(df_titanic['Age'].mean()) # Output: 29.69911764705882
print(df_titanic['Age'].std()) # Output: 14.526497332334044
print(df_titanic['Age'].min()) # Output: 0.42
print(df_titanic['Age'].max()) # Output: 80.0
print(df_titanic['Age'].quantile(0.25)) # Output: 20.125
print(df_titanic['Age'].median()) # Output: 28.0
print(df_titanic['Age'].quantile(0.75)) # Output: 38.0
Kita juga bisa menggunakan fungsi describe
untuk mendapatkan beberapa data statistik dari semua column dengan nilai numerik sekaligus.
stat_titanic = df_titanic.describe()
print(stat_titanic)
# Output:
# PassengerId Survived Pclass ... SibSp Parch Fare
# count 891.000000 891.000000 891.000000 ... 891.000000 891.000000 891.000000
# mean 446.000000 0.383838 2.308642 ... 0.523008 0.381594 32.204208
# std 257.353842 0.486592 0.836071 ... 1.102743 0.806057 49.693429
# min 1.000000 0.000000 1.000000 ... 0.000000 0.000000 0.000000
# 25% 223.500000 0.000000 2.000000 ... 0.000000 0.000000 7.910400
# 50% 446.000000 0.000000 3.000000 ... 0.000000 0.000000 14.454200
# 75% 668.500000 1.000000 3.000000 ... 1.000000 0.000000 31.000000
# max 891.000000 1.000000 3.000000 ... 8.000000 6.000000 512.329200
print(stat_titanic['Age'])
# Output:
# count 714.000000
# mean 29.699118
# std 14.526497
# min 0.420000
# 25% 20.125000
# 50% 28.000000
# 75% 38.000000
# max 80.000000
# Name: Age, dtype: float64
Apabila ingin melakukan kustomisasi pada statistik yang ingin ditampilkan secara sekaligus, kita dapat menggunakan fungsi agg
seperti contoh berikut:
stat_age = df_titanic.agg(average=('Age', 'mean'), standard_deviation=('Age', 'std'))
print(stat_age)
# Output:
# Age
# average 29.699118
# standard_deviation 14.526497
Dalam melakukan analisis data, seringkali kita perlu mendapatkan statistik dari data yang telah digrouping berdasarkan kategori pada column lain. Pada DataFrame
, grouping dapat dilakukan dengan menggunakan fungsi groupby
.
# Contoh penggunaan groupby + describe
stat_titanic_class = df_titanic.groupby(['Pclass']).describe()
print(stat_titanic_class)
# Output:
# PassengerId ... Fare
# count mean std ... 50% 75% max
# Pclass ...
# 1 216.0 461.597222 246.737616 ... 60.2875 93.5 512.3292
# 2 184.0 445.956522 250.852161 ... 14.2500 26.0 73.5000
# 3 491.0 439.154786 264.441453 ... 8.0500 15.5 69.5500
#
# [3 rows x 48 columns]
print(stat_titanic_class['Age'])
# Output:
# count mean std min 25% 50% 75% max
# Pclass
# 1 186.0 38.233441 14.802856 0.92 27.0 37.0 49.0 80.0
# 2 173.0 29.877630 14.001077 0.67 23.0 29.0 36.0 70.0
# 3 355.0 25.140620 12.495398 0.42 18.0 24.0 32.0 74.0
# Contoh penggunaan groupby + agg
stat_age_class = df_titanic.groupby(['Pclass']).agg(age_average=('Age', 'mean'))
print(stat_age_class)
# Output:
# age_average
# Pclass
# 1 38.233441
# 2 29.877630
# 3 25.140620
Apabila kamu perhatikan, setelah kita menggunakan fungsi agg
yang dikombinasikan dengan fungsi groupby
, struktur DataFrame
kita berubah. Nilai pada column
yang kita set pada fungsi groupby
tidak lagi dapat dipanggil seperti biasanya (df['<nama-column>']
). Hal ini karena nilai pada column
tsb. sudah hilang dan berubah menjadi nama index pada DataFrame
. Perhatikan contoh berikut:
# Contoh penggunaan groupby + agg
stat_age_class = df_titanic.groupby(['Pclass']).agg(age_average=('Age', 'mean'))
print(stat_age_class)
# Output:
# age_average
# Pclass
# 1 38.233441
# 2 29.877630
# 3 25.140620
# Kode ini akan error karena column 'Pclass' tidak ada pada dataframe
print(stat_age_class['Pclass'])
# Output:
# raise KeyError(key) from err
#
# KeyError: 'Pclass'
# Nilai pada column 'Pclass' berubah menjadi index pada dataframe
print(stat_age_class.index)
# Output:
# Index([1, 2, 3], dtype='int64', name='Pclass')
Ada satu trik yang bisa kita gunakan agar nilai column
yang kita set pada fungsi groupby
kembali menjadi bagian dari DataFrame
, yaitu dengan menggunakan fungsi reset_index
seperti contoh berikut:
stat_age_class = df_titanic.groupby(['Pclass']).agg(age_average=('Age', 'mean')).reset_index()
print(stat_age_class)
# Output:
# Pclass age_average
# 0 1 38.233441
# 1 2 29.877630
# 2 3 25.140620
print(stat_age_class['Pclass'])
# Output:
# 0 1
# 1 2
# 2 3
# Name: Pclass, dtype: int64
Modifikasi struktur DataFrame
Secara umum, struktur data tabel itu terdiri dari dua macam, yaitu format wide/melebar dan format long/memanjang. Perbedaannya, data dengan format wide menggunakan column untuk menyimpan value untuk tiap variable yang berbeda, sedangkan data dengan format long biasanya menggunakan satu column berisi variable dan satu column berisi value dari variable. Sebagai contoh, data titanic bisa dikategorikan sebagai data dengan format wide karena tiap variable dan value-nya (Survived, Pclass dsb.) dijabarkan ke dalam column yang terpisah.
import pandas as pd
titanic = pd.read_csv('https://raw.githubusercontent.com/pandas-dev/pandas/main/doc/data/titanic.csv', delimiter = ',')
print(titanic)
# Output:
# PassengerId Survived Pclass ... Fare Cabin Embarked
# 0 1 0 3 ... 7.2500 NaN S
# 1 2 1 1 ... 71.2833 C85 C
# 2 3 1 3 ... 7.9250 NaN S
# 3 4 1 1 ... 53.1000 C123 S
# 4 5 0 3 ... 8.0500 NaN S
# .. ... ... ... ... ... ... ...
# 886 887 0 2 ... 13.0000 NaN S
# 887 888 1 1 ... 30.0000 B42 S
# 888 889 0 3 ... 23.4500 NaN S
# 889 890 1 1 ... 30.0000 C148 C
# 890 891 0 3 ... 7.7500 NaN Q
#
# [891 rows x 12 columns]
Apabila kita perlu mengubah format data titanic menjadi long, kita dapat menggunakan fungsi melt
seperti contoh di bawah ini:
columns = ['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age',
'SibSp', 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked']
titanic_long = data.melt(titanic, id_vars = ['PassengerId'], value_vars = columns)
print(titanic_long)
# Output:
# PassengerId variable value
# 0 1 Survived 0
# 1 2 Survived 1
# 2 3 Survived 1
# 3 4 Survived 1
# 4 5 Survived 0
# ... ... ...
# 9796 887 Embarked S
# 9797 888 Embarked S
# 9798 889 Embarked S
# 9799 890 Embarked C
# 9800 891 Embarked Q
#
# [9801 rows x 3 columns]
Pada contoh di atas, kita mengeset parameter id_vars = ['PassengerId']
sebagai column acuan (index), dan parameter value_vars = columns
sebagai column yang ingin kita gabung. Hasilnya akan menjadi DataFrame
baru dengan 3 column: PassengerId
, variable
yang value-nya adalah nama column variable pada parameter value_vars
, dan value
yang berisi value asli dari variablenya. Apabila diperhatikan, jumlah row pada DataFrame
dengan format long lebih besar dibandingkan pada format wide.
Kita juga bisa mengkonversi DataFrame
dengan format long menjadi wide menggunakan fungsi pivot
seperti contoh berikut:
titanic_wide = titanic_long \
.pivot(index = 'PassengerId', columns = 'variable', values = 'value') \
.reset_index()
print(titanic_wide)
# Output:
# variable PassengerId Age Cabin ... SibSp Survived Ticket
# 0 1 22.0 NaN ... 1 0 A/5 21171
# 1 2 38.0 C85 ... 1 1 PC 17599
# 2 3 26.0 NaN ... 0 1 STON/O2. 3101282
# 3 4 35.0 C123 ... 1 1 113803
# 4 5 35.0 NaN ... 0 0 373450
# .. ... ... ... ... ... ... ...
# 886 887 27.0 NaN ... 0 0 211536
# 887 888 19.0 B42 ... 0 1 112053
# 888 889 NaN NaN ... 1 0 W./C. 6607
# 889 890 26.0 C148 ... 0 1 111369
# 890 891 32.0 NaN ... 0 0 370376
#
# [891 rows x 12 columns]