การใช้ Lambda กับ Pandas ใน Python

Thanabhas Ubonjit
3 min readApr 16, 2021

--

สวัสดีครับทุกคนวันนี้จะมาสาธิตการใช้ lambda กันครับ เนื่องจากไม่ค่อยเห็นคนพูดถึงใน medium เลยอยากนำมาฝากให้กับมือใหม่เหมือนกัน ช่วยให้บอกลา for loop แสนยาวได้ 😂 หรือพี่ๆทีมีประสบการ์ณแล้วมาอ่านก็หวังว่าจะได้อะไรไปบ้างนะครับ :) จะเริ่มจากสาธิตในตัว python เดี่ยวๆก่อนแล้วค่อยไปรวมกับ Pandas นะครับ ใครรู้เรื่องอยู่แล้วข้ามไปตรง Pandas ก่อนได้เลยครับ

Introduction

ก่อนอื่นเลยอธิบายคร่าวๆก่อนนะครับว่า lambda คืออะไร ให้พูดภาษาบ้านๆคือเหมือนกับ function ที่เราเขียนได้ในบรรทัดเดียว สมมติผมจะทำ function ง่ายๆสำหรับการแปลงหน่วยเมตรเป็นเซนติเมตร

def convert(metres):
return metres * 100

ถ้าใช้ lambda แบบนี้ก็ได้เหมือนกันครับและจบในบรรทัดเดียว เหมาะมากๆกับฟังก์ชั่นเล็กๆ

convert = lambda metres: metres * 100

จะกับฟังก์ชั่นหลายตัวแปรหน่อยก็ได้นะครับ lambda จะมี syntax คือแค่
lambda arguments: expression
arguments กี่ตัวก็ได้แต่ expression เดียวนะครับ

เช่น

multiply_num = lambda a, b : a*b
multiply_num(3,5)
output : 15

แต่จุดเด่นๆจริงๆเลยคือเมื่อเราใช้ lambda ร่วมกับ function ที่รับอีก function เป็น argument เช่น map(), filter(), reduce() (ขออนุญาตโชว์แค่ map, filter ก่อนนะครับเพื่อความกระชับ) เพราะ function lambda ไม่จำเป็นต้องตั้งชื่อก่อน

map(func, list) จะรับ function เข้ามาและใช้ function นั้นกับทุกตัวในลิสต์ครับ
ตัวอย่าง:

metres_list = [1, 5, 6, 7, 9, 2, 2.5, 4]
cm_list = list(map(lambda x: x*100, metres_list)))
print(cm_list)
output: [100, 500, 600, 700, 900, 200, 250.0, 400]

ถ้าเราไม่ใช้ lambda อาจจะดูไม่ยาวต่างกันมาก แต่ถ้าต้องทำอะไรแนวนี้เยอะๆ ก็อาจจะเกิดปัญหาว่าเรามีชื่อฟังก์ชั่นเต็มไปหมดกันได้นะครับ 😂 lambda จะเข้ามาช่วยส่วนนี้ได้ lambda ใช้กับ condition ก็ได้นะครับในการกรองโดยใช้ filter เช่น

metres_list = [1, 5, 6, 7, 9, 2, 2.5, 4]
cm_list = list(map(lambda x: x*100, metres_list))
print(list(filter(lambda x: x < 500, cm_list)))
output: [100, 200, 250.0, 400]

Pandas

วันนี้จะ focus ที่การใช้ lambda ร่วมกับ apply() เป็นฟังก์ชั่นของ Dataframe ที่นำ function ที่เราใส่ไปใช้กับข้อมูลนะครับ ทำได้หลายอย่างมากครับ
สมมติว่าผมี dataframe แบบนี้นะครับ

เริ่มจากอะไรชิลๆก่อน สมมติว่าผมอยากเปลี่ยน column height ให้หน่วยเป็นเมตร แทนที่จะใช้ for loop ผมสามารถใช้ lambda ได้เลย

df['height'] = df['height'].apply(lambda cm: cm/100)
df.head()

ตอนนี้ผมก็ได้เป็นแบบนี้แล้วครับ บรรทัดเดียวจบเลย!!😍😍
เช่นเดียวกันสมมติว่าผมอยากเพิ่ม column ที่เป็น BMI ของคนเหล่านี้คำนวณได้จาก น้ำหนัก / ส่วนสูง(เมตร​)² ผมก็ใช้ lambda ได้ครับ แต่อันนี้มันใช้ข้อมูลจากสอง column จะเป็นแบบนี้ครับ

df['BMI'] = df.apply(lambda x: round(x['weight'] / x['height'] ** 2), axis=1)
df.head()

จะเห็นได้นะครับรอบนี้สิ่งที่ถูกส่งเข้าไปในฟังก์ชั่นของเราคือทั้ง Dataframe เราก็ access แต่ละ column ได้เหมือนปกติเลยครับ แต่อย่าลืมใส่ axis ด้วยนะครับเพราะรอบนี้ pandas ไม่รู้ว่าเอา column หรือ row ไม่เหมือนตอนที่ใช้แค่กับ column เดียวนะครับ

เอาล่ะทีนี้ลองมาใช้ร่วมกับ condition บ้างดีกว่า!!

เริ่มง่ายๆก่อนสมมติผมอยากเปลี่ยนแถว active ให้ 0= ‘inactive’, 1 = ‘active’

df['active'] = df['active'].apply(lambda x: 'inactive' if x==0 else 'active')
df.head()

ทีนี้ลองกรณีที่มีหลาย condition นะครับ
สมมติผมจะให้จัดเกณฑ์ว่าใครน้ำหนักมากน้อยหรือกลางตามเกณฑ์ BMI < 18.5 = underweight, 18.5–25 = normal, >25 = overweight
ให้ nest ลงไปแบบนี้ได้เลยโดยใช้ () นะครับ เพราะใน lambda ยังใช้ elif ไม่ได้ครับ

df['Class'] = df['BMI'].apply(lambda x: 'Overweight' if x > 25 else ('Normal' if x > 18.5 else 'Underweight'))
df.head()

แค่นี้ก็ได้แล้วครับ หวังว่าทุกคนจะได้ประโยชน์อะไรบ้างนะครับ เชื่อว่ามี use case ให้ใช้แน่นอนครับ! ❤️❤️ ขอบคุณที่อ่านครับ

--

--