1. 程式人生 > >python+pandas+時間、日期以及時間序列處理

python+pandas+時間、日期以及時間序列處理

先簡單的瞭解下日期和時間資料型別及工具

python標準庫包含於日期(date)和時間(time)資料的資料型別,datetime、time以及calendar模組會被經常用到。

datetime以毫秒形式儲存日期和時間,datetime.timedelta表示兩個datetime物件之間的時間差。

給datetime物件加上或減去一個或多個timedelta,會產生一個新的物件

from datetime import datetime

from datetime import timedelta
now = datetime.now()
now
    datetime.datetime
(2017, 6, 27, 15, 56, 56, 167000)
datetime引數:datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
delta = now - datetime(2017,6,27,10,10,10,10)

delta
    datetime.timedelta(0, 20806, 166990)
delta.days
    0
delta.seconds
    20806
delta.microseconds
    166990

只有這三個引數了!

datetime模組中的資料型別

型別 說明
date 以公曆形式儲存日曆日期(年、月、日)
time 將時間儲存為時、分、秒、毫秒
datetime 儲存日期和時間
timedelta 表示兩個datetime值之間的差(日、秒、毫秒)

字串和datetime的相互轉換

1)python標準庫函式

日期轉換成字串:利用str 或strftime

字串轉換成日期:datetime.strptime

stamp = datetime(2017,6,27)
str(stamp)
    '2017-06-27 00:00:00'
stamp.strftime('%y-%m-%d')#%Y是4位年,%y是2位年
    '17-06-27'
#對多個時間進行解析成字串

date = ['2017-6-26','2017-6-27']

datetime2 = [datetime.strptime(x,'%Y-%m-%d') for x in date]

datetime2
    [datetime.datetime(2017, 6, 26, 0, 0), datetime.datetime(2017, 6, 27, 0, 0)]

2)第三方庫dateutil.parser的時間解析函式

from dateutil.parser import parse
parse('2017-6-27')
    datetime.datetime(2017, 6, 27, 0, 0)
parse('27/6/2017',dayfirst =True)
    datetime.datetime(2017, 6, 27, 0, 0)

3)pandas處理成組日期

pandas通常用於處理成組日期,不管這些日期是DataFrame的軸索引還是列,to_datetime方法可以解析多種不同的日期表示形式。

date
    ['2017-6-26', '2017-6-27']
import pandas as pd

pd.to_datetime(date)
    DatetimeIndex(['2017-06-26', '2017-06-27'], dtype='datetime64[ns]', freq=None)

datetime 格式定義

程式碼 說明
%Y 4位數的年
%y 2位數的年
%m 2位數的月[01,12]
%d 2位數的日[01,31]
%H 時(24小時制)[00,23]
%l 時(12小時制)[01,12]
%M 2位數的分[00,59]
%S 秒[00,61]有閏秒的存在
%w 用整數表示的星期幾[0(星期天),6]
%F %Y-%m-%d簡寫形式例如,2017-06-27
%D %m/%d/%y簡寫形式

pandas時間序列基礎以及時間、日期處理

pandas最基本的時間序列型別就是以時間戳(時間點)(通常以python字串或datetime物件表示)為索引的Series:

dates = ['2017-06-20','2017-06-21',\
         '2017-06-22','2017-06-23','2017-06-24','2017-06-25','2017-06-26','2017-06-27']
import numpy as np
ts = pd.Series(np.random.randn(8),index = pd.to_datetime(dates))
ts
    2017-06-20    0.788811
    2017-06-21    0.372555
    2017-06-22    0.009967
    2017-06-23   -1.024626
    2017-06-24    0.981214
    2017-06-25    0.314127
    2017-06-26   -0.127258
    2017-06-27    1.919773
    dtype: float64
ts.index
    DatetimeIndex(['2017-06-20', '2017-06-21', '2017-06-22', '2017-06-23',
                   '2017-06-24', '2017-06-25', '2017-06-26', '2017-06-27'],
                  dtype='datetime64[ns]', freq=None)

pandas不同索引的時間序列之間的算術運算會自動按日期對齊

ts[::2]#從前往後每隔兩個取資料
    2017-06-20    0.788811
    2017-06-22    0.009967
    2017-06-24    0.981214
    2017-06-26   -0.127258
    dtype: float64
ts[::-2]#從後往前逆序每隔兩個取資料
    2017-06-27    1.919773
    2017-06-25    0.314127
    2017-06-23   -1.024626
    2017-06-21    0.372555
    dtype: float64
ts + ts[::2]#自動資料對齊
    2017-06-20    1.577621
    2017-06-21         NaN
    2017-06-22    0.019935
    2017-06-23         NaN
    2017-06-24    1.962429
    2017-06-25         NaN
    2017-06-26   -0.254516
    2017-06-27         NaN
    dtype: float64

索引為日期的Series和DataFrame資料的索引、選取以及子集構造

方法:
1).index[number_int]

2)[一個可以被解析為日期的字串]

3)對於,較長的時間序列,只需傳入‘年’或‘年月’可返回對應的資料切片

4)通過時間範圍進行切片索引

ts
    2017-06-20    0.788811
    2017-06-21    0.372555
    2017-06-22    0.009967
    2017-06-23   -1.024626
    2017-06-24    0.981214
    2017-06-25    0.314127
    2017-06-26   -0.127258
    2017-06-27    1.919773
    dtype: float64
ts[ts.index[2]]
    0.0099673896063391908
ts['2017-06-21']#傳入可以被解析成日期的字串
    0.37255538918121028
ts['21/06/2017']
    0.37255538918121028
ts['20170621']
    0.37255538918121028
ts['2017-06']#傳入年或年月
    2017-06-20    0.788811
    2017-06-21    0.372555
    2017-06-22    0.009967
    2017-06-23   -1.024626
    2017-06-24    0.981214
    2017-06-25    0.314127
    2017-06-26   -0.127258
    2017-06-27    1.919773
    dtype: float64
ts['2017-06-20':'2017-06-23']#時間範圍進行切片
    2017-06-20    0.788811
    2017-06-21    0.372555
    2017-06-22    0.009967
    2017-06-23   -1.024626
    dtype: float64

帶有重複索引的時間序列

1).index.is_unique檢查索引日期是否是唯一的

2)對非唯一時間戳的資料進行聚合,通過groupby,並傳入level = 0(索引的唯一一層)

dates = pd.DatetimeIndex(['2017/06/01','2017/06/02','2017/06/02','2017/06/02','2017/06/03'])
dates
    DatetimeIndex(['2017-06-01', '2017-06-02', '2017-06-02', '2017-06-02',
                   '2017-06-03'],
                  dtype='datetime64[ns]', freq=None)
dup_ts = pd.Series(np.arange(5),index = dates)
dup_ts
    2017-06-01    0
    2017-06-02    1
    2017-06-02    2
    2017-06-02    3
    2017-06-03    4
    dtype: int32
dup_ts.index.is_unique
    False
dup_ts['2017-06-02']
    2017-06-02    1
    2017-06-02    2
    2017-06-02    3
    dtype: int32
grouped = dup_ts.groupby(level=0).mean()
grouped
    2017-06-01    0
    2017-06-02    2
    2017-06-03    4
    dtype: int32
dup_df = pd.DataFrame(np.arange(10).reshape((5,2)),index = dates )
dup_df
0 1
2017-06-01 0 1
2017-06-02 2 3
2017-06-02 4 5
2017-06-02 6 7
2017-06-03 8 9
grouped_df = dup_df.groupby(level=0).mean()##針對DataFrame
grouped_df
0 1
2017-06-01 0 1
2017-06-02 4 5
2017-06-03 8 9

總結

該篇部落格主要內容:

1)字串、日期的轉換方法

2)日期和時間的主要python,datetime、timedelta、pandas.to_datetime等

3)以時間為索引的Series和DataFrame的索引、切片

4)帶有重複時間索引時的索引,.groupby(level=0)應用