Series
คืนเป็น Series ของค่าที่ดึงออกมาครับ เช่น .dt.year คืน Series ของตัวเลขปี, .dt.day_name() คืน Series ของ string ชื่อวัน — เอาไป assign เป็นคอลัมน์ใหม่ หรือต่อด้วย groupby ได้เลย
| อาร์กิวเมนต์ | ชนิด | คำอธิบาย |
|---|---|---|
| [year]ไม่บังคับ | property | ดึงปี (integer) ออกจาก datetime Series — เทียบเท่า YEAR() ใน Excel |
| [month]ไม่บังคับ | property | ดึงเดือน 1-12 ออกจาก datetime Series — เทียบเท่า MONTH() ใน Excel |
| [day]ไม่บังคับ | property | ดึงวันที่ในเดือน 1-31 ออกจาก datetime Series — เทียบเท่า DAY() ใน Excel |
| [dayofweek]ไม่บังคับ | property | ดึงวันในสัปดาห์ 0=Monday ถึง 6=Sunday — เทียบเท่า WEEKDAY() ใน Excel (แต่ index ต่างกัน) |
| [day_name()]ไม่บังคับ | method | คืนชื่อวันเป็น string เช่น ‘Monday’, ‘Tuesday’ — ไม่มีใน Excel ตรงๆ ต้องใช้ TEXT(A1,”dddd”) |
| [quarter]ไม่บังคับ | property | ดึงไตรมาส 1-4 ออกจาก datetime Series — ไม่มีใน Excel โดยตรง ต้องคำนวณเอง |
[ ] = อาร์กิวเมนต์ที่ไม่บังคับ
ถ้าใน Excel เราใช้ YEAR(A1) เพื่อดึงปีออกจากวันที่ ใน pandas ผมใช้ .dt.year ทำแบบเดียวกันครับ แต่ดีกว่าตรงที่มันทำงานกับทั้งคอลัมน์พร้อมกันเลย ไม่ต้องลากสูตรลงทีละแถว
.dt คือ “accessor” ที่เปิดให้ Series เข้าถึง datetime properties ต่างๆ — เงื่อนไขเดียวคือ Series นั้นต้องเป็น datetime type ก่อนครับ ถ้าคอลัมน์เก็บเป็น string ต้องแปลงด้วย pd.to_datetime() ก่อนเสมอ
ที่เจ๋งคือ .dt มี property ให้เลือกเยอะมาก ครอบคลุมทุกอย่างที่ Excel ทำได้และมากกว่านั้น: .dt.year (YEAR), .dt.month (MONTH), .dt.day (DAY), .dt.day_name() (ชื่อวัน เช่น Monday), .dt.dayofweek (WEEKDAY เริ่มจาก 0=Monday), .dt.quarter (ไตรมาส), .dt.week (สัปดาห์ที่) และอีกหลายสิบตัว
ส่วนตัวผมใช้บ่อยที่สุดตอนต้องจัดกลุ่มยอดขายตามเดือนหรือไตรมาส ก็แค่ดึง .dt.month หรือ .dt.quarter ออกมาเป็นคอลัมน์ใหม่ แล้วต่อด้วย groupby ได้เลยครับ 😎
ผมแปลง string เป็น datetime ก่อนด้วย pd.to_datetime() แล้วต่อด้วย .dt.year เพื่อดึงปีออกมาครับ ได้ผลเป็น Series ของตัวเลขปี เหมือนกับการใส่สูตร =YEAR(A1) แล้วลากลงทั้งคอลัมน์ใน Excel เลย
ผมดึงเดือนออกมาเก็บเป็นคอลัมน์ใหม่ชื่อ month ครับ ค่าที่ได้คือ 1-12 เหมือน MONTH() ใน Excel เลย จากนั้นเอาคอลัมน์ month ไปทำ groupby ต่อได้เลย เช่น df.groupby('month')['sales'].sum() เพื่อหายอดขายรวมแต่ละเดือน
อันนี้ผมชอบมากครับ .dt.day_name() คืนชื่อวันเป็น string เช่น 'Monday', 'Tuesday' ซึ่ง Excel ทำแบบนี้ต้องใช้ TEXT(A1,"dddd") แต่ใน pandas เรียกได้เลยง่ายมาก ดีตอนอยากกรองเฉพาะวันทำงาน หรือดูว่าวันไหนยอดขายดีที่สุด
อันนี้คือ workflow จริงที่ผมใช้ประจำเลยครับ ดึง .dt.quarter เก็บเป็นคอลัมน์ก่อน แล้วต่อด้วย groupby เพื่อหารายได้รวมแต่ละไตรมาส ใน Excel ถ้าอยากทำแบบนี้ต้องเขียนสูตร =INT((MONTH(A1)-1)/3)+1 ยาวกว่าเยอะเลยครับ
ต้องเสมอเลยครับ ถ้าคอลัมน์ยังเป็น string แล้วลอง .dt.year จะได้ error ว่า 'Can only use .dt accessor with datetimelike values' ผมเจอบ่อยมากตอนเริ่มใช้ pandas ใหม่ๆ วิธีแก้คือใส่ pd.to_datetime() ก่อนเสมอ เช่น df['date'] = pd.to_datetime(df['date']) แล้วค่อยใช้ .dt ได้เลย
ต่างกันที่จุดเริ่มต้นครับ pandas .dt.dayofweek นับ 0=Monday, 1=Tuesday, …, 6=Sunday แต่ Excel WEEKDAY() โดยค่า default นับ 1=Sunday, 2=Monday, …, 7=Saturday ผมเลยต้องระวังตอนเปรียบเทียบผลกับ Excel ถ้าอยากให้ตรงกัน ให้บวก 1 แล้วปรับ offset เองครับ หรือใช้ .dt.day_name() แทน แล้วกรองตามชื่อวันไปเลยชัวร์กว่า
ได้ครับ แต่ .dt ใช้สำหรับดึงส่วนประกอบของวันที่ออกมา ส่วนการคำนวณระยะห่างระหว่างวันผมทำด้วยการลบ datetime columns ตรงๆ เช่น df['end'] – df['start'] ได้ Timedelta Series ออกมา แล้วค่อยใช้ .dt.days เพื่อแปลงเป็นจำนวนวันต่อได้ครับ
ฟังก์ชันที่ผู้เขียนโยงไว้กับ pandas .dt จัดกลุ่มตามหมวด · ชี้ที่ชื่อใดชื่อหนึ่ง แล้วฟังก์ชันที่ใช้คู่กันจะมีจุดทอง
apply ใน pandas ผมใช้สำหรับรันฟังก์ชันกับแต่ละแถวหรือแต่ละคอลัมน์ใน DataFrame หรือรันกับแต่ละค่าใน Series ตอนที่ต้องการ logic ซับซ้อนที่ vectorized operations ทำไม่ได้ครับ
pd.to_datetime() ใช้แปลงข้อมูลวันที่ที่อยู่ในรูป string หรือตัวเลขให้กลายเป็น datetime ที่ pandas จัดการได้ครับ พอแปลงแล้วก็เรียงลำดับ คำนวณระยะเวลา และดึงเดือน-ปี-วันออกมาได้ทันที
groupby ใน pandas ผมใช้สำหรับจัดกลุ่มข้อมูลใน DataFrame แล้วคำนวณค่าสรุปในแต่ละกลุ่ม เช่น หาผลรวม ค่าเฉลี่ย หรือค่าสถิติต่างๆ ตามหมวดหมู่ที่กำหนด ถ้าใครเคยใช้ PivotTable ใน Excel มาก่อน บอกเลยว่าตัวนี้คือเครื่องมือสายเดียวกันเลยครับ
ยังไม่มีบทความที่เกี่ยวข้องกับฟังก์ชันนี้
Comments
อีเมลของคุณจะไม่ถูกเผยแพร่