Model Mental: Array Berlabel

Series sebagai kolom berlabel dan DataFrame sebagai tabel, dibangun di atas array NumPy.

Daftar isi

Mental model yang tepat membuat perilaku kode pandas dapat diprediksi sebelum kode itu dijalankan. Topik ini menetapkan model tersebut, yaitu Series sebagai kolom berlabel dan DataFrame sebagai kumpulan kolom yang berbagi index. Penjelasan diawali dari pembuatan Series berlabel, dilanjutkan penyelarasan label pada operasi antar-Series, dan ditutup dengan diagram yang merangkum hubungan array NumPy, label, dan Series. Setelah topik ini selesai, munculnya NaN pada hasil operasi dapat dijelaskan tanpa menebak.

Series: nilai beserta labelnya#

Series adalah array satu dimensi yang setiap nilainya dipasangkan dengan satu label melalui index. Dibanding array NumPy, Series menambahkan dua hal, yaitu deretan label dan nama. Deretan label memungkinkan satu nilai dicari melalui nama ruangannya, sedangkan nama Series berperan seperti nama kolom ketika Series nanti dimasukkan ke dalam tabel.

python Contoh: Series pembacaan suhu
import pandas as pd

suhu = pd.Series([22.5, 23.1, 24.0], index=["Lab A", "Lab B", "Ruang Arsip"], name="suhu_c")
print(suhu)
print(suhu["Lab B"])
text Keluaran
Lab A          22.5
Lab B          23.1
Ruang Arsip    24.0
Name: suhu_c, dtype: float64
23.1

Keluaran menampilkan kolom label di kiri, kolom nilai di kanan, lalu nama dan dtype di bagian akhir. Akses suhu["Lab B"] mencari nilai melalui label, sehingga perubahan urutan data tidak merusak kode yang merujuk label. Index juga menempel pada Series, artinya label ikut berpindah ketika Series disalin, disaring, atau diurutkan. Sifat inilah yang membedakan Series dari array NumPy yang hanya dikenali melalui posisinya.

Operasi menyelaraskan label#

Operasi antar-Series menyelaraskan pasangan nilai berdasarkan label indexnya dan bukan berdasarkan posisinya. Mekanisme ini disebut penyelarasan (alignment). Kedua Series diperiksa labelnya satu per satu, lalu pasangan nilai dengan label yang sama dijumlahkan. Label yang hanya dimiliki salah satu Series tidak menemukan pasangannya, sehingga hasilnya ditandai NaN sebagai penanda nilai hilang (missing value).

python Contoh: penjumlahan dua Series dengan label berbeda
import pandas as pd

pagi = pd.Series([22.5, 23.1], index=["Lab A", "Lab B"])
siang = pd.Series([24.0, 24.8, 25.1], index=["Lab A", "Lab B", "Ruang Arsip"])
hasil = pagi + siang
print(hasil)
text Keluaran
Lab A          46.5
Lab B          47.9
Ruang Arsip     NaN
dtype: float64

Ruang Arsip hanya tercatat pada pembacaan siang, sehingga penjumlahannya tidak menemukan pasangan dan menghasilkan NaN. Perilaku ini berbeda dengan penjumlahan array NumPy yang mencocokkan posisi, yaitu elemen ke-0 dengan elemen ke-0. Pada penyelarasan label, urutan data boleh berbeda dan hasilnya tetap benar.

python Contoh: label sama dengan urutan berbeda
import pandas as pd

a = pd.Series([1.0, 2.0], index=["Lab A", "Lab B"])
b = pd.Series([10.0, 20.0], index=["Lab B", "Lab A"])
print(a + b)
text Keluaran
Lab A    21.0
Lab B    12.0
dtype: float64

Kedua Series di atas memuat label yang sama dalam urutan terbalik. Penjumlahannya tetap menghitung 1.0 + 20.0 untuk Lab A dan 2.0 + 10.0 untuk Lab B karena pencocokan dilakukan melalui label. Baris dtype pada keluaran tetap tampil, sedangkan baris Name hilang karena kedua Series yang dijumlahkan tidak membawa nama.

DataFrame: kolom berbagi index#

DataFrame menyusun beberapa kolom nilai di atas satu index yang sama, dan setiap kolomnya tetap berperilaku sebagai Series. Struktur ini membuat tabel dan kolomnya memiliki bahasa yang sama, sehingga mekanisme label yang sudah dijelaskan berlaku pada kedua tingkat tersebut.

python Contoh: kolom DataFrame sebagai Series
import pandas as pd

df = pd.DataFrame({
    "suhu_c": [22.5, 23.1, 24.0],
    "lembap_pct": [55.0, 61.2, 48.9],
}, index=["Lab A", "Lab B", "Ruang Arsip"])
print(df)
s = df["suhu_c"]
print(s)
print(s.index)
print(df.index)
print(df.columns)
text Keluaran
             suhu_c  lembap_pct
Lab A          22.5        55.0
Lab B          23.1        61.2
Ruang Arsip    24.0        48.9
Lab A          22.5
Lab B          23.1
Ruang Arsip    24.0
Name: suhu_c, dtype: float64
Index(['Lab A', 'Lab B', 'Ruang Arsip'], dtype='str')
Index(['Lab A', 'Lab B', 'Ruang Arsip'], dtype='str')
Index(['suhu_c', 'lembap_pct'], dtype='str')

Seleksi df["suhu_c"] mengembalikan Series dengan nama, nilai, dan index yang persis sama dengan kolom asalnya. Karena seluruh kolom berbagi index yang sama, penyelarasan label yang bekerja pada operasi antar-Series berlaku juga di dalam satu DataFrame, misalnya ketika dua kolom dijumlahkan. Kerangka tabel dengan demikian tersusun atas dua deretan label, yaitu index untuk baris dan nama untuk kolom. Keduanya diperiksa melalui df.index dan df.columns, dan keduanya dikelola dengan mekanisme label yang sama.

Diagram array berlabel#

Diagram berikut merangkum mental model array berlabel yang digunakan sepanjang jalur ini. Sisi kiri menampilkan array NumPy yang hanya menyimpan tiga nilai. Satu-satunya identitas pada array itu adalah posisi, sehingga nilai 22.5 hanya dapat dirujuk sebagai elemen pertama. Sisi kanan menampilkan Series yang terdiri atas dua bagian, yaitu deretan label index dan deretan nilai. Pasangan keduanya membentuk satu kolom berlabel, dan DataFrame kemudian menumpuk beberapa Series berlabel yang berbagi deretan index yang sama.

Array NumPy22.523.124.0hanya nilai, diakses lewat posisi+ indexSeriesindexnilai"Lab A""Lab B""Ruang Arsip"22.523.124.0nilai beserta labelnya
Array NumPy menyimpan nilai saja, sedangkan Series menambahkan deretan label index

Model ini menjadi dasar bagi seleksi dengan loc pada modul Seleksi, agregasi per ruangan pada modul GroupBy, dan penggabungan tabel pada modul Penggabungan Data. Seleksi berjalan melalui label, sehingga df.loc merujuk nama baris dan bukan posisinya. Penyelarasan berjalan melalui label, sehingga operasi antarkolom tidak terganggu oleh perbedaan urutan. Selama model array berlabel ini dipegang, perilaku tersebut dapat diprediksi langsung dari bentuk datanya.

Kesalahan umum#

Dua kesalahan yang paling sering terjadi pada tahap ini adalah menganggap operasi Series berbasis posisi dan mengubah hasil seleksi sambil berharap tabel aslinya ikut berubah. Keduanya tidak menampilkan pesan error, sehingga hasilnya baru disadari ketika analisis sudah berlanjut.

Kesalahan yang pertama muncul ketika penjumlahan dua Series menghasilkan NaN padahal kedua Series terlihat berisi data. Penyebabnya adalah label yang tidak cocok, misalnya "Lab A" pada satu Series tertulis "Lab A " dengan spasi tambahan, sehingga pencocokan gagal tanpa terlihat. Perbaikannya dilakukan dengan menampilkan kedua index melalui print terlebih dahulu, lalu menyetarakan penulisan labelnya sebelum operasi dijalankan.

Kesalahan yang kedua terjadi pada pengubahan nilai melalui hasil seleksi. Pada pandas 3, mekanisme Copy-on-Write selalu aktif, sehingga hasil seleksi merupakan salinan dan pengubahannya tidak menjalar ke DataFrame asal.

python Contoh: pengubahan melalui hasil seleksi tidak sampai
import pandas as pd

df = pd.DataFrame({"suhu_c": [22.5, 23.1]})
s = df["suhu_c"]
s[0] = 99.0
print(df)
text Keluaran
   suhu_c
0    22.5
1    23.1

Nilai pada df tetap 22.5 meskipun s sudah diisi 99.0. Pengubahan dilakukan melalui DataFrame-nya langsung, yaitu melalui df.loc untuk satu sel atau melalui df["kolom"] = ... untuk satu kolom penuh.

python Contoh: pengubahan melalui loc
import pandas as pd

df = pd.DataFrame({"suhu_c": [22.5, 23.1]})
df.loc[0, "suhu_c"] = 99.0
print(df)
text Keluaran
   suhu_c
0    99.0
1    23.1

Pola df.loc[...] = ... dan df["kolom"] = ... menjadi bentuk pengubahan yang digunakan sepanjang jalur ini. Bentuk tersebut membuat sasaran setiap pengubahan tertulis secara eksplisit, sehingga akibatnya mudah dilacak pada saat kode ditinjau kembali.

Ringkasan#

  • Series memasangkan nilai array satu dimensi dengan deretan label index, sehingga nilai dicari melalui label dan bukan melalui posisi.
  • Operasi antar-Series menyelaraskan nilai berdasarkan label, dan label tanpa pasangan menghasilkan NaN.
  • DataFrame menumpuk beberapa kolom Series di atas satu index yang sama, yang diperiksa melalui df.index dan df.columns.
  • Copy-on-Write membuat hasil seleksi menjadi salinan, sehingga pengubahan nilai dilakukan melalui df.loc atau df["kolom"] = ....

Referensi#