Thep Excel

pandas applyรันฟังก์ชันกับทุกแถวหรือทุกคอลัมน์

apply ใน pandas ผมใช้สำหรับรันฟังก์ชันกับแต่ละแถวหรือแต่ละคอลัมน์ใน DataFrame หรือรันกับแต่ละค่าใน Series ตอนที่ต้องการ logic ซับซ้อนที่ vectorized operations ทำไม่ได้ครับ

>_
df.apply(func, axis)

ความนิยม5/10
ความยาก3/10
ประโยชน์5/10

อัปเดต 31 May 2026

Syntax & Arguments

คืนค่าSeries

ผลลัพธ์เป็น Series ถ้าฟังก์ชันคืนค่า scalar ต่อแถว/คอลัมน์ หรือเป็น DataFrame ถ้าฟังก์ชันคืน Series (axis=1) ครับ ส่วนใหญ่ตอน apply บน Series หรือ axis=1 แบบง่ายจะได้ Series กลับมา

อาร์กิวเมนต์ ชนิด ค่าเริ่มต้น คำอธิบาย
func callable ฟังก์ชันที่จะรัน รับได้ทั้ง lambda, def function, หรือ numpy function เช่น np.sqrt
[axis]ไม่บังคับ int | str 0 0 หรือ ‘index’ = รันต่อคอลัมน์ (ค่า default), 1 หรือ ‘columns’ = รันต่อแถว ผมใช้ axis=1 บ่อยกว่าครับตอนอยากคำนวณข้ามคอลัมน์
[raw]ไม่บังคับ bool False False = ส่ง Series เข้าฟังก์ชัน, True = ส่ง ndarray แทน เร็วกว่าถ้าใช้ numpy functions ที่รับ array โดยตรง
[result_type]ไม่บังคับ str | None None ใช้ได้เฉพาะ axis=1: ‘expand’ แปลง list เป็นหลายคอลัมน์, ‘reduce’ บีบเป็น Series, ‘broadcast’ คงรูปต้นฉบับ
[args]ไม่บังคับ tuple () arguments เพิ่มเติมที่จะส่งเข้าฟังก์ชัน ตามหลัง argument หลักที่ apply ส่งให้อัตโนมัติ

[ ] = อาร์กิวเมนต์ที่ไม่บังคับ

Additional Notes

apply เป็นเหมือนคำสั่ง “วิ่งทีละแถว” ของ pandas ครับ ทำงานในโหมด Split-Apply-Combine คล้ายกับ groupby เลย แต่แทนที่จะแบ่งกลุ่มก่อน มันจะส่งแต่ละแถว (axis=1) หรือแต่ละคอลัมน์ (axis=0) เป็น Series เข้าไปหาฟังก์ชันที่เราเขียน แล้วรวมผลลัพธ์กลับมา ถ้าใช้กับ Series ธรรมดา (ไม่ใช่ DataFrame) มันจะส่งแต่ละค่าทีละตัวเข้าไปเลย

ที่เจ๋งคือ apply รับฟังก์ชันอะไรก็ได้ ทั้ง lambda แบบสั้น, ฟังก์ชันที่เราเขียนเอง หรือฟังก์ชันจาก library อื่นก็ได้ ทำให้มัน flexible มากครับ อยากทำ logic อะไรที่แปลกๆ ก็ทำได้หมด ✨

ส่วนตัวผมใช้ apply เป็น “ทางเลือกสุดท้าย” ครับ 😎 เพราะมัน loop ทีละแถวใน Python ซึ่งช้ากว่า vectorized operations อย่าง `df[‘col’] * 2` หรือ `np.sqrt(df[‘col’])` เยอะมาก ถ้า logic ง่ายๆ ให้ใช้ arithmetic operators หรือ numpy ก่อน apply ค่อยเข้ามาตอนที่ logic ซับซ้อนจริงๆ

Examples

ตัวอย่างที่ 1: apply บน Series ด้วย lambda (element-wise)s.apply(lambda v: v * 2)

ผมรัน lambda กับแต่ละค่าใน Series ครับ แต่ละตัวจะถูก *2 ทีละค่า ได้ Series ใหม่ออกมา 20, 40, 60, 80 โน้ต: ตัวอย่างนี้ vectorized เร็วกว่า (`s * 2`) แต่เป็นจุดเริ่มต้นที่ดีเพื่อเข้าใจว่า apply ทำอะไรครับ

>_
s.apply(lambda v: v * 2)

ผลลัพธ์0 20
1 40
2 60
3 80
dtype: int64
ตัวอย่างที่ 2: apply กับ named function บน Seriess.apply(categorize)

คราวนี้ผมใช้ฟังก์ชันที่ตั้งชื่อไว้แล้ว (named function) แทน lambda ครับ มีประโยชน์ตอน logic ซับซ้อนเกิน 1 บรรทัด เช่น จัดหมวดหมู่ราคา ผลลัพธ์เป็น Series ของ string 'ราคาถูก' / 'ราคากลาง' / 'ราคาแพง' แต่ละตัวตรงกับค่าตั้นต้น

>_
s.apply(categorize)

ผลลัพธ์0 ราคาถูก
1 ราคากลาง
2 ราคาแพง
3 ราคาถูก
4 ราคาแพง
dtype: str
ตัวอย่างที่ 3: apply บน DataFrame แบบ row-wise ด้วย axis=1df.apply(lambda row: row['base_price'] * (1 – row['discount_pct'] / 100), axis=1)

นี่คือกรณีที่ผมใช้ apply บ่อยที่สุดครับ ตอนต้องคำนวณข้ามหลายคอลัมน์ในแถวเดียว ด้วย axis=1 แต่ละ row จะถูกส่งเข้า lambda เป็น Series และเรา access คอลัมน์ได้ด้วย row['ชื่อ'] ได้ราคาหลังหักส่วนลดออกมาเป็น Series ครับ

>_
df.apply(lambda row: row['base_price'] * (1 – row['discount_pct'] / 100), axis=1)

ผลลัพธ์0 90.0
1 190.0
2 240.0
dtype: float64
ตัวอย่างที่ 4: apply บน DataFrame แบบ column-wise ด้วย axis=0 (default)df.apply(lambda col: col.max() – col.min())

ตอน axis=0 (ค่า default) แต่ละ "คอลัมน์" จะถูกส่งเข้าฟังก์ชันเป็น Series ครับ ผมใช้หา range (ค่าสูงสุด – ต่ำสุด) ของแต่ละคอลัมน์คะแนน ได้ผลออกมาเป็น Series ที่ index คือชื่อคอลัมน์

>_
df.apply(lambda col: col.max() – col.min())

ผลลัพธ์score_A 20
score_B 35
dtype: int64

FAQs

apply ช้าแค่ไหน เทียบกับ vectorized operations?+

ช้ากว่าเยอะมากครับ 😅 apply วน loop ใน Python ทีละแถว ถ้าข้อมูล 1 ล้านแถว vectorized operations เสร็จในหลัก milliseconds แต่ apply อาจใช้เวลาหลายวินาทีเลย ผมเลยใช้ apply เฉพาะตอนที่ logic ซับซ้อนจริงๆ เช่น ต้องเงื่อนไข if-else หลายชั้น หรือ call ฟังก์ชัน external ที่ไม่รับ array ครับ

ต่างจาก applymap (หรือ map) ยังไง?+

apply ส่ง Series เข้าฟังก์ชัน (ทั้งแถวหรือทั้งคอลัมน์) ครับ ส่วน map ใน Series และ applymap (เปลี่ยนชื่อเป็น map ใน pandas 2.1+) ส่งค่าแต่ละ cell เข้าทีละค่าเลย ผมใช้ .map() ตอนอยากเปลี่ยนค่าแต่ละ cell อย่างเดียวโดยไม่ต้องเห็นแถวรอบข้าง และใช้ apply ตอนต้องคำนวณข้ามคอลัมน์ในแถวเดียวกันครับ

ส่ง argument เพิ่มเติมเข้าฟังก์ชันได้ไหม?+

ได้เลยครับ ใช้ parameter args=(val1, val2) เพื่อส่ง positional args เพิ่ม หรือส่งเป็น **kwargs ก็ได้ เช่น df['price'].apply(add_tax, args=(0.07,)) ถ้าเขียนฟังก์ชัน add_tax(price, tax_rate) ไว้ครับ

Resources & Related

ฟังก์ชันที่ผู้เขียนโยงไว้กับ pandas apply จัดกลุ่มตามหมวด · ชี้ที่ชื่อใดชื่อหนึ่ง แล้วฟังก์ชันที่ใช้คู่กันจะมีจุดทอง

ฟังก์ชันนี้pandas applyTransform
Transform (4)
pandas astype

astype ใน pandas ผมใช้สำหรับแปลงประเภทข้อมูล (dtype) ของคอลัมน์หรือ DataFrame เช่น จาก object เป็น int หรือ float เป็น str ทำให้คำนวณได้ถูกต้องและประหยัด memory มากขึ้นครับ

pandas .dt

pandas .dt accessor ผมใช้สำหรับดึงส่วนต่างๆ ของวันที่ออกจาก datetime Series เช่น ปี เดือน วัน ชื่อวัน หรือไตรมาส เหมือนกับที่ Excel มีฟังก์ชัน YEAR() MONTH() DAY() WEEKDAY() แต่ทำได้กับทั้งคอลัมน์พร้อมกันในคำสั่งเดียวเลยครับ

pandas .str

pandas .str accessor ทำให้ผมใช้ text functions อย่าง upper, replace, contains กับทุกแถวในคอลัมน์พร้อมกันบรรทัดเดียว เหมือนได้ UPPER/SUBSTITUTE/SEARCH ของ Excel แต่ไม่ต้องลากสูตรทีละเซลล์ครับ

pandas to_datetime

pd.to_datetime() ใช้แปลงข้อมูลวันที่ที่อยู่ในรูป string หรือตัวเลขให้กลายเป็น datetime ที่ pandas จัดการได้ครับ พอแปลงแล้วก็เรียงลำดับ คำนวณระยะเวลา และดึงเดือน-ปี-วันออกมาได้ทันที

Aggregation (1)
pandas groupby

groupby ใน pandas ผมใช้สำหรับจัดกลุ่มข้อมูลใน DataFrame แล้วคำนวณค่าสรุปในแต่ละกลุ่ม เช่น หาผลรวม ค่าเฉลี่ย หรือค่าสถิติต่างๆ ตามหมวดหมู่ที่กำหนด ถ้าใครเคยใช้ PivotTable ใน Excel มาก่อน บอกเลยว่าตัวนี้คือเครื่องมือสายเดียวกันเลยครับ

Comments

อีเมลของคุณจะไม่ถูกเผยแพร่