#!/usr/bin/env python # coding: utf-8 # # 11.2 Time Series Basics(时间序列基础) # # 在pandas中,一个基本的时间序列对象,是一个用时间戳作为索引的Series,在pandas外部的话,通常是用python 字符串或datetime对象来表示的: # In[4]: import pandas as pd import numpy as np from datetime import datetime # In[5]: dates = [datetime(2011, 1, 2), datetime(2011, 1, 5), datetime(2011, 1, 7), datetime(2011, 1, 8), datetime(2011, 1, 10), datetime(2011, 1, 12)] # In[6]: ts = pd.Series(np.random.randn(6), index=dates) ts # 上面的转化原理是,datetime对象被放进了DatetimeIndex: # In[7]: ts.index # 像其他的Series一行,数值原色会自动按时间序列索引进行对齐: # In[9]: ts[::2] # In[10]: ts + ts[::2] # ts[::2]会在ts中,每隔两个元素选一个元素。 # # pandas中的时间戳,是按numpy中的datetime64数据类型进行保存的,可以精确到纳秒的级别: # In[11]: ts.index.dtype # DatetimeIndex的标量是pandas的Timestamp对象: # In[12]: stamp = ts.index[0] stamp # Timestamp可以在任何地方用datetime对象进行替换。 # # # 1 Indexing, Selection, Subsetting(索引,选择,取子集) # # 当我们基于标签进行索引和选择时,时间序列就像是pandas.Series: # In[15]: ts # In[13]: stamp = ts.index[2] # In[14]: ts[stamp] # 为了方便,我们可以直接传入一个字符串用来表示日期: # In[16]: ts['1/10/2011'] # In[17]: ts['20110110'] # 对于比较长的时间序列,我们可以直接传入一年或一年一个月,来进行数据选取: # In[19]: longer_ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000)) longer_ts # In[20]: longer_ts['2001'] # 这里,字符串'2001'就直接被解析为一年,然后选中这个时期的数据。我们也可以指定月份: # In[21]: longer_ts['2001-05'] # 利用datetime进行切片(slicing)也没问题: # In[22]: ts[datetime(2011, 1, 7)] # 因为大部分时间序列是按年代时间顺序来排列的,我们可以用时间戳来进行切片,选中一段范围内的时间: # In[23]: ts # In[24]: ts['1/6/2011':'1/11/2011'] # 记住,这种方式的切片得到的只是原来数据的一个视图,如果我们在切片的结果上进行更改的的,原来的数据也会变化。 # # 有一个相等的实例方法(instance method)也能切片,truncate,能在两个日期上,对Series进行切片: # In[25]: ts.truncate(after='1/9/2011') # 所有这些都适用于DataFrame,我们对行进行索引: # In[26]: dates = pd.date_range('1/1/2000', periods=100, freq='W-WED') # In[27]: long_df = pd.DataFrame(np.random.randn(100, 4), index=dates, columns=['Colorado', 'Texas', 'New York', 'Ohio']) # In[28]: long_df.loc['5-2001'] # # 2 Time Series with Duplicate Indices(重复索引的时间序列) # # 在某些数据中,可能会遇到多个数据在同一时间戳下的情况: # In[29]: dates = pd.DatetimeIndex(['1/1/2000', '1/2/2000', '1/2/2000', '1/2/2000', '1/3/2000']) # In[31]: dup_ts = pd.Series(np.arange(5), index=dates) dup_ts # 我们通过is_unique属性来查看index是否是唯一值: # In[32]: dup_ts.index.is_unique # 对这个时间序列取索引的的话, 要么得到标量,要么得到切片,这取决于时间戳是否是重复的: # In[33]: dup_ts['1/3/2000'] # not duplicated # In[34]: dup_ts['1/2/2000'] # duplicated # 假设我们想要聚合那些有重复时间戳的数据,一种方法是用groupby,设定level=0: # In[35]: grouped = dup_ts.groupby(level=0) grouped.mean() # In[36]: grouped.count()