แยกวันจากค่า numpy.timedelta64


87

ฉันใช้แพนด้า / python และฉันมีอนุกรมเวลาสองวันที่ s1 และ s2 ซึ่งสร้างขึ้นโดยใช้ฟังก์ชัน 'to_datetime' บนฟิลด์ของ df ที่มีวันที่ / เวลา

เมื่อฉันลบ s1 จาก s2

s3 = s2 - s1

ฉันได้รับซีรีส์ s3 ประเภท

timedelta64 [ns]

0    385 days, 04:10:36
1     57 days, 22:54:00
2    642 days, 21:15:23
3    615 days, 00:55:44
4    160 days, 22:13:35
5    196 days, 23:06:49
6     23 days, 22:57:17
7      2 days, 22:17:31
8    622 days, 01:29:25
9     79 days, 20:15:14
10    23 days, 22:46:51
11   268 days, 19:23:04
12                  NaT
13                  NaT
14   583 days, 03:40:39

ฉันจะดู 1 องค์ประกอบของซีรีส์ได้อย่างไร:

s3 [10]

ฉันได้รับสิ่งนี้:

numpy.timedelta64 (2069211000000000, 'ns')

ฉันจะแยกวันออกจาก s3 ได้อย่างไรและอาจเก็บเป็นจำนวนเต็ม (ไม่สนใจชั่วโมง / นาทีเป็นต้น)

ขอบคุณล่วงหน้าสำหรับความช่วยเหลือใด ๆ


4
เพียงแค่ FYI กำลังจะรวมเป็นแพนด้าให้เชี่ยวชาญฟังก์ชันนี้: github.com/pydata/pandas/pull/4534 (คุณสามารถทำได้ใน 0.12 และก่อนหน้าโดย:s.apply(lambda x: x / np.timedelta64(1,'D'))
เจฟฟ์

คำตอบ:


147

คุณสามารถแปลงเป็น timedelta ด้วยความแม่นยำของวัน หากต้องการแยกค่าจำนวนเต็มของวันให้หารด้วย timedelta ของวันหนึ่ง

>>> x = np.timedelta64(2069211000000000, 'ns')
>>> days = x.astype('timedelta64[D]')
>>> days / np.timedelta64(1, 'D')
23

หรือเป็น @PhillipCloud ปัญหาเพียงdays.astype(int)ตั้งแต่timedeltaเป็นเพียงจำนวนเต็ม 64bit ที่ถูกตีความในรูปแบบต่างๆขึ้นอยู่กับพารามิเตอร์ที่สองคุณผ่าน ( 'D', 'ns', ... )

ท่านสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ที่นี่


16
คุณยังสามารถทำdays.item().daysหรือdays.astype(int).
Phillip Cloud

1
แพนด้าเวอร์ชันล่าสุดรองรับประเภท Timedelta เต็มรูปแบบดูเอกสารที่นี่: pandas.pydata.org/pandas-docs/stable/timedeltas.html
Jeff

นี่คือตัวเลือกที่ดีสำหรับ. สมัคร คุณสามารถทำได้ในบรรทัดเดียวกับที่คุณคำนวณค่าของคอลัมน์โดยใส่ .apply (lambda x: x / np.timedelta64 (1, 'D')) ต่อท้ายเพื่อใช้การแปลงที่ระดับคอลัมน์ เช่น s3 = (s1-s2) .apply (lambda x: x / np.timedelta64 (1, 'D'))
Ezekiel Kruglick

2
วิธีนี้astype('timedelta64[D]')(ประมาณ 96ms) มีประสิทธิภาพมากกว่าdt.days.(ประมาณ 24 วินาที) สำหรับ 4,000,000 แถว
Pengju Zhao

39

ใช้dt.daysเพื่อรับแอตทริบิวต์วันเป็นจำนวนเต็ม

เช่น:

In [14]: s = pd.Series(pd.timedelta_range(start='1 days', end='12 days', freq='3000T'))

In [15]: s
Out[15]: 
0    1 days 00:00:00
1    3 days 02:00:00
2    5 days 04:00:00
3    7 days 06:00:00
4    9 days 08:00:00
5   11 days 10:00:00
dtype: timedelta64[ns]

In [16]: s.dt.days
Out[16]: 
0     1
1     3
2     5
3     7
4     9
5    11
dtype: int64

มากกว่าปกติ - คุณสามารถใช้คุณสมบัติการเข้าถึงรูปแบบของการลดลง.componentstimedelta

In [17]: s.dt.components
Out[17]: 
   days  hours  minutes  seconds  milliseconds  microseconds  nanoseconds
0     1      0        0        0             0             0            0
1     3      2        0        0             0             0            0
2     5      4        0        0             0             0            0
3     7      6        0        0             0             0            0
4     9      8        0        0             0             0            0
5    11     10        0        0             0             0            0

ตอนนี้เพื่อรับhoursแอตทริบิวต์:

In [23]: s.dt.components.hours
Out[23]: 
0     0
1     2
2     4
3     6
4     8
5    10
Name: hours, dtype: int64

+1 - นี่เป็นวิธีที่ดีที่สุดในการดำเนินการในขณะนี้เนื่องจากแพคเกจแพนด้ามีความคืบหน้าตั้งแต่คำถามนี้ถูกถาม
Austin

7

สมมติว่าคุณมีชุดเวลา:

import pandas as pd
from datetime import datetime
z = pd.DataFrame({'a':[datetime.strptime('20150101', '%Y%m%d')],'b':[datetime.strptime('20140601', '%Y%m%d')]})

td_series = (z['a'] - z['b'])

วิธีหนึ่งในการแปลงคอลัมน์หรืออนุกรมเวลานี้คือการส่งไปยังวัตถุ Timedelta (แพนด้า 0.15.0+) จากนั้นแยกวันออกจากวัตถุ:

td_series.astype(pd.Timedelta).apply(lambda l: l.days)

อีกวิธีหนึ่งคือการแคสซีรีส์เป็น timedelta64 ในหลายวันจากนั้นจึงส่งเป็น int:

td_series.astype('timedelta64[D]').astype(int)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.