Setelah subset kolom tersusun, kebutuhan berikutnya sering kali justru menambah kolom baru: kolom total dari harga dikali jumlah, kolom status yang isinya sama untuk semua baris, atau kolom dari data lain yang sudah tersimpan sebagai Series. Pandas menyediakan pola penugasan yang sama sederhananya untuk ketiga kebutuhan itu, sebagaimana dirangkum pada halaman Intro to data structures . Pada Chapter ini kita menambahkan kolom dari perhitungan antar kolom, dari konstanta, mengatur posisi kolom dengan insert(), lalu memahami alignment yang terjadi ketika sumbernya Series dengan index tidak lengkap.

Menambah Kolom dari Perhitungan dan Konstanta #

Kita lanjutkan memakai data penjualan toko Buah Segar. Kebutuhan pertama adalah kolom total yang nilainya harga * jumlah untuk setiap baris, dan kolom status_stok yang berisi teks sama untuk semua produk. Skrip berikut menambahkan keduanya, menyisipkan kolom toko di tengah tabel, lalu menambahkan kolom dari Series lain.

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["total"] = penjualan["harga"] * penjualan["jumlah"]
penjualan["status_stok"] = "tersedia"
print(penjualan[["produk", "harga", "jumlah", "total", "status_stok"]])
print()

penjualan.insert(1, "toko", "Buah Segar")
print(list(penjualan.columns))
print()

restock = pd.Series({"P002": 24, "P004": 10})
penjualan["restock"] = restock
print(penjualan[["produk", "restock"]])
print(penjualan["restock"].dtype)

Output yang Dihasilkan:

text
             produk  harga  jumlah   total status_stok
P001      Kopi Gayo  18000      35  630000    tersedia
P002     Teh Melati  12000      40  480000    tersedia
P003      Gula Aren  15000      25  375000    tersedia
P004     Roti Bakar  20000      20  400000    tersedia
P005  Pisang Goreng  10000      50  500000    tersedia

['produk', 'toko', 'kasir', 'cabang', 'harga', 'jumlah', 'stok', 'total', 'status_stok']

             produk  restock
P001      Kopi Gayo      NaN
P002     Teh Melati     24.0
P003      Gula Aren      NaN
P004     Roti Bakar     10.0
P005  Pisang Goreng      NaN
float64

Mari kita telaah peran setiap baris kode di atas:

  1. Baris 15 (penjualan["total"] = penjualan["harga"] * penjualan["jumlah"]): pandas mengalikan kolom harga dengan kolom jumlah baris demi baris sekaligus (vectorized), lalu menambahkan hasilnya sebagai kolom baru di posisi paling kanan.
  2. Baris 16 (penjualan["status_stok"] = "tersedia"): satu nilai teks tunggal di-broadcast ke seluruh baris, sehingga kelima baris memperoleh nilai tersedia.
  3. Baris 20 (penjualan.insert(1, "toko", "Buah Segar")): method insert() menyisipkan kolom baru pada posisi 1, tepat setelah kolom produk.
  4. Baris 21 (print(list(penjualan.columns))): daftar nama kolom membuktikan toko berada di antara produk dan kasir.
  5. Baris 24-25: Series restock hanya memiliki label P002 dan P004; ketika ditugaskan sebagai kolom, pandas menyelaraskan kedua sisi berdasarkan label index (alignment).

Output pertama menunjukkan kolom total bertipe int64 karena hasil perkalian dua kolom integer memang integer. Penugasan penjualan["total"] = ... mengubah penjualan secara langsung, dan penulisan ini sah karena merupakan satu akses indexing yang utuh. Bedakan dengan mengubah isi dari hasil seleksi seperti penjualan["harga"], yang pada pandas 3.0 berperilaku seperti copy sehingga modifikasinya tidak merambat ke penjualan.

Mengatur Posisi Kolom dengan insert() #

Penugasan df["nama"] = ... selalu menaruh kolom baru di posisi paling kanan. Bila posisi penting, misalnya agar kolom kunci tampil di awal laporan, gunakan method insert() dengan tiga argumen: posisi (loc), nama kolom (column), dan isinya (value). Method ini mengubah DataFrame yang memanggilnya secara langsung dan mengembalikan None, sehingga penulisannya tidak perlu disimpan ke variabel. Menambahkan kolom dengan nama yang sudah ada melalui insert() menimbulkan galat ValueError: cannot insert toko, already exists.

Menambah Kolom dari Series Lain #

Baris 24 membuat Series restock yang hanya mencantumkan label P002 dan P004. Ketika Series tersebut ditugaskan sebagai kolom baru, pandas menyelaraskan nilai berdasarkan label index, bukan berdasarkan posisi baris. Baris tanpa pasangan label memperoleh NaN, seperti terlihat pada output ketiga, dan seluruh kolom bergeser ke dtype float64 karena NaN disimpan sebagai angka desimal. Perilaku alignment ini sama dengan yang kita pelajari pada Section Dasar Series, dan menjadikan penugasan dari Series lebih dapat diandalkan daripada mengandalkan urutan list.

Kini tabel kita memiliki kolom total, status_stok, toko, dan restock yang siap dipakai untuk laporan. Kolom-kolom tersebut masih bisa disesuaikan lebih lanjut ketika data mentah mengandung kesalahan pada sel tertentu. Cara mengubah nilai sel secara langsung dan aman dengan .loc dan .at kita bahas pada Chapter berikutnya.