pd.to_datetime() ใช้แปลงข้อมูลวันที่ที่อยู่ในรูป string หรือตัวเลขให้กลายเป็น datetime ที่ pandas จัดการได้ครับ พอแปลงแล้วก็เรียงลำดับ คำนวณระยะเวลา และดึงเดือน-ปี-วันออกมาได้ทันที
pd.to_datetime(arg, format, errors, dayfirst, yearfirst, utc, unit, origin, cache)
pd.to_datetime(arg, format, errors, dayfirst, yearfirst, utc, unit, origin, cache)
Series
เมื่อส่ง Series เข้าไปจะได้ Series ที่มี dtype datetime64 กลับมาครับ จากนั้นต่อด้วย .dt.year / .dt.month / .dt.day หรือใช้ใน sort_values ได้ทันที
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| arg | str | list | Series | DataFrame | Yes | ข้อมูลที่ต้องการแปลง อาจเป็น string เดี่ยว, list, หรือ Series ของ string วันที่ก็ได้ครับ | |
| format | str | Optional | None | รูปแบบ strftime ที่บอกว่า string นั้นหน้าตาเป็นยังไง เช่น ‘%d/%m/%Y’ หรือ ‘%Y%m%d’ ถ้าไม่ใส่ pandas จะ infer เองครับ |
| errors | str | Optional | 'raise' | ถ้าแปลงไม่ได้จะทำยังไง: ‘raise’ = ขึ้น error, ‘coerce’ = ใส่ NaT แทน ผมชอบ ‘coerce’ สำหรับข้อมูลสกปรกครับ |
| dayfirst | bool | Optional | False | ถ้า True ให้ parse วันเป็นตัวแรก เช่น ’10/11/2024′ = 10 พฤศจิกา ไม่ใช่ 11 ตุลา ใช้กับรูปแบบยุโรป/ไทยครับ |
| yearfirst | bool | Optional | False | ถ้า True ให้ parse ปีเป็นตัวแรก ใช้กับรูปแบบ ISO เช่น ‘2024-12-31’ (ปกติ pandas ก็ infer ได้เองแต่ระบุชัดกว่าครับ) |
| utc | bool | Optional | False | ถ้า True จะ normalize ทุก datetime ให้เป็น UTC เหมาะกับข้อมูลที่มีหลาย timezone ผสมกันครับ |
| unit | str | Optional | None | หน่วยของ arg เมื่อเป็นตัวเลข เช่น ‘s’ = วินาที, ‘ms’ = millisecond, ‘D’ = วัน นับจาก origin |
| origin | str | Timestamp | Optional | 'unix' | จุดเริ่มต้นสำหรับตัวเลข unit เช่น ‘unix’ = 1970-01-01, ‘julian’ หรือ Timestamp ก็ได้ครับ |
| cache | bool | Optional | True | ถ้า True จะ cache ผลการแปลง string เพื่อความเร็ว ใช้ได้ดีกับข้อมูลที่มีวันที่ซ้ำหลายแถวครับ |
pd.to_datetime(df['date_str'])pd.to_datetime(df['date_str'])
0 2024-01-15
1 2024-02-20
2 2024-03-05
Name: date_str, dtype: datetime64[us]
pd.to_datetime(df['date_str'], format='%d/%m/%Y')pd.to_datetime(df['date_str'], format='%d/%m/%Y')
0 2024-01-31
1 2024-02-28
2 2024-03-15
Name: date_str, dtype: datetime64[us]
df['date'].dt.yeardf['date'].dt.year
0 2024
1 2024
2 2024
Name: date, dtype: int32
pd.to_datetime(df['date_str'], errors='coerce')pd.to_datetime(df['date_str'], errors='coerce')
0 2024-01-15
1 NaT
2 2024-03-05
3 NaT
Name: date_str, dtype: datetime64[us]
ใช้ได้บางอย่างครับ แต่พังหลายจุดมากเลย 😅 ปัญหาหลักคือการเรียงลำดับ string วันที่แบบ ‘2/1/2024’ ‘1’ ใน string) และที่สำคัญคือทำ date arithmetic ไม่ได้ เช่น หาว่าสองวันต่างกันกี่วัน ผมเจอ bug แบบนี้บ่อยมากตอนยังใหม่อยู่ครับ แปลงก่อนเสมอดีกว่า
format= บอก pattern ชัดเจน 100% ว่าแต่ละส่วนอยู่ตรงไหนครับ แปลงได้แน่นอนและเร็วกว่า ส่วน dayfirst=True แค่ hint ให้ pandas เวลา infer อัตโนมัติ ซึ่งอาจ override ได้ถ้าหน้าตาข้อมูลมันดูเหมือน month-first มากกว่า ผมแนะนำให้ระบุ format= ตรงๆ เลยถ้าทราบรูปแบบ ไม่ต้องพึ่ง dayfirst ครับ
ขึ้นอยู่กับ input ครับ ถ้าส่ง list หรือ array เข้าไปจะได้ DatetimeIndex กลับมา แต่ถ้าส่ง Series เข้าไปจะได้ Series กลับมา ในทางปฏิบัติผมมักใช้กับ Series (df[‘date_col’]) ซึ่งได้ Series datetime64 กลับมา แล้ว assign กลับเข้าคอลัมน์ตามปกติเลยครับ
ผมคิดว่าปัญหาคลาสสิกที่นักวิเคราะห์ข้อมูลเจอบ่อยมากคือ คอลัมน์วันที่ที่ Excel หรือ CSV ส่งมาให้มักเป็น string ธรรมดา เช่น ‘2024-01-15′ หรือ ’15/01/2024’ ซึ่ง pandas ยังไม่รู้ว่ามันคือวันที่จริงๆ ครับ pd.to_datetime() คือเครื่องมือที่ใช้แปลงตรงนั้นให้เป็น datetime64 ที่ทำงานได้จริง
พอแปลงแล้ว ข้อมูลวันที่จะปลดล็อกความสามารถหลายอย่างมากครับ ทั้งเรียงลำดับได้ถูกต้อง คำนวณระยะห่างระหว่างวันได้เป็นตัวเลข และที่ผมใช้บ่อยที่สุดคือ .dt accessor ที่ช่วยดึงปี เดือน วันในสัปดาห์ออกมาแยกคอลัมน์ได้เลย
ที่เจ๋งคือมี parameter format= ที่บอก pandas ว่าสตริงนั้นหน้าตาเป็นยังไง เช่น ‘%d/%m/%Y’ สำหรับ ’31/12/2024′ ซึ่งช่วยให้แปลงได้เร็วและแม่นยำมาก และมี errors=’coerce’ สำหรับจัดการค่าผิดพลาดในข้อมูลจริงโดยไม่ให้โปรแกรมพัง
ส่วนตัวผมแนะนำให้แปลงคอลัมน์วันที่ทันทีตั้งแต่ขั้นตอนโหลดข้อมูลเลยครับ ไม่ต้องรอให้ต้องใช้ทีหลัง เพราะถ้าคอลัมน์ยังเป็น string อยู่ มักทำให้เจอ bug ตอน sort หรือ filter แบบงงๆ 😎