1. 程式人生 > >Pandas日期資料處理:如何按日期篩選、顯示及統計資料

Pandas日期資料處理:如何按日期篩選、顯示及統計資料

前言

pandas有著強大的日期資料處理功能,本期我們來了解下pandas處理日期資料的一些基本功能,主要包括以下三個方面:

  • 按日期篩選資料
  • 按日期顯示資料
  • 按日期統計資料

執行環境為 windows系統,64位,python3.5。

1 讀取並整理資料

  • 首先引入pandas庫
    import pandas as pd
    
  • 從csv檔案中讀取資料
df = pd.read_csv(‘date.csv‘, header=None)
print(df.head(2))
            0  1
0  2013-10-24  3
1  2013-10-25  4
  • 整理資料
df.columns = [‘date‘,‘number‘]
df[‘date‘] = pd.to_datetime(df[‘date‘]) #將資料型別轉換為日期型別
df = df.set_index(‘date‘) # 將date設定為index
print(df.head(2))
print(df.tail(2))
print(df.shape)
            number
date              
2013-10-24       3
2013-10-25       4
            number
date              
2017-02-14       6
2017-02-22       6
(425, 1)
  • df的行數一共是425行。

檢視Dataframe的資料型別

print(type(df))
print(df.index)
print(type(df.index))
<class ‘pandas.core.frame.DataFrame‘>
DatetimeIndex([‘2013-10-24‘, ‘2013-10-25‘, ‘2013-10-29‘, ‘2013-10-30‘,
               ‘2013-11-04‘, ‘2013-11-06‘, ‘2013-11-08‘, ‘2013-11-12‘,
               ‘2013-11-14‘, ‘2013-11-25‘,
               ...
               ‘2017-01-03‘, ‘2017-01-07‘, ‘2017-01-14‘, ‘2017-01-17‘,
               ‘2017-01-23‘, ‘2017-01-25‘, ‘2017-01-26‘, ‘2017-02-07‘,
               ‘2017-02-14‘, ‘2017-02-22‘],
              dtype=‘datetime64[ns]‘, name=‘date‘, length=425, freq=None)
<class ‘pandas.tseries.index.DatetimeIndex‘>

構造Series型別資料

s = pd.Series(df[‘number‘], index=df.index)
print(type(s))
s.head(2)
<class ‘pandas.core.series.Series‘>

date
2013-10-24    3
2013-10-25    4
Name: number, dtype: int64

2 按日期篩選資料

按年度獲取資料

print(‘---------獲取2013年的資料-----------‘)
print(df[‘2013‘].head(2)) # 獲取2013年的資料
print(df[‘2013‘].tail(2)) # 獲取2013年的資料
---------獲取2013年的資料-----------
            number
date              
2013-10-24       3
2013-10-25       4
            number
date              
2013-12-27       2
2013-12-30       2

獲取2016至2017年的資料

print(‘---------獲取2016至2017年的資料-----------‘)
print(df[‘2016‘:‘2017‘].head(2))  #獲取2016至2017年的資料
print(df[‘2016‘:‘2017‘].tail(2))  #獲取2016至2017年的資料
---------獲取2016至2017年的資料-----------
            number
date              
2016-01-04       4
2016-01-07       6
            number
date              
2017-02-14       6
2017-02-22       6

獲取某月的資料

print(‘---------獲取某月的資料-----------‘)
print(df[‘2013-11‘]) # 獲取某月的資料
---------獲取某月的資料-----------
            number
date              
2013-11-04       1
2013-11-06       3
2013-11-08       1
2013-11-12       5
2013-11-14       2
2013-11-25       1
2013-11-29       1

獲取具體某天的資料

  • 請注意dataframe型別的資料,獲取具體某天的資料時,跟series是有些差異的,詳細情況如下述程式碼所示:
# 按日期篩選資料
print(‘---------獲取具體某天的資料-----------‘)
# 獲取具體某天的資料
print(s[‘2013-11-06‘])

# 獲取具體某天的資料,用datafrme直接選取某天時會報錯,而series的資料就沒有問題
# print(df[‘2013-11-06‘])

#可以考慮用區間來獲取某天的資料
print(df[‘2013-11-06‘:‘2013-11-06‘])
---------獲取具體某天的資料-----------
3
            number
date              
2013-11-06       3
  • dataframe的truncate函式可以獲取某個時期之前或之後的資料,或者某個時間區間的資料
  • 但一般建議直接用切片(slice),這樣更為直觀,方便
# dataframe的truncate函式可以獲取某個時期之前或之後的資料,或者某個時間區間的資料
# 但一般建議直接用切片(slice),這樣更為直觀,方便
print(‘---------獲取某個時期之前或之後的資料-----------‘)
print(‘--------after------------‘)
print(df.truncate(after = ‘2013-11‘))
print(‘--------before------------‘)
print(df.truncate(before=‘2017-02‘))
---------獲取某個時期之前或之後的資料-----------
--------after------------
            number
date              
2013-10-24       3
2013-10-25       4
2013-10-29       2
2013-10-30       1
--------before------------
            number
date              
2017-02-07       8
2017-02-14       6
2017-02-22       6

3 按日期顯示資料

3.1 to_period()方法

  • 請注意df.index的資料型別是DatetimeIndex;
  • df_peirod的資料型別是PeriodIndex

按月顯示,但不統計

df_period = df.to_period(‘M‘) #按月顯示,但不統計
print(type(df_period))

print(type(df_period.index))
# 請注意df.index的資料型別是DatetimeIndex;
# df_peirod的資料型別是PeriodIndex

print(df_period.head())
<class ‘pandas.core.frame.DataFrame‘>
<class ‘pandas.tseries.period.PeriodIndex‘>
         number
date           
2013-10       3
2013-10       4
2013-10       2
2013-10       1
2013-11       1

按季度顯示,但不統計

print(df.to_period(‘Q‘).head()) #按季度顯示,但不統計
        number
date          
2013Q4       3
2013Q4       4
2013Q4       2
2013Q4       1
2013Q4       1

按年度顯示,但不統計

print(df.to_period(‘A‘).head()) #按年度顯示,但不統計
      number
date        
2013       3
2013       4
2013       2
2013       1
2013       1

3.2 asfreq()方法

按年度頻率顯示

df_period.index.asfreq(‘A‘) # ‘A‘預設是‘A-DEC‘,其他如‘A-JAN‘
PeriodIndex([‘2013‘, ‘2013‘, ‘2013‘, ‘2013‘, ‘2013‘, ‘2013‘, ‘2013‘, ‘2013‘,
             ‘2013‘, ‘2013‘,
             ...
             ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘,
             ‘2017‘, ‘2017‘],
            dtype=‘period[A-DEC]‘, name=‘date‘, length=425, freq=‘A-DEC‘)
df_period.index.asfreq(‘A-JAN‘) # ‘A‘預設是‘A-DEC‘,其他如‘A-JAN‘
PeriodIndex([‘2014‘, ‘2014‘, ‘2014‘, ‘2014‘, ‘2014‘, ‘2014‘, ‘2014‘, ‘2014‘,
             ‘2014‘, ‘2014‘,
             ...
             ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2017‘, ‘2018‘,
             ‘2018‘, ‘2018‘],
            dtype=‘period[A-JAN]‘, name=‘date‘, length=425, freq=‘A-JAN‘)
  • 按年度頻率在不同情形下的顯示,可參考下圖所示:技術分享

按季度頻率顯示

df_period.index.asfreq(‘Q‘) # ‘Q‘預設是‘Q-DEC‘,其他如“Q-SEP”,“Q-FEB”
PeriodIndex([‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘,
             ‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘, ‘2013Q4‘,
             ...
             ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘,
             ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘, ‘2017Q1‘],
            dtype=‘period[Q-DEC]‘, name=‘date‘, length=425, freq=‘Q-DEC‘)
df_period.index.asfreq(‘Q-SEP‘) # 可以顯示不同的季度財年,“Q-SEP”,“Q-FEB”
# df_period.index = df_period.index.asfreq(‘Q-DEC‘) # 可以顯示不同的季度財年,“Q-SEP”,“Q-FEB”
# print(df_period.head())
PeriodIndex([‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘,
             ‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘, ‘2014Q1‘,
             ...
             ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘,
             ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘, ‘2017Q2‘],
            dtype=‘period[Q-SEP]‘, name=‘date‘, length=425, freq=‘Q-SEP‘)
  • 按季度頻率在不同情形下的顯示,可參考下圖所示:技術分享

按月度頻率顯示

df_period.index.asfreq(‘M‘) # 按月份顯示
PeriodIndex([‘2013-10‘, ‘2013-10‘, ‘2013-10‘, ‘2013-10‘, ‘2013-11‘, ‘2013-11‘,
             ‘2013-11‘, ‘2013-11‘, ‘2013-11‘, ‘2013-11‘,
             ...
             ‘2017-01‘, ‘2017-01‘, ‘2017-01‘, ‘2017-01‘, ‘2017-01‘, ‘2017-01‘,
             ‘2017-01‘, ‘2017-02‘, ‘2017-02‘, ‘2017-02‘],
            dtype=‘period[M]‘, name=‘date‘, length=425, freq=‘M‘)

按工作日顯示

  • method 1
df_period.index.asfreq(‘B‘, how=‘start‘) # 按工作日期顯示
PeriodIndex([‘2013-10-01‘, ‘2013-10-01‘, ‘2013-10-01‘, ‘2013-10-01‘,
             ‘2013-11-01‘, ‘2013-11-01‘, ‘2013-11-01‘, ‘2013-11-01‘,
             ‘2013-11-01‘, ‘2013-11-01‘,
             ...
             ‘2017-01-02‘, ‘2017-01-02‘, ‘2017-01-02‘, ‘2017-01-02‘,
             ‘2017-01-02‘, ‘2017-01-02‘, ‘2017-01-02‘, ‘2017-02-01‘,
             ‘2017-02-01‘, ‘2017-02-01‘],
            dtype=‘period[B]‘, name=‘date‘, length=425, freq=‘B‘)
  • method 2
df_period.index.asfreq(‘B‘, how=‘end‘) # 按工作日期顯示
PeriodIndex([‘2013-10-31‘, ‘2013-10-31‘, ‘2013-10-31‘, ‘2013-10-31‘,
             ‘2013-11-29‘, ‘2013-11-29‘, ‘2013-11-29‘, ‘2013-11-29‘,
             ‘2013-11-29‘, ‘2013-11-29‘,
             ...
             ‘2017-01-31‘, ‘2017-01-31‘, ‘2017-01-31‘, ‘2017-01-31‘,
             ‘2017-01-31‘, ‘2017-01-31‘, ‘2017-01-31‘, ‘2017-02-28‘,
             ‘2017-02-28‘, ‘2017-02-28‘],
            dtype=‘period[B]‘, name=‘date‘, length=425, freq=‘B‘)

4 按日期統計資料

4.1按日期統計資料

按周統計資料

print(df.resample(‘w‘).sum().head())
# “w”,week
            number
date              
2013-10-27     7.0
2013-11-03     3.0
2013-11-10     5.0
2013-11-17     7.0
2013-11-24     NaN

按月統計資料

print(df.resample(‘M‘).sum().head())
# "MS"是每個月第一天為開始日期, "M"是每個月最後一天
            number
date              
2013-10-31      10
2013-11-30      14
2013-12-31      27
2014-01-31      16
2014-02-28       4

按季度統計資料

print(df.resample(‘Q‘).sum().head())
# "QS"是每個季度第一天為開始日期, "Q"是每個季度最後一天
            number
date              
2013-12-31      51
2014-03-31      73
2014-06-30      96
2014-09-30     136
2014-12-31     148

按年統計資料


print(df.resample(‘AS‘).sum())
# "AS"是每年第一天為開始日期, "A是每年最後一天
            number
date              
2013-01-01      51
2014-01-01     453
2015-01-01     743
2016-01-01    1552
2017-01-01      92
  • 關於日期的型別,按參考下圖所示來選擇合適的分期頻率:技術分享

4.2 按日期統計後,按年或季度或月份顯示

按年統計並顯示

print(df.resample(‘AS‘).sum().to_period(‘A‘))
# 按年統計並顯示
      number
date        
2013      51
2014     453
2015     743
2016    1552
2017      92

按季度統計並顯示

print(df.resample(‘Q‘).sum().to_period(‘Q‘).head())
# 按季度統計並顯示
        number
date          
2013Q4      51
2014Q1      73
2014Q2      96
2014Q3     136
2014Q4     148

按月度統計並顯示

print(df.resample(‘M‘).sum().to_period(‘M‘).head())
# 按月度統計並顯示
         number
date           
2013-10      10
2013-11      14
2013-12      27
2014-01      16
2014-02       4