pivot_table ใน pandas ผมใช้สำหรับสร้างตารางสรุปข้อมูลแบบ PivotTable เหมือนใน Excel เลยครับ — กำหนดได้ว่าจะเอาคอลัมน์ไหนเป็น rows, columns และจะรวมค่าด้วยฟังก์ชันอะไร ทั้งหมดจบในคำสั่งเดียว
pd.pivot_table(data, values, index, columns, aggfunc)
pd.pivot_table(data, values, index, columns, aggfunc)
DataFrame
คืนเป็น DataFrame รูปตาราง pivot ที่พร้อมใช้งานทันทีครับ ต่างจาก groupby ที่คืน GroupBy object ก่อน pivot_table คืนผลสำเร็จรูปเลย สามารถนำไปต่อด้วย .reset_index(), .to_excel(), .plot() หรือ filter ต่อได้เลย
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| data | DataFrame | Yes | DataFrame ต้นทางที่จะสร้าง pivot table จาก | |
| values | str | list | Optional | None | ชื่อคอลัมน์ที่จะนำมาคำนวณ เช่น ‘sales’ หรือ [‘sales’, ‘qty’] ถ้าไม่ระบุ pandas จะใช้ทุกคอลัมน์ที่เป็นตัวเลข |
| index | str | list | Optional | None | คอลัมน์ที่จะเป็น rows ของ pivot table เทียบได้กับการลากฟิลด์ลง Rows ใน Excel PivotTable |
| columns | str | list | Optional | None | คอลัมน์ที่จะกระจายเป็นหัวตาราง (columns) ของ pivot table เทียบได้กับการลากฟิลด์ลง Columns ใน Excel PivotTable |
| aggfunc | str | function | list | dict | Optional | 'mean' | ฟังก์ชันที่ใช้รวมค่า เช่น ‘sum’, ‘mean’, ‘count’, ‘max’, ‘min’ หรือส่งเป็น list [‘sum’, ‘mean’] เพื่อคำนวณหลายค่าพร้อมกัน ค่า default คือ ‘mean’ |
| fill_value | scalar | Optional | None | ค่าที่ใช้แทน NaN เมื่อไม่มีข้อมูลในเซลล์นั้น เช่น fill_value=0 เพื่อแสดง 0 แทนช่องว่าง |
| margins | bool | Optional | False | ถ้า True จะเพิ่มแถวและคอลัมน์ ‘All’ ที่แสดงผลรวมทั้งหมด (Grand Total) เหมือนเปิด Grand Totals ใน Excel PivotTable |
| margins_name | str | Optional | 'All' | ชื่อของแถว/คอลัมน์ margins ค่า default คือ ‘All’ แต่เปลี่ยนได้ เช่น ‘รวม’ |
| dropna | bool | Optional | True | ถ้า True จะตัดแถวที่มี NaN ออกจากการคำนวณ ถ้า False จะรวม NaN ไว้ด้วย |
pd.pivot_table(df, values='sales', index='category', aggfunc='sum')pd.pivot_table(df, values='sales', index='category', aggfunc='sum')
sales
category
Clothing 1000
Electronics 3500
pd.pivot_table(df, values='sales', index='category', columns='month', aggfunc='sum', fill_value=0)pd.pivot_table(df, values='sales', index='category', columns='month', aggfunc='sum', fill_value=0)
month Feb Jan
category
Clothing 1500 400
Electronics 800 2700
pd.pivot_table(df, values='sales', index='category', aggfunc=['sum', 'mean'])pd.pivot_table(df, values='sales', index='category', aggfunc=['sum', 'mean'])
sum mean
sales sales
category
Clothing 1000 500.000000
Electronics 3500 1166.666667
pd.pivot_table(df, values='sales', index='category', columns='month', aggfunc='sum', fill_value=0, margins=True)pd.pivot_table(df, values='sales', index='category', columns='month', aggfunc='sum', fill_value=0, margins=True)
month Feb Jan All
category
Clothing 1500 400 1900
Electronics 800 2700 3500
All 2300 3100 5400
ผมมองแบบนี้ครับ: groupby เหมาะกับการสรุปค่าแบบ 1 มิติ เช่น ยอดขายรวมแต่ละเมือง ได้ผลออกมาเป็น Series หรือ DataFrame แบบยาว ส่วน pivot_table เหมาะตอนอยากได้ตารางไขว้ 2 มิติ เช่น ยอดขายแต่ละหมวดในแต่ละเดือน ถ้าต้องรายงานหรือพรีเซนต์ ผมเลือก pivot_table เพราะผลออกมาพร้อมใช้ทันทีเลยครับ
เกิดเพราะไม่มีข้อมูลในหมวดหมู่นั้นๆ ครับ เช่น ไม่มีสินค้า Electronics ในเดือน March เลย ช่องก็จะว่าง วิธีแก้คือใส่ fill_value=0 เพื่อให้แสดง 0 แทน NaN ผมใช้ตัวนี้เกือบทุกครั้งที่สร้าง pivot_table เพราะตอน export ไป Excel หรือ visualize ต่อ ค่า 0 จัดการง่ายกว่า NaN มากครับ
ได้เลยครับ ใส่ aggfunc=’count’ แล้วระบุ values ที่ต้องการนับ ผลจะออกมาเป็นจำนวนแถวที่มีข้อมูลในแต่ละกลุ่มครับ ถ้าอยากนับทุกแถวรวมถึง NaN ให้ใช้ aggfunc=’size’ แทน เพราะ count ข้าม NaN แต่ size นับทุกแถวครับ
ผมถือว่า pivot_table คือ “PivotTable ของ Excel ในโลก Python” เลยครับ ถ้าเคยลากฟิลด์เข้า Rows / Columns / Values ใน PivotTable มาแล้ว จะรู้สึกคุ้นมากเพราะแนวคิดเหมือนกันทุกอย่าง แค่เปลี่ยนจากคลิกมาเป็นเขียนโค้ดแทน
หลักการทำงานคือ pandas จะรับ DataFrame ดิบ แล้วจัดกลุ่มตามคอลัมน์ที่เรากำหนดใน index (แนวนอน) และ columns (แนวตั้ง) จากนั้นนำค่าใน values มาสรุปด้วย aggfunc ที่เราเลือก เช่น sum, mean, count ผลลัพธ์จะออกมาเป็น DataFrame รูปตารางไขว้ที่อ่านง่ายครับ
ที่เจ๋งคือ pivot_table รองรับ aggfunc หลายตัวพร้อมกันได้ เช่น [‘sum’, ‘mean’] และยังมี margins=True ที่เพิ่มแถวและคอลัมน์รวมทั้งหมด (Grand Total) ให้อัตโนมัติ เหมือนติ๊กถูก “Grand Totals” ใน PivotTable ของ Excel นั่นเองครับ ✨
ส่วนตัวผมชอบใช้ pivot_table ตอนอยากเห็นภาพรวมข้อมูล 2 มิติ เช่น ยอดขายแต่ละสินค้าในแต่ละเดือน หรือต้องการ cross-tab ที่พร้อมรายงานทันทีโดยไม่ต้องฟอร์แมตเพิ่ม 😎