Data mentah hampir selalu mengandung koreksi kecil: harga produk perlu disesuaikan setelah kenaikan harga, jumlah terjual salah ketik, atau stok perlu dinaikkan sampai batas minimum. Menulis loop Python yang membandingkan baris satu per satu bukan cara kerja pandas. Akses .loc dan .at mengubah nilai sel secara langsung pada DataFrame asli dengan satu baris kode. Pada Chapter ini kita mengubah satu sel, beberapa sel sekaligus, dan seluruh sel yang memenuhi kondisi tertentu.

Mengubah Satu Sel dengan .loc #

Mari kita koreksi harga Gula Aren dari 15000 menjadi 16000. Label index produk tersebut adalah P003, sehingga penulisannya menjadi penjualan.loc["P003", "harga"] = 16000: label baris terlebih dahulu, nama kolom berikutnya. Skrip berikut mempraktikkan koreksi itu beserta dua variasi lainnya.

python
import pandas as pd

penjualan = pd.DataFrame(
    {
        "produk": ["Kopi Gayo", "Teh Melati", "Gula Aren", "Roti Bakar", "Pisang Goreng"],
        "kasir": ["Budi", "Siti", "Dewi", "Budi", "Dewi"],
        "cabang": ["Bandung", "Jakarta", "Bandung", "Surabaya", "Jakarta"],
        "harga": [18000, 12000, 15000, 20000, 10000],
        "jumlah": [35, 40, 25, 20, 50],
        "stok": [12, 8, 30, 15, 22],
    },
    index=["P001", "P002", "P003", "P004", "P005"],
)

penjualan.loc["P003", "harga"] = 16000
print(penjualan.loc["P003", ["produk", "harga"]])
print()

penjualan.loc[["P001", "P002"], "jumlah"] = [40, 45]
penjualan.at["P005", "stok"] = 18
print(penjualan.loc[["P001", "P002", "P005"], ["produk", "jumlah", "stok"]])
print()

penjualan.loc[penjualan["stok"] < 15, "stok"] = 15
print(penjualan[["produk", "stok"]])

Output yang Dihasilkan:

text
produk    Gula Aren
harga         16000
Name: P003, dtype: object

             produk  jumlah  stok
P001      Kopi Gayo      40    12
P002     Teh Melati      45     8
P005  Pisang Goreng      50    18

             produk  stok
P001      Kopi Gayo    15
P002     Teh Melati    15
P003      Gula Aren    30
P004     Roti Bakar    15
P005  Pisang Goreng    18

Mari kita telaah peran setiap baris kode di atas:

  1. Baris 15 (penjualan.loc["P003", "harga"] = 16000): .loc menerima pasangan [label_baris, kolom]; penugasan mengubah satu sel pada penjualan secara langsung.
  2. Baris 16 (print(penjualan.loc["P003", ["produk", "harga"]])): kita membaca kembali baris P003 untuk membuktikan harga sudah menjadi 16000.
  3. Baris 19 (penjualan.loc[["P001", "P002"], "jumlah"] = [40, 45]): list label baris dan list nilai memiliki panjang yang sama; pandas memasangkan keduanya sesuai urutan penulisan.
  4. Baris 20 (penjualan.at["P005", "stok"] = 18): accessor .at khusus untuk satu label dan satu kolom, sehingga lebih ringkas untuk pengisian nilai tunggal.
  5. Baris 24 (penjualan.loc[penjualan["stok"] < 15, "stok"] = 15): mask boolean di posisi baris; hanya baris dengan kondisi True yang diubah.

Output pertama tampil sebagai Series dengan dtype: object karena kolom yang memuat campuran teks dan angka tidak dapat direpresentasikan sebagai satu tipe data. Output kedua menegaskan jumlah untuk P001 dan P002 sudah berganti nilai. Pada baris P005, stok tercetak 18 sebagai hasil pengisian lewat .at.

Mengubah Banyak Sel Sekaligus #

.loc dengan list label mengubah banyak baris sekaligus dalam satu pernyataan. Panjang list nilai harus sama dengan jumlah label baris, dan pasangannya mengikuti urutan penulisan: nilai pertama untuk label pertama, dan seterusnya. Bila kebutuhannya hanya satu sel, .at lebih ringkas; namun .at menolak list dan hanya menerima satu nilai tunggal (skalar). Bentuk-bentuk akses .loc ini dirinci lebih jauh pada halaman Indexing and selecting data .

Untuk koreksi massal berdasarkan aturan bisnis, gabungkan .loc dengan mask boolean. Penulisan penjualan["stok"] < 15 menghasilkan Series boolean yang panjangnya sama dengan jumlah baris, lalu .loc memakainya untuk memilih baris mana yang boleh diisi. Pada output ketiga, hanya P001 yang semula 12 dan P002 yang semula 8 dinaikkan menjadi 15; baris P004 tetap 15 karena nilainya tidak lebih kecil dari 15.

Dengan .loc, .at, dan mask boolean, seluruh kebutuhan koreksi nilai sudah tertangani. Koreksi nilai tidak menyentuh nama kolom maupun label index; kebutuhan itu diserahkan pada method lain. Chapter berikutnya menambahkan alat koreksi berbasis syarat — where() dan mask() — sebelum rename() menangani penggantian nama kolom dan label index.