1. 程式人生 > >python+pandas生成指定日期和重取樣

python+pandas生成指定日期和重取樣

python 日期的範圍、頻率、重取樣以及頻率轉換

pandas有一整套的標準時間序列頻率以及用於重取樣、頻率推斷、生成固定頻率日期範圍的工具。

生成指定日期範圍的範圍

pandas.date_range()用於生成指定長度的DatatimeIndex:

1)預設情況下,date_range會按著時間間隔為天的方式生成從給定開始到結束時間的時間戳陣列;

2)如果只指定開始或結束時間,還需要periods標定時間長度。

import pandas as pd
pd.date_range('2017-6-20','2017-6-27')
    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='D')
pd.date_range('2017-6-20 12:59:30','2017-6-27')
    DatetimeIndex(['2017-06-20 12:59:30', '2017-06-21 12:59:30',
                   '2017-06-22 12:59:30'
, '2017-06-23 12:59:30', '2017-06-24 12:59:30', '2017-06-25 12:59:30', '2017-06-26 12:59:30'], dtype='datetime64[ns]', freq='D')
pd.date_range('2017-6-20 12:59:30',periods = 8)
    DatetimeIndex(['2017-06-20 12:59:30', '2017-06-21 12:59:30',
                   '2017-06-22 12:59:30'
, '2017-06-23 12:59:30', '2017-06-24 12:59:30', '2017-06-25 12:59:30', '2017-06-26 12:59:30', '2017-06-27 12:59:30'], dtype='datetime64[ns]', freq='D')
pd.date_range('2017-6-20 12:59:30',periods = 8, normalize = True)
    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='D')

頻率和日期偏移量

pandas中的頻率是由一個基礎頻率(M、H)也可以是(Hour、Minute、h、min等)

pd.date_range('2017-6-27',periods = 7,freq = '1h30min')
    DatetimeIndex(['2017-06-27 00:00:00', '2017-06-27 01:30:00',
                   '2017-06-27 03:00:00', '2017-06-27 04:30:00',
                   '2017-06-27 06:00:00', '2017-06-27 07:30:00',
                   '2017-06-27 09:00:00'],
                  dtype='datetime64[ns]', freq='90T')
pd.date_range('2017-6-27',periods = 7,freq = 'M')
    DatetimeIndex(['2017-06-30', '2017-07-31', '2017-08-31', '2017-09-30',
                   '2017-10-31', '2017-11-30', '2017-12-31'],
                  dtype='datetime64[ns]', freq='M')
pd.date_range('2017-6-27',periods = 7,freq = 'd')
    DatetimeIndex(['2017-06-27', '2017-06-28', '2017-06-29', '2017-06-30',
                   '2017-07-01', '2017-07-02', '2017-07-03'],
                  dtype='datetime64[ns]', freq='D')
pd.date_range('2017-6-27',periods = 7,freq = 'H')
    DatetimeIndex(['2017-06-27 00:00:00', '2017-06-27 01:00:00',
                   '2017-06-27 02:00:00', '2017-06-27 03:00:00',
                   '2017-06-27 04:00:00', '2017-06-27 05:00:00',
                   '2017-06-27 06:00:00'],
                  dtype='datetime64[ns]', freq='H')

常用的基礎頻率

別名 偏移量 說明
D/d Day 每日曆日
B BusinessDay 每工作日
H/h Hour 每小時
T或min Minute 每分
S Secend 每秒
L或ms Milli 每毫秒(每千分之一秒)
U Micro 每微秒(即百萬分之一秒)
M MonthEnd 每月最後一個日曆日
BM BusinessDayEnd 每月最後一個工作

上表只展示了部分!

WOM日期(可獲得例如“每月第3個星期五”)

pd.date_range('2017-06-01','2017-07-31',freq='WOM-3FRI')
    DatetimeIndex(['2017-06-16', '2017-07-21'], dtype='datetime64[ns]', freq='WOM-3FRI')

重取樣及頻率轉換

降取樣:高頻資料到低頻資料

升取樣:低頻資料到高頻資料

主要函式:resample()(pandas物件都會有這個方法)

resample方法的引數

引數 說明
freq 表示重取樣頻率,例如‘M’、‘5min’,Second(15)
how=’mean’ 用於產生聚合值的函式名或陣列函式,例如‘mean’、‘ohlc’、np.max等,預設是‘mean’,其他常用的值由:‘first’、‘last’、‘median’、‘max’、‘min’
axis=0 預設是縱軸,橫軸設定axis=1
fill_method = None 升取樣時如何插值,比如‘ffill’、‘bfill’等
closed = ‘right’ 在降取樣時,各時間段的哪一段是閉合的,‘right’或‘left’,預設‘right’
label= ‘right’ 在降取樣時,如何設定聚合值的標籤,例如,9:30-9:35會被標記成9:30還是9:35,預設9:35
loffset = None 面元標籤的時間校正值,比如‘-1s’或Second(-1)用於將聚合標籤調早1秒
limit=None 在向前或向後填充時,允許填充的最大時期數
kind = None 聚合到時期(‘period’)或時間戳(‘timestamp’),預設聚合到時間序列的索引型別
convention = None 當重取樣時期時,將低頻率轉換到高頻率所採用的約定(start或end)。預設‘end’

降取樣

需考慮:

1)各區間哪邊是閉合的(引數:closed)

2)如何標記各聚合面元,用區間的開頭還是末尾(引數:label)

ts_index = pd.date_range('2017-06-20',periods =12,freq = '1min')#一分鐘取樣資料

ts = pd.Series(np.arange(12),index = ts_index)
ts
    2017-06-20 00:00:00     0
    2017-06-20 00:01:00     1
    2017-06-20 00:02:00     2
    2017-06-20 00:03:00     3
    2017-06-20 00:04:00     4
    2017-06-20 00:05:00     5
    2017-06-20 00:06:00     6
    2017-06-20 00:07:00     7
    2017-06-20 00:08:00     8
    2017-06-20 00:09:00     9
    2017-06-20 00:10:00    10
    2017-06-20 00:11:00    11
    Freq: T, dtype: int32

聚合到5分鐘

ts.resample('5min',how='sum')
    C:\Program Files\anaconda\lib\site-packages\ipykernel\__main__.py:1: FutureWarning: how in .resample() is deprecated
    the new syntax is .resample(...).sum()
      if __name__ == '__main__':

    2017-06-20 00:00:00    10
    2017-06-20 00:05:00    35
    2017-06-20 00:10:00    21
    Freq: 5T, dtype: int32
ts.resample('5min',how='sum',closed='left')
    C:\Program Files\anaconda\lib\site-packages\ipykernel\__main__.py:1: FutureWarning: how in .resample() is deprecated
    the new syntax is .resample(...).sum()
      if __name__ == '__main__':

    2017-06-20 00:00:00    10
    2017-06-20 00:05:00    35
    2017-06-20 00:10:00    21
    Freq: 5T, dtype: int32
ts.resample('5min',how='sum',closed='left',label ='left')
    C:\Program Files\anaconda\lib\site-packages\ipykernel\__main__.py:1: FutureWarning: how in .resample() is deprecated
    the new syntax is .resample(...).sum()
      if __name__ == '__main__':

    2017-06-20 00:00:00    10
    2017-06-20 00:05:00    35
    2017-06-20 00:10:00    21
    Freq: 5T, dtype: int32

通過groupby進行重插樣

另外一種降取樣方法

ts1_index = pd.date_range('2017-6-01',periods = 100,freq = 'd')

ts1 = pd.Series(np.arange(100),index = ts1_index)
ts1.head()
    2017-06-01    0
    2017-06-02    1
    2017-06-03    2
    2017-06-04    3
    2017-06-05    4
    Freq: D, dtype: int32
ts1.groupby(lambda x:x.month).mean()
    6    14.5
    7    45.0
    8    76.0
    9    95.5
    dtype: float64
ts1.groupby(lambda x:x.weekday).mean()
    0    49.5
    1    50.5
    2    51.5
    3    49.0
    4    50.0
    5    47.5
    6    48.5
    dtype: float64
df1 = pd.DataFrame(np.arange(200).reshape(100,2),index = ts1_index)
df1.groupby(lambda x:x.weekday).mean()
0 1
0 99 100
1 101 102
2 103 104
3 98 99
4 100 101
5 95 96
6 97 98

對於具有時間序列索引的pandas資料結構,當groupby傳入一個函式時,可以對時間索引對應列進行聚合

升取樣

升取樣沒有聚合,但是需要填充

df2 = pd.DataFrame(np.arange(200).reshape(100,2),index = ts1_index,columns=['add1','add2'])
df2.head()
add1 add2
2017-06-01 0 1
2017-06-02 2 3
2017-06-03 4 5
2017-06-04 6 7
2017-06-05 8 9
df2.resample('W-THU',fill_method = 'ffill')
    C:\Program Files\anaconda\lib\site-packages\ipykernel\__main__.py:1: FutureWarning: fill_method is deprecated to .resample()
    the new syntax is .resample(...).ffill()
      if __name__ == '__main__':
add1 add2
2017-06-01 0 1
2017-06-08 14 15
2017-06-15 28 29
2017-06-22 42 43
2017-06-29 56 57
2017-07-06 70 71
2017-07-13 84 85
2017-07-20 98 99
2017-07-27 112 113
2017-08-03 126 127
2017-08-10 140 141
2017-08-17 154 155
2017-08-24 168 169
2017-08-31 182 183
2017-09-07 196 197
2017-09-14 198 199

總結

本篇部落格主要內容:

1)生成指定時間段,指定頻率的日期

2)對含有時間索引的pandas資料進行重取樣,包括降取樣和升取樣等。