天天看點

python時間序列資料分析_python資料分析之:時間序列一

在處理很多資料的時候,我們都要用到時間的概念。比如時間戳,固定時期或者時間間隔。pandas提供了一組标準的時間序列處理工具和資料算法。

在python中datetime.datetime子產品是用的最多的子產品。比如使用datetime.datetime.now()就得到了目前的時間2018-04-14 14:12:31.888964。這個時間包含了年,月,日,小時,分鐘,秒,毫秒。

通過datetime子產品還可以得到兩個時間的時間差

t1=datetime(2018,4,11)

t2=datetime(2018,3,3)

print(t1-t2)

39 days, 0:00:00

也可以通過timedelta進行日期的運算

t1=datetime(2018,4,11)

delta=timedelta(12)

print(t1+delta)

結果:

2018-04-23 00:00:00

但是實際在代碼開發過程中,我們經常會遇到用字元串來表示時間,如何轉換成datetime子產品呢。這裡需要用打算哦strptime函數。

value='2018-4-12'

datetime.strptime(value,'%Y-%m-%d')

但是每次都需要用strptime來轉換時間太過于麻煩。而且很多時候有不同的時間表達式。比如‘Apri 12,2018’這種格式就無法通過strptime來轉換。這裡及需要用到dateutil中的parser方法

from dateutil.parser import parse

parse('April 12,2018 12:00 PM')

運作結果:

2018-04-12 12:00:00

還有下面的這種格式,如果設定dayfirst為True.那麼表示第一個表示日,而不是月

parse('12/4/2018',dayfirst=True)

2018-04-12 00:00:00

如果不設定,則表示第一個參數為月,

parse('12/4/2018')

2018-12-04 00:00:00

下面介紹pandas中如何處理日期

datestr=['4/12/2018','3/12/2018']

pd.to_datetime(datestr)

運作結果,得到的是一個datetime對象。

DatetimeIndex(['2018-04-12', '2018-03-12'], dtype='datetime64[ns]', freq=None)

時間序列:

pandas最基本的時間序列類型就是時間戳為索引的series

datestr=[datetime(2018,4,12),datetime(2018,4,11),datetime(2018,4,10),datetime(2018,4,9)]

ts=Series(np.random.randn(4),index=datestr)

2018-04-12 0.282997

2018-04-11 0.775905

2018-04-10 -1.039524

2018-04-09 1.946392

dtype: float64

索引,選取,子集

既然通過時間形成了時間序列。那麼也可以通過時間索引來的到對應的值。

stamp=ts.index[2]

ts[stamp]

對于時間較長的序列,比如持續100天或者跨度年,月。那麼index就可以通過pd.date_range的方法設定起始時間以及時間跨度。在這裡periods這裡就表示的是持續時間。

ts=Series(np.random.randn(100),index=pd.date_range('4/12/2018',periods=100))

得到從4月12号往後一白天的時間。

2018-04-12 -0.148937

2018-04-13 0.937058

2018-04-14 -2.096196

2018-04-15 0.916470

2018-04-16 -0.697598

2018-04-17 0.643925

2018-04-18 -0.307314

2018-04-19 -0.141321

2018-04-20 -0.175498

2018-04-21 -0.829793

2018-04-22 -0.024155

2018-04-23 -1.051386

2018-04-24 0.540014

2018-04-25 0.154808

2018-04-26 1.358971

2018-04-27 0.525493

2018-04-28 -0.669124

2018-04-29 -0.207421

2018-04-30 -0.228202

2018-05-01 0.816570

2018-05-02 -0.877241

2018-05-03 0.772659

2018-05-04 0.554481

2018-05-05 -0.714872

2018-05-06 1.773668

2018-05-07 0.326872

2018-05-08 -1.079632

2018-05-09 1.024192

2018-05-10 -0.646678

2018-05-11 -1.515030

...

2018-06-21 -0.053543

2018-06-22 2.118719

2018-06-23 0.106124

2018-06-24 0.659720

2018-06-25 -0.991692

2018-06-26 -0.556483

2018-06-27 -0.819689

2018-06-28 0.031711

2018-06-29 0.543342

2018-06-30 0.009368

2018-07-01 1.141678

2018-07-02 0.222943

2018-07-03 0.303460

2018-07-04 -0.815658

2018-07-05 1.291347

2018-07-06 -0.681728

2018-07-07 -0.327148

2018-07-08 1.385592

2018-07-09 1.302346

2018-07-10 1.179094

2018-07-11 -0.465722

2018-07-12 -0.351399

2018-07-13 0.059268

2018-07-14 -0.235086

2018-07-15 0.983399

2018-07-16 -1.767474

2018-07-17 0.596053

2018-07-18 -2.022643

2018-07-19 0.539513

2018-07-20 0.421791

Freq: D, Length: 100, dtype: float64

在上面生成的這個序列中,可以通過設定索引的到某一年或者某一月的資料。ts['2018-4']就可以得到4月份的資料。格式也可以是ts['2018/4']

通過下面的方式得到一段時間内的資料

ts['2018/4/12':'2018/4/23']

運作結果:

2018-04-12 -1.080229

2018-04-13 1.231485

2018-04-14 0.725456

2018-04-15 0.029311

2018-04-16 0.331900

2018-04-17 0.921682

2018-04-18 -0.822750

2018-04-19 -0.569305

2018-04-20 0.589461

2018-04-21 1.405626

2018-04-22 -0.049872

2018-04-23 -0.144766

Freq: D, dtype: float64

還可以通過truncate的方式得到某段時間前或者後的資料

ts.truncate(after='2018/4/15') #得到2018/4/15之前的資料

ts.truncate(before='2018/4/15') #得到2018/4/15之後的資料

前面設定的時間序列的間隔是天級的。如要設定間隔是月度或者是年度的間隔,就需要設定freq的值,D,M,Y反别代表日為間隔,月為間隔,年為間隔。

pd.date_range('4/12/2018',periods=100,freq='D')

pd.date_range('4/12/2018',periods=100,freq='M')

pd.date_range('4/12/2018',periods=100,freq='Y')

還有其他很多的參數設定。具體的參數設定如下:

python時間序列資料分析_python資料分析之:時間序列一
python時間序列資料分析_python資料分析之:時間序列一

帶有重複序列的時間序列

在有些應用場景中,可能會存在多個觀測資料落在同一個時間點的情況

dup_ts=Series(np.arange(4),index=dates)

2018-04-12 0

2018-04-13 1

2018-04-14 2

2018-04-14 3

dtype: int64

通過is_unique就可以得到是否是重複序列

dup_ts.index.is_unique

日期的範圍,頻率以及移動

pd.date_range('4/12/2018','5/12/2018')

得到4月12日到5月12日的日期。同樣的也可以設定freq來設定間隔

DatetimeIndex(['2018-04-12', '2018-04-13', '2018-04-14', '2018-04-15',

'2018-04-16', '2018-04-17', '2018-04-18', '2018-04-19',

'2018-04-20', '2018-04-21', '2018-04-22', '2018-04-23',

'2018-04-24', '2018-04-25', '2018-04-26', '2018-04-27',

'2018-04-28', '2018-04-29', '2018-04-30', '2018-05-01',

'2018-05-02', '2018-05-03', '2018-05-04', '2018-05-05',

'2018-05-06', '2018-05-07', '2018-05-08', '2018-05-09',

'2018-05-10', '2018-05-11', '2018-05-12'],

dtype='datetime64[ns]', freq='D')

如果想對生成的時間序列進行移位擷取。就要用到shift函數

ts=Series(np.random.randn(4),index=pd.date_range('4/12/2018',periods=4,freq='M'))

print(ts)

print(ts.shift(2))

結果如下,時間被移位,對應的資料也移位

2018-04-30 -0.065679

2018-05-31 -0.163013

2018-06-30 0.501377

2018-07-31 0.856595

Freq: M, dtype: float64

2018-04-30 NaN

2018-05-31 NaN

2018-06-30 -0.065679

2018-07-31 -0.163013

Freq: M, dtype: float64

由于單純的移位操作不會修改索引。是以部分資料會被丢棄。是以,如果頻率已知,則可以将其傳給shift可以實作時間戳進行位移而不是對資料進行簡機關移

ts.shift(2,freq='M')

2018-06-30 -0.235855

2018-07-31 1.189707

2018-08-31 0.005851

2018-09-30 -0.134599

Freq: M, dtype: float64