### 引入
DataFrame處理的數(shù)據(jù)中經(jīng)常會看到某一列的數(shù)據(jù)類型是時間類型或者是字符串但是需要轉(zhuǎn)成時間類型。什么是時間類型?與Python中使用的模塊time、datetime等有什么聯(lián)系?
首先看看下面這張圖,如果看到數(shù)據(jù)的如果類型是**datetime64[ns]**說明就是DataFrame中的日期時間類型。
但是有時候我們看到的數(shù)據(jù)明明都是日期格式,怎么就偏偏不是**datetime64[ns]**類型呢?而顯示的是object類型,比如下面你看到的數(shù)據(jù)
上面看到都是object類型,object類型在獲取日期時間的年月日時分秒的時候就不方便,比獲取
### 簡單回顧Python日期時間模塊
python標準庫包含用于日期(date)和時間(time)數(shù)據(jù)的數(shù)據(jù)類型,而且還有日歷方面的功能。我們主要會用到datetime、time以及calendar模塊。
#### datetime模塊
datetime模塊常用的類如下:
| 類型 | 說明 |
| --------- | ------------------------------------------ |
| date | 日期對象,以公歷形式存儲日期(年、月、日) |
| time | 時間對象,將時間存儲為:時、分、秒、毫秒 |
| datetime | 存儲日期和時間 |
| timedelta | 時間間隔,表示兩個datetime之間的差 |
附錄(日期和時間的格式化符號表)
| 符號 | 說明 |
| :--- | :---------------------------------------- |
| `%y` | 兩位數(shù)的年份表示(00-99) |
| `%Y` | 四位數(shù)的年份表示(000-9999) |
| `%m` | 月份(01-12) |
| `%d` | 月內(nèi)中的一天(0-31) |
| `%H` | 24小時制小時數(shù)(0-23) |
| `%I` | 12小時制小時數(shù)(01-12) |
| `%M` | 分鐘數(shù)(00=59) |
| `%S` | 秒(00-59) |
| `%a` | 本地簡化星期名稱 |
| `%A` | 本地完整星期名稱 |
| `%b` | 本地簡化的月份名稱 |
| `%B` | 本地完整的月份名稱 |
| `%c` | 本地相應的日期表示和時間表示 |
| `%j` | 年內(nèi)的一天(001-366) |
| `%p` | 本地A.M.或P.M.的等價符 |
| `%U` | 一年中的星期數(shù)(00-53)星期天為星期的開始 |
| `%w` | 星期(0-6),星期天為星期的開始 |
| `%W` | 一年中的星期數(shù)(00-53)星期一為星期的開始 |
| `%x` | 本地相應的日期表示 |
| `%X` | 本地相應的時間表示 |
| `%Z` | 當前時區(qū)的名稱 |
| `%%` | %號本身 |
date類代碼演示:
> datetime.date(year, month, day)
```python
from datetime import date
# 獲取當前的日期
today = date.today()
print(today) # 2021-08-10
print(today.day) # 10
# 也可以創(chuàng)建一個指定的日期對象
tomorrow = date(2021,8,11)
print(tomorrow) # 2021-08-11
print(tomorrow.day) # 11
print(today.strftime('%Y年%m月%d日')) # 相當于格式化輸出
```
time類代碼演示:
> datetime.time(hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] )
```python
from datetime import time
# 創(chuàng)建一個time對象
t = time(14,20,59,83999)
print(t) # 14:20:59.083999
print(t.strftime('%H:%M:%S')) # 相當于格式化輸出
```
datetime代碼演示:
> datetime相當于date和time結(jié)合起來
> datetime.datetime (year, month, day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] )
```python
from datetime import datetime
now = datetime.now()
print(now) # datetime.datetime(2021, 8, 10, 15, 21, 6, 581886)
print(now.year) # 2021
print(now.month) # 8
print(now.day) # 21
print(now.date())
print(now.time())
print(now.strftime('%Y年%m月%d日 %H:%M:%S')) # 格式化輸出
```
timedelta代碼演示:
> 使用timedelta可以很方便的在日期上做天days,小時hours,分鐘,秒,毫秒,微妙的時間計算,如果要計算月份則需要另外的辦法。
```python
from datetime import *
dt = datetime.now()
#日期減一天,dt1和dt2都表示昨天,兩種不同的操作方式
dt1 = dt + timedelta(days=-1) # 昨天
dt2 = dt - timedelta(days=1) # 昨天
dt3 = dt + timedelta(days=1) # 明天
print(dt1)
print(dt2)
print(dt3)
# 也可以小時的加減
t1 = dt + timedelta(hours=1)
print(t1)
```
**案例**:獲取指定日期月份的**最后一天的日期和本月天數(shù)**
```
from datetime import datetime,date,timedelta
date1 = datetime.now()
def eomonth(date_object):
if date_object.month == 12:
next_month_first_date = date(date_object.year+1,1,1)
else:
next_month_first_date = date(date_object.year, date_object.month+1, 1)
return next_month_first_date - timedelta(1)
print(eomonth(date1))
print(eomonth(date1).day)
```
#### time模塊
time模塊中時間表現(xiàn)的格式主要有三種:
> a、timestamp時間戳,時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量
>
> b、struct_time時間元組,共有九個元素組。
>
> c、format time 格式化時間,已格式化的結(jié)構(gòu)使時間更具可讀性。包括自定義格式和固定格式
```python
import time
# 生成timestamp
print(time.time()) # 時間戳時間
print(time.localtime()) # 生成struct_time
print(time.strptime('2021-08-10 16:37:06', '%Y-%m-%d %X')) # 格式化時間轉(zhuǎn)struct_time
print(time.strftime("%Y-%m-%d %X",time.localtime())) # struct_time轉(zhuǎn)格式化時間
```
當然還有大家常用的time.sleep(seconds)休眠。
### panads日期時間操作
我們在數(shù)據(jù)分析的時候時間日期的操作無非下面幾種:
#### object轉(zhuǎn)日期時間類型
| 原有數(shù)據(jù)類型(object)和展示形式 | 想得到的格式 | 代碼 |
| -------------------------------- | ------------------- | ----------------------------------------------------- |
| 2021-08-10 | 2021-08-10 | pd.to_datetime(data['time_object']) |
| 08/10/21 | 2021-08-10 | pd.to_datetime(data['time_object'],format='%m/%d/%y') |
| 2021-08-10 14:20:59 | 2021-08-10 14:20:59 | pd.to_datetime(data['time_object']) |
| 2021年08月 | 2021-08-01 | pd.to_datetime(data['time_object'],format='%Y年%m月') |
#### 日期轉(zhuǎn)固定格式的
| 原有數(shù)據(jù)類型(datetime64)和展示形式 | 想得到的格式 | 代碼 |
| ------------------------------------ | ------------------- | ------------------------------------------------------------ |
| 2021-08-10 14:20:59 | 2021-08-10 | data['datetime_col'].dt.date 或者pd.to_datetime(data['datetime_col'].dt.strftime('%Y-%m-%d')) |
| 2021-08-10 14:20:59 | 2021-08-10 00:00:00 | data['datetime_col'].dt.strftime('%Y-%m-%d 00:00:00') |
#### 提取日期類型的年月日
| 原有數(shù)據(jù)類型(datetime64)和展示形式 | 想得到的格式 | 代碼 |
| ------------------------------------ | ------------ | ------------------------------ |
| 2021-08-10 14:20:59 | 2021 | data['datetime_col'].dt.year |
| 2021-08-10 14:20:59 | 8 | data['datetime_col'].dt.month |
| 2021-08-10 14:20:59 | 10 | data['datetime_col'].dt.day |
| 2021-08-10 14:20:59 | 14 | data['datetime_col'].dt.hour |
| 2021-08-10 14:20:59 | 20 | data['datetime_col'].dt.minute |
| 2021-08-10 14:20:59 | 59 | data['datetime_col'].dt.second |
#### 時間差的計算
| startdate | enddate | difference | 代碼 |
| ------------------- | ------------------- | ---------- | ------------------------------------------------------------ |
| 2018-02-14 12:20:36 | 2019-02-28 13:38:41 | 379.054225 | (data['datetime_col']-data['datetime_col'])/np.timedelta64(1,'D') |
np.timedelta64具體內(nèi)容可以參看文檔:https://numpy.org/doc/stable/reference/arrays.datetime.html文檔中給出的案例非常詳細。