บทนำ
การเลือกแถวที่มีค่าสูงสุดของคอลัมน์บางคอลัมน์ภายในแต่ละกลุ่ม เป็น operation พื้นฐานในการวิเคราะห์ข้อมูล บทความนี้แสดงวิธีหาค่าสูงสุดของแต่ละกลุ่มใน DataFrame
ปัญหา
สมมติมีข้อมูลหนัง ต้องการรายการหนังที่มี popularity สูงสุดของแต่ละปี
ขั้นตอนการทำงาน
1. เตรียมข้อมูล
โหลดข้อมูลหนังจาก Kaggle/GitHub
import pandas as pd
import numpy as np
movies = pd.read_csv("https://raw.githubusercontent.com/sasankac/TestDataSet/master/movies_data.csv")
2. สำรวจข้อมูล
print(movies.dtypes)
# budget int64, id int64, original_language object, ...
# popularity float64, release_date object, revenue int64, runtime float64...
3. ลดขนาดหน่วยความจำ (Optional)
แปลง int64/float64 ให้เล็กลงได้ เช่น vote_count, runtime ใช้ int16
4. สร้างคอลัมน์ปีจาก release_date
movies['year'] = pd.to_datetime(movies['release_date']).dt.year.astype('Int64')
วิธีที่ 1: ไม่ใช้ GroupBy (Sort + Drop Duplicates)
- เลือกคอลัมน์ title, year, popularity
- เรียงลำดับ year ascending, popularity descending
- drop_duplicates subset='year' เก็บแถวแรกของแต่ละปี (ซึ่งเป็น popularity สูงสุด)
result = movies[["title", "year", "popularity"]]\
.sort_values(["year", "popularity"], ascending=[True, False])\
.drop_duplicates(subset="year")
วิธีที่ 2: ใช้ GroupBy
result = movies[["title", "year", "popularity"]]\
.groupby("year", as_index=False)\
.apply(lambda df: df.sort_values("popularity", ascending=False).head(1))\
.droplevel(0)\
.sort_values("year", ascending=False)
ผลลัพธ์
ทั้งสองวิธีให้ผลลัพธ์เดียวกัน: หนังที่มี popularity สูงสุดแต่ละปี เช่น 2016 → Deadpool (514.57), 2015 → Minions (875.58), 2014 → Interstellar (724.25) ฯลฯ
สรุป
- วิธีที่ 1 เข้าใจง่าย ใช้ sort + drop_duplicates
- วิธีที่ 2 ใกล้เคียง SQL ใช้ groupby + apply
- ทั้งคู่มีประสิทธิภาพดี เลือกได้ตามความชอบ