Sintaks Python Umum dalam Ilmu Data (Dasar)
Beberapa hari ini saya sedang membaca buku Data Science from Scratch (link PDF), sebuah buku pengantar ilmu data yang bagus dan mudah dipahami. Salah satu babnya membahas sintaks dasar Python dan sintaks tingkat lanjut yang sering dipakai dalam ilmu data. Karena penjelasannya sangat bagus, ringkas, dan jelas, saya memutuskan untuk menerjemahkannya di sini sebagai pengingat.
Sintaks Python Umum dalam Ilmu Data (Dasar)
Sintaks Python Umum dalam Ilmu Data (Lanjutan)
Bab ini berfokus pada pengenalan sintaks dan fitur dasar Python yang sangat berguna dalam pemrosesan data (berdasarkan Python 2.7).
Format Spasi
Banyak bahasa menggunakan kurung kurawal untuk mengontrol blok kode, tetapi Python menggunakan indentasi:
for i in [1, 2, 3, 4, 5]:
print i # Baris pertama dari perulangan "for i"
for j in [1, 2, 3, 4, 5]:
print j # Baris pertama dari perulangan "for j"
print i + j # Baris terakhir dari perulangan "for j"
print i # Baris terakhir dari perulangan "for i"
print "done looping"
Ini membuat kode Python sangat mudah dibaca, tetapi juga berarti Anda harus selalu memperhatikan format. Spasi dalam kurung akan diabaikan, ini berguna saat menulis ekspresi panjang:
long_winded_computation = (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20)
Juga membuat kode lebih mudah dibaca:
list_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
easier_to_read_list_of_lists = [ [1, 2, 3],
[4 ,5 ,6 ],
[7 ,8 ,9 ] ]
Pernyataan Multi-Baris
Anda bisa menggunakan garis miring terbalik (backslash) untuk menyambung dua baris yang terputus (praktik ini jarang digunakan):
two_plus_three = 2 + \
3
Modul
Baik modul bawaan Python maupun modul pihak ketiga yang Anda unduh, semuanya perlu diimpor secara manual sebelum bisa digunakan.
- Cukup mengimpor seluruh modul secara langsung:
import re
my_regex = re.compile("[0-9]+", re.I)
Modul re yang diimpor di sini digunakan untuk ekspresi reguler. Setelah modul diimpor, Anda dapat langsung memanggil fungsinya dengan menggunakan nama modul sebagai prefiks (misalnya, re.).
- Jika nama modul yang diimpor sudah digunakan dalam kode, Anda bisa memetakannya ke nama lain saat mengimpornya:
import re as regex
my_regex = regex.compile("[0-9]+", regex.I)
- Jika Anda (secara iseng) ingin, Anda bisa mengimpor seluruh modul ke dalam namespace saat ini, yang mungkin secara tidak sengaja menimpa variabel yang sudah Anda definisikan:
match = 10
from re import * # Modul re memiliki fungsi match
print match # Mencetak fungsi match
Karena Anda adalah orang baik, saya yakin Anda tidak akan melakukan ini.
Operasi Aritmatika
Python 2.7 secara default menggunakan pembagian integer (pembagian bulat), jadi $ 5 / 2 = 2 $. Namun, seringkali kita tidak menginginkan pembagian bulat, jadi kita bisa mengimpor modul ini:
from __future__ import division
Setelah diimpor, hasilnya akan $5 / 2 = 2.5$.
Pembagian bulat: $5 // 2 = 2$.
Fungsi
Definisi Fungsi
Fungsi adalah aturan yang dapat menerima nol atau lebih input dan mengembalikan output tertentu. Di Python, kita mendefinisikan fungsi menggunakan def nama_fungsi(parameter):
def double(x):
"""Anda bisa menulis penjelasan tentang fungsi di sini.
Contohnya, fungsi ini akan mengalikan input dengan 2"""
# Anda bisa menulis badan fungsi di sini, jangan lupa indentasi
return x * 2
Penggunaan Fungsi
Di Python, fungsi adalah objek kelas satu (first-class object), yang berarti kita dapat menetapkan fungsi ke sebuah variabel, atau melewatkannya sebagai argumen ke fungsi lain:
def apply_to_one(f):
"""Memanggil fungsi f dan melewatkan 1 sebagai parameter fungsi"""
return f(1)
my_double = double # double mengacu pada fungsi yang didefinisikan di bagian sebelumnya
x = apply_to_one(my_double) # x sama dengan 2
Fungsi Anonim
Anda juga bisa membuat fungsi anonim melalui lambda:
y = apply_to_one(lambda x: x + 4) # Sama dengan 5
Anda bisa menetapkan lambda ke variabel lain, tetapi kebanyakan orang akan menyarankan Anda untuk tetap menggunakan def:
another_double = lambda x: 2 * x # Tidak disarankan
def another_double(x): return 2 * x # Praktik yang disarankan
Tambahan:
lambdahanyalah sebuah ekspresi, badan fungsinya jauh lebih sederhana daripadadef.- Badan
lambdaadalah sebuah ekspresi, bukan blok kode. Anda hanya bisa membungkus logika terbatas ke dalam ekspresilambda.
Melewatkan Parameter Fungsi
Parameter fungsi dapat didefinisikan dengan nilai default. Jika ekspresi fungsi dipanggil tanpa parameter, nilai default akan digunakan; jika parameter disertakan, nilai yang ditentukan akan dilewatkan:
def my_print(message="my default message"):
print message
my_print("hello") # Mencetak "hello"
my_print() # Mencetak "my default message"
Terkadang, sangat berguna juga untuk menentukan parameter langsung melalui namanya:
def subtract(a=0, b=0):
return a - b
subtract(10, 5) # Mengembalikan 5
subtract(0, 5) # Mengembalikan -5
subtract(b=5) # Sama seperti sebelumnya, mengembalikan -5
String
Anda bisa menggunakan tanda kutip tunggal atau ganda untuk membuat string (pastikan tanda kutip berpasangan):
single_quoted_string = 'data science'
double_quoted_string = "data science"
Gunakan garis miring terbalik (backslash) untuk karakter escape, contohnya:
tab_string = "\t" # Representasi tab
len(tab_string) # Sama dengan 1
Ketika Anda ingin menggunakan garis miring terbalik itu sendiri (misalnya untuk direktori Windows atau ekspresi reguler), Anda bisa mendefinisikannya dengan string mentah r"":
not_tab_string = r"\t" # Merepresentasikan karakter '\' dan 't'
len(not_tab_string) # Sama dengan 2
Buat string multibarisan menggunakan tiga tanda kutip ganda:
multi_line_string = """Ini adalah baris pertama
Ini adalah baris kedua
Ini adalah baris ketiga"""
Penanganan Pengecualian (Exception Handling)
Ketika program mengalami kesalahan, Python akan mengeluarkan sebuah exception (pengecualian). Jika kita tidak menanganinya, program akan berhenti dieksekusi. Untuk menangkap pengecualian, kita bisa menggunakan pernyataan try dan except:
try:
print 0 / 0
except ZeroDivisionError:
print "Tidak bisa dibagi nol"
Meskipun dalam bahasa lain pengecualian dianggap sebagai hal yang buruk, di Python, penanganan pengecualian yang lebih banyak akan membuat kode Anda lebih ringkas dan bersih.
Daftar (List)
Membuat Daftar
Daftar adalah koleksi terurut yang sederhana, dan juga merupakan struktur data paling dasar di Python (mirip dengan array di bahasa lain, tetapi daftar memiliki beberapa fitur tambahan). Membuat daftar:
integer_list = [1, 2, 3]
heterogeneous_list = ["string", 0.1, True]
list_of_lists = [ integer_list, heterogeneous_list, [] ]
list_length = len(integer_list) # Sama dengan 3
list_sum = sum(integer_list) # Sama dengan 6
Mengakses Nilai dalam Daftar
Anda bisa mengindeks nilai dalam daftar menggunakan kurung siku:
x = range(10) # Mendapatkan daftar x = [0, 1, ..., 9]
zero = x[0] # Sama dengan 0, indeks daftar dimulai dari 0
one = x[1] # Sama dengan 1
nine = x[-1] # Sama dengan 9, elemen terakhir dalam daftar
eight = x[-2] # Sama dengan 8, elemen kedua terakhir dalam daftar
x[0] = -1 # Daftar x saat ini = [-1, 1, 2, 3, ..., 9]
Memotong Daftar (Slicing)
Anda bisa memotong daftar menggunakan kurung siku:
first_three = x[:3] # [-1, 1, 2]
three_to_end = x[3:] # [3, 4, ..., 9]
one_to_four = x[1:5] # [1, 2, 3, 4]
last_three = x[-3:] # [7, 8, 9]
without_first_and_last = x[1:-1] # [1, 2, ..., 8]
copy_of_x = x[:] # [-1, 1, 2, ..., 9]
Anda bisa menggunakan in untuk memeriksa apakah sebuah elemen ada dalam daftar:
1 in [1, 2, 3] # True
0 in [1, 2, 3] # False
Metode pencarian elemen ini sangat tidak efisien. Gunakan hanya jika daftar sangat kecil atau Anda tidak terlalu peduli dengan waktu pencarian.
Menggabungkan Daftar
Di Python, sangat mudah untuk menggabungkan dua daftar:
x = [1, 2, 3]
x.extend([4, 5, 6]) # x saat ini = [1,2,3,4,5,6]
Jika Anda tidak ingin mengubah daftar x yang asli, Anda bisa menggunakan operator “penjumlahan” untuk membuat daftar baru:
x = [1, 2, 3]
y = x + [4, 5, 6] # y saat ini = [1, 2, 3, 4, 5, 6]; x tidak berubah
Seringkali, kita menambahkan satu elemen ke daftar dengan cara ini:
x = [1, 2, 3]
x.append(0) # x saat ini = [1, 2, 3, 0]
y = x[-1] # Sama dengan 0
z = len(x) # Sama dengan 4
Memecah Daftar (Unpacking)
Jika Anda tahu berapa banyak elemen dalam daftar, sangat mudah untuk membongkar daftar ini:
x, y = [1, 2] # x saat ini = 1, y = 2
Jika jumlah elemen di kedua sisi persamaan tidak cocok, Anda akan mendapatkan ValueError. Oleh karena itu, kita lebih sering menggunakan garis bawah untuk menampung sisa bagian dari daftar:
_, y = [1, 2] # y saat ini == 2, elemen pertama diabaikan
Tuple
Daftar dan tuple sangat mirip. Satu-satunya perbedaan dengan daftar adalah elemen dalam tuple tidak dapat dimodifikasi.
Membuat Tuple
Anda bisa menggunakan kurung biasa atau tanpa kurung sama sekali untuk membuat tuple:
my_tuple = (1, 2)
other_tuple = 3, 4
my_list[1] = 3 # my_list saat ini adalah [1, 3]
try:
my_tuple[1] = 3
except TypeError:
print "Tidak bisa mengubah tuple"
Menggunakan tuple sangat nyaman untuk mendapatkan beberapa nilai kembalian dari sebuah fungsi:
def sum_and_product(x, y):
return (x + y),(x * y)
sp = sum_and_product(2, 3) # Sama dengan (5, 6)
s, p = sum_and_product(5, 10) # s = 15, p = 50
Tuple (dan daftar) mendukung penugasan nilai ke beberapa elemen secara bersamaan:
x, y = 1, 2 # x saat ini = 1, y = 2
x, y = y, x # Menukar nilai dua variabel di Python; x saat ini = 2, y = 1
Kamus (Dictionary)
Membuat Kamus
Struktur data dasar lain di Python adalah kamus (dictionary), yang memungkinkan Anda mendapatkan nilai (value) yang sesuai dengan cepat melalui kunci (key):
empty_dict = {} # Definisi kamus kosong yang sangat 'Pythonic'
empty_dict2 = dict() # Definisi kamus kosong yang kurang 'Pythonic'
grades = { "Joel" : 80, "Tim" : 95 } # Penyimpanan kamus
Mencari Elemen Kamus
Anda bisa menggunakan kurung siku bersama kunci untuk mencari nilai yang sesuai:
joels_grade = grades["Joel"] # Sama dengan 80
Jika kunci yang dicari tidak ada dalam kamus, akan mengembalikan KeyError:
try:
kates_grade = grades["Kate"]
except KeyError:
print "Tidak ada nilai untuk Kate!"
Anda bisa menggunakan in untuk memeriksa apakah sebuah kunci ada dalam kamus:
joel_has_grade = "Joel" in grades # True
kate_has_grade = "Kate" in grades # False
Kamus memiliki metode yang dapat mengembalikan nilai default. Jika kunci yang dicari tidak ada dalam kamus, ia akan mengembalikan nilai default yang telah ditetapkan (bukan menyebabkan pengecualian):
joels_grade = grades.get("Joel", 0) # Sama dengan 80
kates_grade = grades.get("Kate", 0) # Sama dengan 0
no_ones_grade = grades.get("No One") # Mengembalikan nilai default None
Mengubah Kamus
Anda bisa menggunakan kurung siku untuk membuat dan memodifikasi pasangan kunci-nilai dalam kamus:
grades["Tim"] = 99 # Mengganti nilai lama
grades["Kate"] = 100 # Menambah pasangan kunci-nilai baru
num_students = len(grades) # Sama dengan 3
Kita akan sering menggunakan kamus seperti ini untuk merepresentasikan struktur data:
tweet = {
"user" : "joelgrus",
"text" : "Data Science is Awesome",
"retweet_count" : 100,
"hashtags" : ["#data", "#science", "#datascience", "#awesome", "#yolo"]
}
Selain mencari kunci tertentu, kita juga bisa memanipulasi semua kunci seperti ini:
tweet_keys = tweet.keys() # Mendapatkan daftar kunci
tweet_values = tweet.values() # Mendapatkan daftar nilai
tweet_items = tweet.items() # Mendapatkan tuple (kunci, nilai)
"user" in tweet_keys # Mengembalikan True, menggunakan pencarian `in` daftar yang kurang efisien
"user" in tweet # Cara yang lebih 'Pythonic', menggunakan pencarian `in` kamus yang efisien
"joelgrus" in tweet_values # True
Kunci dalam kamus adalah unik, dan daftar tidak dapat digunakan sebagai kunci kamus. Jika Anda memerlukan kunci multi-bagian, Anda bisa menggunakan tuple, atau mengubah kunci menjadi string melalui beberapa cara.
Kamus Bawaan (Defaultdict)
Jika Anda mencoba menghitung frekuensi setiap kata dalam sebuah dokumen, cara yang jelas adalah membuat kamus di mana kata-kata berfungsi sebagai kunci dan frekuensinya sebagai nilai yang sesuai. Kemudian, iterasi dokumen tersebut. Jika bertemu kata yang sudah ada, tambahkan 1 ke nilai kunci yang sesuai di kamus; jika bertemu kata yang belum ada, tambahkan pasangan kunci-nilai baru ke kamus:
word_counts = {}
for word in document:
if word in word_counts:
word_counts[word] += 1
else:
word_counts[word] = 1
Tentu saja, Anda juga bisa menangani kunci yang hilang sebelumnya dengan pendekatan “mencoba dulu, baru tangani jika gagal” seperti ini:
word_counts = {}
for word in document:
try:
word_counts[word] += 1
except KeyError:
word_counts[word] = 1
Metode ketiga adalah menggunakan get, metode ini sangat baik dalam menangani kunci yang hilang:
word_counts = {}
for word in document:
previous_count = word_counts.get(word, 0)
word_counts[word] = previous_count + 1
Kamus bawaan (defaultdict) sama dengan kamus biasa, satu-satunya perbedaan adalah ketika Anda mencoba mencari kunci yang tidak ada dalam kamus, defaultdict akan secara otomatis membuat pasangan kunci-nilai menggunakan kunci yang Anda berikan. Untuk menggunakan defaultdict, Anda perlu mengimpor pustaka collections:
from collections import defaultdict
word_counts = defaultdict(int) # int() menghasilkan 0
for word in document:
word_counts[word] += 1
Defaultdict juga sangat berguna dalam daftar, kamus biasa, bahkan fungsi kustom:
dd_list = defaultdict(list) # list() menghasilkan daftar kosong
dd_list[2].append(1) # dd_list saat ini adalah {2: [1]}
dd_dict = defaultdict(dict) # dict() menghasilkan kamus kosong
dd_dict["Joel"]["City"] = "Seattle" # Konten dd_dict saat ini adalah { "Joel" : { "City" : "Seattle"}}
dd_pair = defaultdict(lambda: [0, 0]) # Membuat kamus di mana nilai untuk kunci adalah daftar
dd_pair[2][1] = 1 # Konten dd_pair saat ini adalah {2: [0,1]}
Metode ini sangat berguna, di masa mendatang ketika kita ingin mendapatkan hasil nilai dari kunci tertentu dalam kamus, kita tidak perlu lagi memeriksa apakah kuncinya ada atau tidak.
Penghitung (Counter)
Counter dapat langsung mengubah sekumpulan nilai menjadi objek mirip kamus, di mana kuncinya adalah salah satu elemen dalam kumpulan tersebut, dan nilai yang sesuai adalah jumlah kemunculan elemen tersebut. Ini sering digunakan saat membuat histogram:
from collections import Counter
c = Counter([0, 1, 2, 0]) # c (kurang lebih) adalah { 0 : 2, 1 : 1, 2 : 1 }
Dengan demikian, kita memiliki cara yang sangat nyaman untuk menghitung frekuensi kata:
word_counts = Counter(document)
Counter juga memiliki metode most_common yang sangat sering digunakan, yang dapat langsung mendapatkan beberapa kata paling sering muncul beserta frekuensinya:
# Mencetak 10 kata paling sering muncul beserta jumlahnya
for word, count in word_counts.most_common(10):
print word, count
Set
Struktur data lain di Python adalah set (himpunan). Set adalah kumpulan elemen-elemen unik.
Anda bisa membuat set dan menambahkan elemen ke dalamnya seperti ini:
s = set()
s.add(1) # s adalah { 1 }
s.add(2) # s adalah { 1, 2 }
s.add(2) # s adalah { 1, 2 }
x = len(s) # Sama dengan 2
y = 2 in s # Sama dengan True
z = 3 in s # Sama dengan False
Dua alasan utama menggunakan set:
Pertama, operasi in dalam set sangat efisien. Ketika jumlah elemen dalam sebuah dataset sangat besar, mencari elemen dalam bentuk set jelas lebih cocok daripada dalam bentuk daftar:
stopwords_list = ["a","an","at"] + hundreds_of_other_words + ["yet", "you"]
"zip" in stopwords_list # Gagal, perlu memeriksa setiap elemen
stopwords_set = set(stopwords_list)
"zip" in stopwords_set # Pencarian berhasil dan sangat cepat
Kedua, menggunakan set sangat nyaman untuk mendapatkan elemen-elemen unik dari sekumpulan data:
item_list = [1, 2, 3, 1, 2, 3]
num_items = len(item_list) # 6
item_set = set(item_list) # {1, 2, 3}
num_distinct_items = len(item_set) # 3
distinct_item_list = list(item_set) # [1, 2, 3]
Namun, pada kenyataannya, frekuensi penggunaan set tidak setinggi kamus dan daftar.
Pernyataan Kondisional
Dalam sebagian besar bahasa pemrograman, Anda bisa menggunakan if untuk menyatakan percabangan kondisional seperti ini:
if 1 > 2:
message = "andai saja 1 lebih besar dari dua…"
elif 1 > 3:
message = "elif adalah singkatan dari 'else if'"
else:
message = "jika semua gagal, gunakan else (jika Anda mau)"
Anda juga bisa menulis pernyataan percabangan kondisional dalam satu baris seperti ini, tetapi ini jarang digunakan:
parity = "even" if x % 2 == 0 else "odd"
Pernyataan Perulangan (Loop)
Perulangan while
Perulangan while di Python:
x = 0
while x < 10:
print x, "kurang dari 10"
x += 1
Perulangan for
Yang lebih sering digunakan adalah perulangan for-in:
for x in range(10):
print x, "kurang dari 10"
Ekspresi logika yang lebih kompleks dapat menggunakan pernyataan continue dan break:
for x in range(10):
if x == 3:
continue # Langsung masuk ke iterasi berikutnya
if x == 5:
break # Keluar sepenuhnya dari perulangan
print x
Hasilnya akan mencetak 0, 1, 2, dan 4.
Kebenaran (Truthiness)
Variabel Boolean di Python digunakan mirip dengan bahasa lain, satu-satunya perbedaan adalah huruf awalnya harus kapital:
one_is_less_than_two = 1 < 2 # Adalah True
true_equals_false = True == False # Adalah False
Python menggunakan None untuk menunjukkan bahwa suatu nilai tidak ada, mirip dengan null di bahasa lain:
x = None
print x == None # Mencetak True, kurang elegan
print x is None # Mencetak True, lebih elegan
Python memungkinkan Anda menggunakan nilai lain sebagai pengganti nilai boolean. Berikut ini semuanya setara dengan False:
- False
- None
- [] (daftar kosong)
- {} (kamus kosong)
- ""
- set()
- 0
- 0.0
Demikian pula, ada banyak nilai yang setara dengan True. Ini sangat memudahkan Anda untuk memeriksa daftar kosong, string kosong, kamus kosong, dan lain-lain.
Tentu saja, jika Anda tidak bisa memprediksi hasilnya, mungkin akan terjadi kesalahan selama penggunaan:
s = some_function_that_returns_a_string()
if s:
first_char = s[0]
else:
first_char = ""
Cara yang lebih sederhana, dengan efek yang sama seperti di atas:
first_char = s and s[0]
Jika nilai pertama adalah True, nilai kedua akan dikembalikan; jika tidak, nilai pertama akan dikembalikan.
Serupa, jika x mungkin berupa angka atau kosong, maka cara ini bisa mendapatkan x yang pasti berupa angka:
safe_x = x or 0
Python juga memiliki fungsi all, yang mengembalikan True jika setiap elemen adalah True. Fungsi any mengembalikan True jika setidaknya ada satu elemen yang True. Misalnya, untuk sebuah daftar di mana setiap elemen adalah “benar”, fungsi all akan mengembalikan True, jika tidak akan mengembalikan False:
all([True, 1, { 3 }]) # True
all([True, 1, {}]) # False, {} setara dengan 'False'
any([True, 1, {}]) # True
all([]) # True, tidak ada elemen yang setara dengan 'False'
any([]) # False, tidak ada elemen yang setara dengan 'True'
Bacaan Lanjutan:
Sintaks Python Umum dalam Ilmu Data (Lanjutan)