在數據處理過程中,難免會遇到日期格式,特別是從外部讀取數據到jupyter或其他python編譯器中,用於數據處理分析時。若讀取excel文檔時還能保留原本日期時間格式,但有時卻差強人意,讀取後為字符串格式,尤其是以csv格式存儲的數據。此時就需要用到字符串轉日期格式。
本文將介紹比較常用的字符串與日期格式互轉的方法,是屬於時間序列中部分內容。
datetime.datetimedatetime以毫秒形式存儲日期和時間。Python標準庫包含用於日期(date)和時間(time)數據的數據類型,而且還有日曆方面的功能。我們主要會用到datetime、time以及calendar模塊。datetime.datetime(也可以簡寫為datetime)是用得最多的數據類型。
>>> from datetime import datetime
>>> now = datetime.now()
>>> now
datetime.datetime(2020, 2, 6, 19, 15, 6, 617163)
>>> now.year
2020
>>> now.month
2
>>> now.day
6
timedeltatimedelta表示兩個datetime對象之間的時間差
>>> delta = datetime.now() - datetime(2016, 4, 3)
>>> delta
datetime.timedelta(days=1404, seconds=69929, microseconds=636512)
>>> delta.days
1404可以給datetime對象加上(或減去)一個或多個timedelta,這樣會產生一個新對象
>>> from datetime import timedelta
>>> start = datetime(2016,4,3)
>>> start + timedelta(1404)
datetime.datetime(2020, 2, 6, 0, 0)
>>> start - 2* timedelta(1404)
datetime.datetime(2008, 7, 26, 0, 0)datetime模塊中的數據類型
類型說明date以公曆形式存儲日期(年、月、日)time將時間存儲為時、分、秒、毫秒datetime存儲日期和時間日、秒、毫秒timedelta表示兩個datetime 值之間的差datetime 轉換為字符串datetime.strftime()
利用str或strftime方法(傳入一個格式化字符串),datetime對象和pandas的Timestamp對象可以被格式化為字符串:
>>> tamp = datetime(2020,5,20)
>>> str(tamp)
'2020-05-20 00:00:00'
>>> tamp.strftime('%Y-%m-%d')
'2020-05-20'
>>> datetime.strftime(tamp, '%Y-%m-%d')
'2020-05-20'datetime格式定義(兼容ISO C89)
代碼說明%Y4位數的年%y2位數的年%m2位數的月 [01,12]%d2位數的日 [01, 31]%H時(24小時制) [00, 23]%I時(12小時制) [01, 12]%M2位數的分[00, 59]%S秒[0,61] (秒60和61用於閏秒)%w用整數表示的星期幾 [0(星期天), 6]%U每年的第幾周[00, 53]。星期天被認為是每周的第一天,每年第一個星期天之前的那幾天被認為是"第0周"%W每年的第幾周[00, 53]。星期一被認為是每周的第一天,每年第一個星期一之前的那幾天被認為是"第0周"%z以+HHMM或-HHMM表示UTC的時區偏移量,如果時區為naive,則返回空字符串%F%Y-%m-%d 簡寫形式,例如 2020-05-25%D%m/%d/%y 簡寫形式,例如 05/25/20格式化編碼將字符串轉換為 datetimedatetime.strptime()>>> value = '2020-05-20'
>>> datetime.strptime(value,'%Y-%m-%d')
datetime.datetime(2020, 5, 20, 0, 0)
dateutil.parser.parsedatetime.strptime()是通過已知格式進行日期解析的最佳方式。但是每次都要編寫格式定義是很麻煩的事情,尤其是對於一些常見的日期格式。這種情況下,你可以用dateutil這個第三方包中的parser.parse方法(pandas中已經自動安裝好了):
>>> from dateutil.parser import parse
>>> parse('2020-02-06')
datetime.datetime(2020, 2, 6, 0, 0)dateutil可以解析幾乎所有人類能夠理解的日期表示形式
>>> parse('Jan 31, 1997 10:45 PM')
datetime.datetime(1997, 1, 31, 22, 45)在國際通用的格式中,日出現在月的前面很普遍,傳入dayfirst=True即可解決這個 問題:
>>> a = parse('02/06/2020',dayfirst = True)
>>> print(a)
2020-06-02 00:00:00
>>> a = parse('02/06/2020')
>>> print(a)
2020-02-06 00:00:00
pandas.to_datetime() --轉換成DatetimeIndexpandas通常是用於處理成組日期的,不管這些日期是DataFrame的軸索引還是列。to_datetime方法可以解析多種不同的日期表示形式。對標準日期格式(如ISO8601)的解析非常快:
>>> import pandas as pd
>>> datestrs = ['2011-07-06 12:00:00', '2011-08-06 00:00:00']
>>> pd.to_datetime(datestrs)
DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00'], dtype='datetime64[ns]', freq=None)它還可以處理缺失值(None、空字符串等)
>>> import numpy as np
>>> idx = datestrs + [np.nan]
>>> pd.to_datetime(idx) # NaT(Not a Time)是pandas中時間戳數據的null值。
DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00', 'NaT'], dtype='datetime64[ns]', freq=None)注意:dateutil.parser是一個實用但不完美的工具。比如說,它會把一些原本不是日期的字符串認作是日期(比如"42"會被解析為2042年的今天)。
NaT(Not a Time)是pandas中時間戳數據的null值。
pandas Timestamp 轉 datetime我們知道了利用str或datetime.strftime()方法(傳入一個格式化字符串),可將datetime對象和pandas的Timestamp對象可以被格式化為字符串。也知道了將字符串轉化為datetime對象。
在數據處理過程中,特別是在處理時間序列過程中,常常會出現pandas._libs.tslibs.timestamps.Timestamp格式的日期類型,這與我們所希望的datetime.datetime格式的日期格式不相同。
to_pydatetime()方法轉化轉換直接創建的pd.Timestamp對象>>> ts = pd.Timestamp('2020-05-20 00:00:00', tz=None)
>>> type(ts)
pandas._libs.tslibs.timestamps.Timestamp
>>> ts.to_pydatetime()
datetime.datetime(2020, 5, 20, 0, 0)
>>> type(ts.to_pydatetime())
datetime.datetime
轉換由 pandas.to_datetime() 生成的 DatetimeIndex 的單個元素>>> datestrs = ['2011-07-06 12:00:00'
, '2011-08-06 00:00:00']
>>> pd.to_datetime(datestrs)
DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00'], dtype='datetime64[ns]', freq=None)
>>> type(pd.to_datetime(datestrs))
pandas.core.indexes.datetimes.DatetimeIndex
# 取其中一個元素
>>> pd.to_datetime(datestrs)[0]
Timestamp('2011-07-06 12:00:00')
>>> type(pd.to_datetime(datestrs)[0])
pandas._libs.tslibs.timestamps.Timestamp
>>> ts = pd.to_datetime(datestrs)[0]
>>> ts.to_pydatetime()
datetime.datetime(2011, 7, 6, 12, 0)
直接將DatetimeIndex整體轉換>>> rng = pd.date_range('20/05/2020'
, periods=3, freq='D')
>>> rng
DatetimeIndex(['2020-05-20', '2020-05-21', '2020-05-22']
, dtype='datetime64[ns]', freq='D')
>>> rng.to_pydatetime()
array([datetime.datetime(2020, 5, 20, 0, 0),
datetime.datetime(2020, 5, 21, 0, 0),
datetime.datetime(2020, 5, 22, 0, 0)], dtype=object)
time 與日期互轉字符串轉time類型>>> import time
>>> timestr = "2020-05-25"
>>> t = time.strptime(timestr, "%Y-%m-%d")
>>> t
time.struct_time(tm_year=2020, tm_mon=5, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=146, tm_isdst=-1)
>>> type(t)
time.struct_time
time類型與datetime類型的轉換還是需要datetime模塊將其轉換為日期格式
>>> from datetime import datetime
>>> y,m,d = t[0:3]
>>> datetime(y,m,d)
datetime.datetime(2020, 5, 20, 0, 0)
>>> print(datetime(y,m,d))
2020-05-20 00:00:00
time類型轉字符串>>> time.strftime("%Y-%m-%d %X", time.localtime())
'2020-5-20 20:05:20'time格式定義
代碼說明%a星期幾的簡寫 Weekday name, abbr.%A星期幾的全稱 Weekday name, full%b月分的簡寫 Month name, abbr%B月份的全稱 Month name, full%c標準的日期的時間串 Complete date and time representation%d十進位表示的每月的第幾天 Day of the month%H24小時制的小時 Hour (24-hour clock)%I12小時制的小時 Hour (12-hour clock)%j十進位表示的每年的第幾天 Day of the year%m十進位表示的月份 Month number%M十時制表示的分鐘數 Minute number%S十進位的秒數 Second number%U第年的第幾周,把星期日做為第一天(值從0到53)Week number (Sunday first weekday)%w十進位表示的星期幾(值從0到6,星期天為0)weekday number%W每年的第幾周,把星期一做為第一天(值從0到53) Week number (Monday first weekday)%x標準的日期串 Complete date representation (e.g. 13/01/08)%X標準的時間串 Complete time representation (e.g. 17:02:10)%y不帶世紀的十進位年份(值從0到99)Year number within century%Y帶世紀部分的十制年份 Year number%z,%Z時區名稱,如果不能得到時區名稱則返回空字符。Name of time zonepandas時間序列基礎
-- 數據STUDIO --