เก็บเฉพาะส่วนวันที่เมื่อใช้ pandas.to_datetime


206

ฉันใช้pandas.to_datetimeเพื่อแยกวิเคราะห์วันที่ในข้อมูลของฉัน หมีแพนด้าโดยค่าเริ่มต้นจะแสดงวันที่ด้วยdatetime64[ns]แม้ว่าวันที่จะเป็นทุกวันเท่านั้น ฉันสงสัยว่ามีวิธีที่สง่างาม / ฉลาดในการแปลงวันที่ไปdatetime.dateหรือdatetime64[D]เพื่อให้เมื่อฉันเขียนข้อมูลไปยัง CSV 00:00:00วันที่ไม่ได้รับการผนวกเข้ากับ ฉันรู้ว่าฉันสามารถแปลงประเภทองค์ประกอบด้วยตนเองโดยองค์ประกอบ:

[dt.to_datetime().date() for dt in df.dates]

pandas.to_datetimeแต่นี้เป็นช้าจริงๆเพราะผมมีหลายแถวและการเรียงลำดับของความปราชัยวัตถุประสงค์ของการใช้ มีวิธีการแปลงdtypeคอลัมน์ทั้งหมดในครั้งเดียวหรือไม่? หรือมิฉะนั้นpandas.to_datetimeสนับสนุนข้อกำหนดความแม่นยำเพื่อให้ฉันสามารถกำจัดส่วนเวลาในขณะที่ทำงานกับข้อมูลรายวัน?

คำตอบ:


295

เนื่องจากเวอร์ชัน0.15.0นี้สามารถทำได้อย่างง่ายดายโดยใช้.dtเพื่อเข้าถึงเฉพาะวันที่:

df['just_date'] = df['dates'].dt.date

ด้านบนจะส่งกลับค่าdatetime.datedtype หากคุณต้องการให้มีส่วนประกอบdatetime64จากนั้นคุณสามารถnormalizeกำหนดองค์ประกอบเวลาเป็นเที่ยงคืนเพื่อให้ตั้งค่าทั้งหมดเป็น00:00:00:

df['normalised_date'] = df['dates'].dt.normalize()

สิ่งนี้จะเก็บ dtype ไว้datetime64แต่จอแสดงผลจะแสดงเฉพาะdateค่า


37

วิธีแก้ปัญหาง่าย ๆ :

df['date_only'] = df['date_time_column'].dt.date

เพียงแค่คำเตือนนี้จะเปลี่ยนประเภทเป็นวัตถุ ดังนั้นคุณต้อง astype ('datetime64') เพื่อให้ความสอดคล้อง
misantroop

26

ในขณะที่ฉัน upvoted คำตอบของ EdChum ซึ่งเป็นคำตอบที่ตรงที่สุดสำหรับคำถามที่ OP ถูกตั้งไว้มันไม่ได้แก้ปัญหาประสิทธิภาพการทำงาน (จริง ๆ แล้วมันยังต้องอาศัยdatetimeวัตถุหลามและด้วยเหตุนี้การดำเนินการใด ๆ กับพวกเขาจะไม่ได้ จะช้า)

ทางเลือกที่มีประสิทธิภาพที่ดีกว่าdf['dates'].dt.floor('d')คือการใช้งาน พูดอย่างเคร่งครัดก็ไม่ได้ "ให้ส่วนหนึ่งวันเท่านั้น" 00:00:00เพราะมันเป็นเพียงแค่กำหนดเวลาในการ แต่มันจะทำงานได้ตามที่ OP ต้องการเช่น:

  • พิมพ์ไปที่หน้าจอ
  • บันทึกเป็น csv
  • ใช้คอลัมน์เพื่อ groupby

... และมันมีประสิทธิภาพมากขึ้นเนื่องจากการดำเนินการเป็นแบบเวกเตอร์

แก้ไข:ในความเป็นจริงคำตอบของ OP จะมีที่แนะนำอาจจะเป็น "รุ่นล่าสุดของpandasไม่ได้เขียนถึงเวลาที่จะ CSV ถ้ามันเป็น00:00:00สำหรับการสังเกตทุกคน"


แต่น่าเสียดายที่ยังคงเขียนเต็มรูปแบบto_json 00:00:00
IanS

@IanS คุณหมายถึงเมื่อใช้งานdate_format='iso'หรือไม่! โดยค่าเริ่มต้นมันเพียงแค่ส่งออกวินาทีตั้งแต่ยุค
Pietro Battiston

ใช่นั่นคือสิ่งที่ฉันหมายถึง
IanS

สิ่งนี้เร็วกว่าdt.normalize()ในซีรีย์ที่ยาวกว่าสองสามร้อยองค์ประกอบ
C8H10N4O2

17

นุ่นDatetimeIndexและSeriesมีวิธีการที่เรียกnormalizeว่าทำสิ่งที่คุณต้องการ

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ในคำตอบนี้

มันสามารถใช้เป็น ser.dt.normalize()


17

Pandas v0.13 +: ใช้to_csvกับdate_formatพารามิเตอร์

หลีกเลี่ยงการแปลงdatetime64[ns]ซีรี่ส์ของคุณเป็นobjectชุดdatetime.dateวัตถุประเภทdtype หลังมักสร้างโดยใช้pd.Series.dt.dateถูกเก็บไว้เป็นอาร์เรย์ของพอยน์เตอร์และไม่มีประสิทธิภาพเทียบกับชุด NumPy ที่ใช้บริสุทธิ์

เนื่องจากความกังวลของคุณเป็นรูปแบบเมื่อเขียนเป็น CSVเพียงใช้พารามิเตอร์ของdate_format to_csvตัวอย่างเช่น:

df.to_csv(filename, date_format='%Y-%m-%d')

ดูคำสั่งของ Pythonstrftimeสำหรับการจัดรูปแบบการประชุม


8

นี่เป็นวิธีง่ายๆในการแยกวันที่:

import pandas as pd

d='2015-01-08 22:44:09' 
date=pd.to_datetime(d).date()
print(date)

OP ได้ใช้เมธอด. วันที่ () ในคำถามของพวกเขาแล้วดังนั้นวิธีนี้จึงไม่ตอบคำถามของพวกเขา แต่ฉันคิดว่ามันมีประโยชน์ที่จะเห็นตัวอย่างง่ายๆของการใช้เมธอด date () เช่นเดียวกับการอ้างอิง
Nic Scozzaro

5

แปลงเป็นdatetime64[D]:

df.dates.values.astype('M8[D]')

แม้ว่าการกำหนดใหม่ให้กับ DataFrame col จะเปลี่ยนกลับเป็น [ns]

หากคุณต้องการจริงdatetime.date:

dt = pd.DatetimeIndex(df.dates)
dates = np.array([datetime.date(*date_tuple) for date_tuple in zip(dt.year, dt.month, dt.day)])

3
หากคุณใช้ astype ('M8 [D]') มันจะแปลงค่าที่หายไปเป็นวันที่เริ่มต้น 1970-1-1 น่าจะดีกว่าที่จะใช้ pandas.to_datetime () ทุกวันนี้
Stewbaca

1
หมายเหตุถึงใครก็ตามที่รวมโมดูล datetime เป็นประจำด้วยdtคำตอบนี้จะเขียนทับโมดูลนั้น! @ Dale-Jung บางทีอาจเปลี่ยนบรรทัดเป็น dt_index
yeliabsalohcin

ฉันยังพบปัญหาด้วยในครั้งต่อไปที่ฉันลองและเพิ่มแถวใหม่ด้วยdf.loc[date]วิธีการดัชนีจะย้อนกลับไปที่เวลาซึ่งหมายความว่าการเปรียบเทียบที่ตามมาจะไม่ทำงานอีกต่อไป
yeliabsalohcin

3

เพียงแค่ให้คำตอบที่ทันสมัยมากขึ้นในกรณีที่มีคนเห็นโพสต์เก่านี้

การเพิ่ม "utc = False" เมื่อแปลงเป็นวันที่และเวลาจะเป็นการลบองค์ประกอบของเขตเวลาและเก็บเฉพาะวันที่ในประเภทข้อมูลที่เป็น 64 [ns]

pd.to_datetime(df['Date'], utc=False)

คุณจะสามารถบันทึกลงใน excel ได้โดยไม่เกิดข้อผิดพลาด "ValueError: Excel ไม่สนับสนุนชุดข้อมูลด้วยเขตเวลาโปรดตรวจสอบให้แน่ใจว่าชุดข้อมูลเป็นเขตเวลาที่ไม่รู้จักก่อนที่จะเขียนลงใน Excel"

ป้อนคำอธิบายรูปภาพที่นี่


สิ่งนี้ด้วยเหตุผลบางอย่างล้มเหลวหลังจากที่คุณใช้ฟังก์ชันรวมใด ๆ กับคอลัมน์
RaphX

0

ฉันต้องการที่จะสามารถเปลี่ยนประเภทของชุดคอลัมน์ในกรอบข้อมูลแล้วลบเวลาในการรักษาทั้งวัน round (), floor (), ceil ()งานทั้งหมด

df[date_columns] = df[date_columns].apply(pd.to_datetime)
df[date_columns] = df[date_columns].apply(lambda t: t.dt.floor('d'))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.