Ketika kita memanggil df.sum() atau mengalikan dua kolom DataFrame, sebenarnya pandas sedang memanggil mesin NumPy di balik layar. NumPy menyediakan struktur array berkecepatan tinggi yang menjadi fondasi hampir semua library data di Python, dan pandas membungkus fondasi itu dengan index serta label kolom yang nyaman digunakan. Memahami relasi keduanya membuat kita tahu kapan harus tetap di pandas dan kapan perlu turun ke array NumPy. Pada Chapter ini kita membedah kedudukan NumPy di dalam pandas, lalu berlatih pertukaran data dua arah antara DataFrame dan ndarray.
NumPy sebagai Fondasi pandas #
NumPy (Numerical Python) menyediakan ndarray, yaitu array berdimensi-N yang isinya disimpan berdampingan di memori. Karena data tersimpan rapat, operasi aritmetika NumPy berjalan vectorized: satu perintah memproses seluruh elemen dalam kode C, jauh lebih cepat daripada loop Python.
pandas tidak menemukan kembali mesin itu. Setiap kolom Series menyimpan nilainya dalam satu ndarray, dan DataFrame mengelola kumpulan blok kolom tersebut sambil menambahkan dua hal yang tidak dimiliki NumPy murni: index berlabel dan kolom bernama. Tabel berikut merangkum pembagian peran keduanya.
| Aspek | NumPy | pandas |
|---|---|---|
| Struktur | ndarray berdimensi-N | Series dan DataFrame |
| Penandaan | posisi angka saja (0, 1, 2, …) | index dan nama kolom yang bisa dinamai |
| Tipe data campuran | satu dtype untuk semua elemen | tiap kolom boleh punya dtype sendiri |
| Peran | mesin komputasi array | pengelola data tabel berlabel |
Membangun DataFrame dari ndarray #
Arah pertukaran pertama: ndarray menjadi DataFrame. Kita memberikan array dua dimensi beserta daftar index dan columns.
import numpy as np
import pandas as pd
# 1. Membangun DataFrame dari ndarray NumPy
data = np.array([
[40, 68000],
[25, 35000],
[30, 18000],
])
penjualan = pd.DataFrame(
data, index=["Beras", "Minyak", "Gula"], columns=["jumlah", "harga"]
)
print(penjualan)
print()
# 2. Kembali ke ndarray dengan to_numpy()
arr = penjualan.to_numpy()
print("tipe arr :", type(arr).__name__)
print("dtype arr :", arr.dtype)
print("writeable :", arr.flags.writeable)
print()
# 3. Fungsi NumPy pada Series mengembalikan Series
log_jumlah = np.log1p(penjualan["jumlah"])
print("np.log1p(Series) ->", type(log_jumlah).__name__)
print(log_jumlah.round(3))
print()
# 4. np.where menghasilkan ndarray murni
label = np.where(penjualan["jumlah"] >= 30, "banyak", "sedang")
print("np.where ->", type(label).__name__, label.tolist())
print()
# 5. Hasil ndarray bisa menjadi kolom baru
penjualan["total"] = penjualan["jumlah"].to_numpy() * penjualan["harga"].to_numpy()
print(penjualan)Output yang Dihasilkan:
jumlah harga
Beras 40 68000
Minyak 25 35000
Gula 30 18000
tipe arr : ndarray
dtype arr : int64
writeable : False
np.log1p(Series) -> Series
Beras 3.714
Minyak 3.258
Gula 3.434
Name: jumlah, dtype: float64
np.where -> ndarray ['banyak', 'sedang', 'banyak']
jumlah harga total
Beras 40 68000 2720000
Minyak 25 35000 875000
Gula 30 18000 540000Mari kita telaah baris-baris pentingnya:
- Baris 5-9 (
data = np.array([...])): NumPy membangun array dua dimensi bertipeint64berisi tiga baris dan dua kolom. Array ini masih “buta” terhadap makna datanya. - Baris 10-12 (
pd.DataFrame(data, index=..., columns=...)): pandas membungkus array tersebut menjadi tabel berlabel; barisnya bernamaBeras,Minyak,Guladan kolomnya bernamajumlah,harga. - Baris 17-20 (
arr = penjualan.to_numpy()): methodto_numpy()mengembalikan kembali isi tabel sebagai ndarray. Perhatikanwriteable: False— array hasil konversi bersifat read-only; kita akan membahas alasannya pada bagian berikutnya. - Baris 24-26 (
np.log1p(penjualan["jumlah"])): fungsi NumPy yang menerimaSeriesmengembalikanSerieslagi, lengkap dengan indexBeras,Minyak,Gula. pandas memastikan fungsi NumPy tidak membuang label. - Baris 30-31 (
np.where(...)): fungsinp.where()bekerja di level array sehingga hasilnya ndarray murni tanpa index, lalulabel.tolist()mengubahnya menjadi list Python. - Baris 35 (
penjualan["total"] = ...): hasil perkalian dua ndarray menjadi kolom baru; pertukaran array-ke-pandas berlangsung dalam satu baris.
Fungsi NumPy yang Sadar-DataFrame #
Pola pada baris 24 dan 30 menunjukkan dua perilaku berbeda yang perlu kita pegang. Fungsi NumPy yang diteruskan pandas — seperti np.log1p, np.sqrt, dan np.abs — menghormati struktur pandas: masukan Series menghasilkan Series, dan masukan DataFrame menghasilkan DataFrame. Nama index dan kolom ikut terbawa, sehingga hasilnya bisa langsung dipakai kembali dalam alur kerja tabel.
Sebaliknya, fungsi yang bekerja di level array seperti np.where() atau np.asarray() mengembalikan ndarray tanpa label. Hasil tersebut cocok untuk dikonsumsi kode NumPy lain, tetapi tidak lagi bisa memanfaatkan fitur seleksi berlabel pandas.
Kapan Turun ke Array NumPy #
Kita tetap di pandas selama pekerjaannya berkaitan dengan tabel: seleksi berlabel, penggabungan, agregasi, dan pembersihan data. Kita turun ke ndarray ketika kebutuhannya milik NumPy: operasi aljabar linear lewat arr @ vektor, fungsi ilmiah yang hanya ada di NumPy, atau antarmuka ke library yang menuntut array murni sebagai input. Baris 35 pada contoh di atas memperlihatkan jalan tengahnya — hitung di level array, simpan kembali sebagai kolom DataFrame.
Setelah fondasi ini jelas, babak berikutnya menambahkan lapisan visual: pandas menyediakan method .plot() yang mendelegasikan seluruh penggambarannya ke Matplotlib, dan itulah topik Chapter berikutnya.
Referensi resmi yang relevan untuk chapter ini: dokumentasi NumPy , pandas.DataFrame.to_numpy , dan catatan rilis pandas 3.0.0 yang menjelaskan perubahan Copy-on-Write.