pandas之時間操作


顧名思義,時間序列(time series),就是由時間構成的序列,它指的是在一定時間內按照時間順序測量的某個變量的取值序列,比如一天內的溫度會隨時間而發生變化,或者股票的價格會隨着時間不斷的波動,這里用到的一系列時間,就可以看做時間序列。時間序列包含三種應用場景,分別是:

  • 特定的時刻(timestamp),也就是時間戳;
  • 固定的日期(period),比如某年某月某日;
  • 時間間隔(interval),每隔一段時間具有規律性;


在處理時間序列的過程中,我們一般會遇到兩個問題,第一,如何創建時間序列;第二,如何更改已生成時間序列的頻率。 Pandas 為解決上述問題提供了一套簡單、易用的方法。

下面用 Python 內置的 datetime 模塊來獲取當前時間,通過該模塊提供的now()方法即可實現。

  1. from datetime import datetime
  2. #數據類型為datetime
  3. print(datetime.now())

輸出結果:

2020-12-16 16:36:18.791297

創建時間戳

TimeStamp(時間戳) 是時間序列中的最基本的數據類型,它將數值與時間點完美結合在一起。Pandas 使用下列方法創建時間戳:

  1. import pandas as pd
  2. print (pd.Timestamp('2017-03-01'))

輸出結果:

2017-03-01 00:00:00

同樣,可以將整型或浮點型表示的時間轉換為時間戳。默認的單位是納秒(時間戳單位),示例如下:

  1. import pandas as pd
  2. print(pd.Timestamp(1587687255,unit='s'))

輸出結果:

2022-03-19 14:26:39

創建時間范圍

通過 date_range() 方法可以創建某段連續的時間或者固定間隔的時間時間段。該函數提供了三個參數,分別是:

  • start:開始時間
  • end:結束時間
  • freq:時間頻率,默認為 "D"(天)


示例如下:

  1. import pandas as pd
  2. #freq表示時間頻率,每30min變化一次
  3. print(pd.date_range("9:00", "18:10", freq="30min").time)

輸出結果:

[datetime.time(9, 0) datetime.time(9, 30) datetime.time(10, 0)
datetime.time(10, 30) datetime.time(11, 0) datetime.time(11, 30)
datetime.time(12, 0) datetime.time(12, 30) datetime.time(13, 0)
datetime.time(13, 30) datetime.time(14, 0) datetime.time(14, 30)
datetime.time(15, 0) datetime.time(15, 30) datetime.time(16, 0)
datetime.time(16, 30) datetime.time(17, 0) datetime.time(17, 30)
datetime.time(18, 0)]

更改時間頻率

  1. import pandas as pd
  2. #修改為按小時
  3. print(pd.date_range("6:10", "11:45", freq="H").time)

輸出結果:

[datetime.time(6, 10) datetime.time(7, 10) datetime.time(8, 10)
datetime.time(9, 10) datetime.time(10, 10) datetime.time(11, 10)]

轉化為時間戳

您可以使用 to_datetime() 函數將 series 或 list 轉換為日期對象,其中 list 會轉換為DatetimeIndex。示例如下:

  1. import pandas as pd
  2. print(pd.to_datetime(pd.Series(['Jun 3, 2020','2020-12-10', None])))

輸出結果:

  1. 0 2020-06-03
  2. 1 2020-12-10
  3. 2 NaT
  4. dtype: datetime64[ns]

注意:NaT 表示的不是時間 ,它等效於 NaN。

最后再來看一個示例:

  1. import pandas as pd
  2. #傳入list,生成Datetimeindex
  3. print(pd.to_datetime(['Jun 31, 2020','2020-12-10', None]))

輸出結果:

DatetimeIndex(['2020-06-03', '2020-12-10', 'NaT'], dtype='datetime64[ns]', freq=None)

頻率和周期轉換

Time Periods 表示時間跨度,一段時間周期,它被定義在 Pandas Periods 類中,通過該類提供的方法可以實現將頻率轉換為周期。比如 Periods() 方法,可以將頻率 "M"(月)轉換為 Period(時間段)。

下面示例,使用 asfreq() 和 start 參數,打印 "01" ,若使用 end 參數,則打印 "31"。示例如下:

  1. import pandas as pd
  2. x = pd.Period('2014', freq='M')
  3. #start參數
  4. x.asfreq('D', 'start')
  5. #end參數
  6. x.asfreq('D', 'end')

輸出結果:

Period('2014-01-01', 'D')
Period('2014-01-31', 'D')

對於常用的時間序列頻率,Pandas 為其規定了一些字符串別名,我們將這些別名稱為“offset(偏移量)”。如下表所示:

別名 描述 別名 描述
B 工作日頻率 BQS 工作季度開始頻率
D 日歷日頻率 A 年終頻率
W 每周頻率 BA 工作年度結束頻率
M 月末頻率 BAS 工作年度開始頻率
SM 半月結束頻率 BH 營業時間頻率
BM 工作月結束頻率 H 小時頻率
MS 月開始頻率 T,min 每分鍾頻率
SMS 半月開始頻率 S 每秒鍾頻率
BMS 工作月開始頻率 L,ms 毫秒
Q 季末頻率 U,us 微妙
BQ 工作季度結束頻率 N 納秒
QS 季度開始頻率    

時間周期計算

周期計算,指的是對時間周期進行算術運算,所有的操作將在“頻率”的基礎上執行。

  1. import pandas as pd
  2. #S表示秒
  3. x = pd.Period('2014', freq='S')
  4. x

輸出結果:

Period('2014-01-01 00:00:00', 'S')

執行計算示例:

  1. import pandas as pd
  2. x = pd.Period('2014', freq='S')
  3. #加1s的時間
  4. print(x+1)

輸出結果:

Period('2014-01-01 00:00:01', 'S')

再看一組完整的示例:

  1. #定義時期period,默認freq="Y"年份
  2. p1=pd.Period('2020')
  3. p2=pd.Period('2019')
  4. #使用f''格式化輸出
  5. print(f'p1={p1}年')
  6. print(f'p2={p2}年')
  7. print(f'p1和p2間隔{p1-p2}年')
  8. #f''表示字符串格式化輸出
  9. print(f'五年前是{p1-5}年')

輸出結果:

p1=2020年
p2=2019年
p1和p2間隔<YearEnd: month=12>年
五年前是2015年

創建時間周期

我們可以使用 period_range() 方法來創建時間周期范圍。示例如下:

  1. import pandas as pd
  2. #Y表示年
  3. p = pd.period_range('2016','2018', freq='Y')
  4. p

輸出結果:

PeriodIndex(['2016', '2017', '2018'], dtype='period[A-DEC]', freq='A-DEC')

時間序列轉換

如果想要把字符串日期轉換為 Period,首先需要將字符串轉換為日期格式,然后再將日期轉換為 Period。示例如下:

  1. # 創建時間序列
  2. index=pd.date_range("2020-03-17","2020-03-30",freq="1.5H")
  3. #隨機選取4個互不相同的數
  4. loc=np.random.choice(np.arange(len(index)),size=4,replace=False)
  5. loc.sort()
  6. ts_index=index[loc]
  7. ts_index
  8. pd_index=ts_index.to_periods('D')
  9. pd_index()

輸出結果:

DatetimeIndex(['2020-03-17 12:00:00', '2020-03-22 04:30:00',
               '2020-03-27 03:00:00', '2020-03-30 00:00:00'],
              dtype='datetime64[ns]', freq=None)

PeriodIndex(['2020-03-17', '2020-03-19', '2020-03-19', '2020-03-27'], dtype='period[D]', freq='D')

使用 to_timestamp() 能夠將 Period 時期轉換為時間戳(timestamp),示例如下:

  1. import pandas as pd
  2. p1=pd.Periods("2020-2-3")
  3. p1.to_timestamp()

輸出結果:

Timestamp('2020-02-03 00:00:00')

創建日期范圍

Pandas 提供了用來創建日期序列的函數 date_range(),該函數的默認頻率為 "D", 也就是“天”。日期序列只包含年、月、日,不包含時、分、秒。

下面是一組簡單的示例,如下所示:

  1. import pandas as pd
  2. print(pd.date_range('12/15/2020', periods=10))

輸出結果:

DatetimeIndex(['2020-12-15', '2020-12-16', '2020-12-17', '2020-12-18',
               '2020-12-19', '2020-12-20', '2020-12-21', '2020-12-22',
               '2020-12-23', '2020-12-24'],
              dtype='datetime64[ns]', freq='D')

當我們使用 date_range() 來創建日期范圍時,該函數包含結束的日期,用數學術語來說就是區間左閉右閉,即包含起始值,也包含結束值。示例如下:

  1. import pandas as pd
  2. #建議使用Python的datetime模塊創建時間
  3. start = pd.datetime(2019, 1, 1)
  4. end = pd.datetime(2019, 1, 5)
  5. print pd.date_range(start,end)

輸出結果:

DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04','2019-01-05']
,dtype='datetime64[ns]', freq='D')

更改日頻率

使用下列方法可以修改頻率,比如按“天”為按“月”,示例如下:

  1. import pandas as pd
  2. print(pd.date_range('12/15/2011', periods=5,freq='M'))

輸出結果:

DatetimeIndex(['2020-12-31', '2021-01-31', '2021-02-28', '2021-03-31',
               '2021-04-30'],dtype='datetime64[ns]', freq='M')

工作日時間

bdate_range() 表示創建工作日的日期范圍,它與 date_range() 不同,它不包括周六、周日。

  1. import pandas as pd
  2. print(pd.date_range('11/25/2020', periods=8))

輸出結果:

DatetimeIndex(['2020-11-25', '2020-11-26', '2020-11-27', '2020-11-28','2020-11-29', '2020-11-30', '2020-12-01', '2020-12-02'],dtype='datetime64[ns]', freq='D')

上述方法中,date_range() 默認頻率是日歷日,而 bdate_range() 的默認頻率是工作日。

 

----------------------------------------------------------------‘’

日期格式化符號

在對時間進行格式化處理時,它們都有固定的表示格式,比如小時的格式化符號為%H ,分鍾簡寫為%M ,秒簡寫為%S。下表對常用的日期格式化符號做了總結:

日期格式化符號
符號 說明
%y 兩位數的年份表示(00-99)
%Y 四位數的年份表示(000-9999)
%m 月份(01-12)
%d 月內中的一天(0-31)
%H 24小時制小時數(0-23)
%I 12小時制小時數(01-12)
%M 分鍾數(00=59)
%S 秒(00-59)
%a 本地英文縮寫星期名稱
%A 本地英文完整星期名稱
%b 本地縮寫英文的月份名稱
%B 本地完整英文的月份名稱
%w 星期(0-6),星期天為星期的開始
%W 一年中的星期數(00-53)星期一為星期的開始
%x 本地相應的日期表示
%X 本地相應的時間表示
%Z 當前時區的名稱
%U 一年中的星期數(00-53)星期天為星期的開始
%j 年內的一天(001-366)
%c 本地相應的日期表示和時間表示

Python處理

Python 內置的 strptime() 方法能夠將字符串日期轉換為 datetime 類型,下面看一組示例:

  1. from datetime import datetime
  2. #將日期定義為字符串
  3. date_str1 = 'Wednesday, July 18, 2020'
  4. date_str2 = '18/7/20'
  5. date_str3 = '18-07-2020'
  6. #將日期轉化為datetime對象
  7. dmy_dt1 = datetime.strptime(date_str1, '%A,%B%d,%Y')
  8. dmy_dt2 = datetime.strptime(date_str2, '%d/%m/%y')
  9. dmy_dt3 = datetime.strptime(date_str3, '%d-%m-%Y')
  10. #處理為相同格式,並打印輸出
  11. print(dmy_dt1)
  12. print(dmy_dt2)
  13. print(dmy_dt3)

輸出結果:

2020-07-18 00:00:00
2020-07-18 00:00:00
2020-07-18 00:00:00

注意:strftime() 可以將 datetime 類型轉換為字符串類型,恰好與 strptime() 相反。

Pandas處理

除了使用 Python 內置的 strptime() 方法外,你還可以使用 Pandas 模塊的 pd.to_datetime() 和 pd.DatetimeIndex() 進行轉換。

1) to_datetime()

通過 to_datetime() 直接轉換為 datetime 類型

  1. import pandas as pd
  2. import numpy as np
  3. date = ['2012-05-06 11:00:00','2012-05-16 11:00:00']
  4. pd_date=pd.to_datetime(date)
  5. df=pd.Series(np.random.randn(2),index=pd_date)

輸出結果:

2012-05-06 11:00:00    0.189865
2012-05-16 11:00:00    1.052456
dtype: float64

2) DatetimeIndex()

使用 Datetimeindex() 函數設置時間序,示例如下:

  1. date = pd.DatetimeIndex(['1/1/2008', '1/2/2008', '1/3/2008', '1/4/2008', '1/5/2008'])
  2. dt = pd.Series(np.random.randn(5),index = date)
  3. print(dt)

輸出結果:

2008-01-01    1.965619
2008-01-02   -2.897374
2008-01-03    0.625929
2008-01-04    1.204926
2008-01-05    1.755680
dtype: float6-----------------------------------------------------------
Timedelta 表示時間差(或者時間增量),我們可以使用不同的時間單位來表示它,比如,天、小時、分、秒。時間差的最終的結果可以是正時間差,也可以是負時間差。

本節主要介紹創建 Timedelta (時間差)的方法以及與時間差相關的運算法則。

字符串

通過傳遞字符串可以創建 Timedelta 對象,示例如下:
  1. import pandas as pd
  2. print(pd.Timedelta('5 days 8 hours 6 minutes 59 seconds'))
輸出結果:

5 days 08:06:59

整數

通過傳遞整數值和unit參數也可以創建一個 Timedelta 對象。
  1. import pandas as pd
  2. print(pd.Timedelta(19,unit='h'))
輸出結果:

0 days 19:00:00

數據偏移量

數據偏移量, 比如,周(weeks)、天(days)、小時(hours)、分鍾(minutes)、秒(milliseconds)、毫秒、微秒、納秒都可以使用。
  1. import pandas as pd
  2. print (pd.Timedelta(days=2,hours=6))
輸出結果:

2 days 06:00:00

to_timedelta()

您可以使用pd.to_timedelta()方法,將具有 timedelta 格式的值 (標量、數組、列表或 Series)轉換為 Timedelta 類型。如果輸入是 Series,則返回 Series;如果輸入是標量,則返回值也為標量,其他情況輸出 TimedeltaIndex。示例如下:
  1. import pandas as pd
  2. print(pd.to_timedelta(['1 days 06:05:01.00003', '15.5us', 'nan']))
  3. print(pd.to_timedelta(np.arange(5), unit='s'))
輸出結果:
TimedeltaIndex(['1 days 06:05:01.000030', '0 days 00:00:00.000015', NaT],dtype='timedelta64[ns]', freq=None)

TimedeltaIndex(['0 days 00:00:00', '0 days 00:00:01', '0 days 00:00:02','0 days 00:00:03', 
'0 days 00:00:04'],dtype='timedelta64[ns]', freq=None)

算術操作

通過對datetime64[ns]類型的時間序列或時間戳做算術運算,其運算結果依然是datetime64[ns]數據類型。接下來,我們創建一個帶有 Timedelta 與 datetime 的 DataFrame 對象,並對其做一些算術運算。
  1. import pandas as pd
  2. s = pd.Series(pd.date_range('2020-1-1', periods=5, freq='D'))
  3. #推導式用法
  4. td = pd.Series([ pd.Timedelta(days=i) for i in range(5)])
  5. df = pd.DataFrame(dict(A = s, B = td))
  6. print(df)
輸出結果:
           A      B
0 2020-01-01 0 days
1 2020-01-02 1 days
2 2020-01-03 2 days
3 2020-01-04 3 days
4 2020-01-05 4 days

加法運算

  1. import pandas as pd
  2. s = pd.Series(pd.date_range('20120-1-1', periods=3, freq='D'))
  3. td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ])
  4. df = pd.DataFrame(dict(A = s, B = td))
  5. #加法運算
  6. df['C']=df['A']+df['B']
  7. print(df)
輸出結果:
           A      B          C
0 2020-01-01 0 days 2020-01-01
1 2020-01-02 1 days 2020-01-03
2 2020-01-03 2 days 2020-01-05

減法運算

  1. import pandas as pd
  2. s = pd.Series(pd.date_range('2012-1-1', periods=3, freq='D'))
  3. td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ])
  4. df = pd.DataFrame(dict(A = s, B = td))
  5. df['C']=df['A']+df['B']
  6. df['D']=df['C']-df['B']
  7. print(df)
輸出結果:
           A      B          C          D
0 2019-01-01 0 days 2019-01-01 2019-01-01
1 2019-01-02 1 days 2019-01-03 2019-01-02
2 2019-01-03 2 days 2019-01-05 2019-01-03
------------------------------------------------------

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM