一、时间序列基础
1. 时间戳索引DatetimeIndex
生成20个DatetimeIndex
from datetime import datetime
dates = pd.date_range(start='2019-04-01',periods=20)
dates
用这20个索引作为ts的索引
ts = pd.Series(np.random.randn(20),index=dates)
ts
不同索引的时间序列之间的算术运算在日期上自动对齐
ts + ts[::2]
pandas使用numpy的datetime64数据类型在纳秒级的分辨率下存储时间戳
ts.index.dtype
DatetimeIndex中的标量值是pandas的Timestamp对象
stamp =ts.index[0]
stamp
2. 索引、选择
(1) 索引
ts是一个series;stamp是索引为2的时间戳,Timestamp('2019-04-03 00:00:00', freq='D')
stamp =ts.index[2] ts[stamp]
为了方便,可以传递一个能解释为日期的字符串
(2) 选择
[1]对于长的时间序列,可以传递一个年份或一个年份和月份来选择数据的切片
longer_ts = pd.Series(np.random.randn(10),index=pd.date_range('4/1/2019',periods=10))
longer_ts
选择2019年4月份的所有数据
longer_ts.loc['2019-4']#可以写成'2019/04',不能写成'201904'
选择2019年的所有数据
longer_ts['2019']
[2]选择一段时间内的数据
ts[datetime(2019,1,1):]
ts['1/4/2019':'4/10/2019']
truncate也可以实现在两个日期间对Series进行切片
ts.truncate(after='4/3/2019')
以上操作也都适用于DataFrame
3. 含有重复索引的时间序列
在某些应用中,可能会有多个数据观察值落在特定的时间戳中。
dates = pd.DatetimeIndex(['4/1/2019','4/2/2019','4/2/2019','4/2/2019','4/3/2019']) dup_ts = pd.Series(np.arange(5),index=dates)
dup_ts
通过检查索引的is_unique属性,我们可以看出索引并不是唯一的。
dup_ts.index.is_unique
对上面的Series进行索引,结果是标量值还是Series切片取决于是否有时间戳是重复的。
假设你想要聚合含有非唯一时间戳的数据,一种方式就是使用groupby并传递level=0
二、日期范围、频率和移位
有些应用中经常需要处理固定频率的场景,例如每日的、每月的或每10分钟,这意味着我们甚至需要在必要的时候向时间序列中引入缺失值。pandas可以帮助我们重新采样、推断频率以及生成固定频率的数据范围。
1. 生成日期范围pd.date_range()、pd.period_range()
常用函数:
- pd.date_range(),生成的是DatetimeIndex格式的日期序列;
-
pd.period_range(),生成PeriodIndex的时期日期序列。
(1)pd.date_range()
参数:起始时间,结束时间,freq,periods (四选三)
开始日期和结束日期严格定义了生成日期索引的边界, 周时间序列,默认以sunday周日作为一周最后一日;若要改成周一作为第一天,freq='W-SAT'
freq='M'月,'D'天,'W',周,'Y'年。默认情况下,date_range生成的是每日的时间戳,如果只传递一个起始或结尾日期,就必须要传递一个用于生成范围的数字,如 “BM” 代表 bussiness end of month
#使用date_range生成日期序列
#如要详细了解该函数,可以使用help(pd.date_range)
#参数四选三:起始时间,结束时间,freq,periods
#freq='M'月,'D'天,'W',周,'Y'年
#生成月时间序列
dm = pd.date_range('2018/01/01', freq='M', periods=12)
print(f'生成月时间序列:\n{dm}')
#算头不算尾
#生成年时间序列,默认是以12月结尾,freq='Y-DEC'
dy=pd.date_range('2008-01-01','2019-01-10',freq='Y')
print(f'生成年时间序列:\n{dy}')
#生成日时间序列
dd=pd.date_range('2018-01-01',freq='D',periods=10)
print(f'生成日时间序列:\n{dd}')
#生成周时间序列,默认以sunday周日作为一周最后一日
#如要改成周一作为第一天,freq='W-SAT'
dw=pd.date_range('2018-01-01',freq='W',periods=10)
print(f'生成周时间序列:\n{dw}')
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
#画以时间为x轴的图,pandas的DataFrame自动将index列作为x轴
np.random.seed(2)
#生成日期序列
x=pd.date_range('2018/01/01','2019/12/31', freq='d')
#x=pd.period_range('2018/01/01','2019/12/31', freq='d')
#标准正态分布时间序列
y=np.random.standard_normal(len(x))
#将二者转换为pandas的数据格式
df=pd.DataFrame(y,columns=['标准正态分布'],index=x)
df.plot(figsize=(12,6))
plt.title('模拟标准正态分布随机数') ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.show()
(2)pd.period_range()
具体period见第五节
#使用period_range生成日期序列
#参数四选三:起始时间,结束时间,freq,periods
#freq='M'月,'D'天,'W',周,'Y'年
#生成月时期序列
dpm = pd.period_range('2019/01/01', freq='M', periods=12)
print(f'生成月时间序列:\n{dpm}')
#生成年时期序列,默认是以12月结尾,freq='Y-DEC'
dpy=pd.period_range('2008-01-01','2019-01-10',freq='Y')
print(f'生成年时间序列:\n{dpy}')
#生成日时期序列
dpd=pd.period_range('2018-01-01',freq='D',periods=10)
print(f'生成日时间序列:\n{dpd}')
#生成周时期序列,默认以sunday周日作为一周最后一日
#如要改成周一作为第一天,freq='W-SAT'
dpw=pd.period_range('2018-01-01',freq='W-SUN',periods=10)
print(f'生成周时间序列:\n{dpw}')
其他的一些freq频率值,见下图
有时候会获得包含时间信息的开始日期或结束日期,但是想要生成的是标准化为零点的时间戳。用normalize=True就可以解决
pd.date_range(start='2019-4-1 12:45:23',periods=5) #不加normalize
pd.date_range(start='2019-4-1 12:45:23',periods=5,normalize=True)
2. 频率和日期偏置
pandas中的频率是由基础频率和倍数组成的。基础频率通常会有字符串别名,例如'M'代表每月,'H'代表每小时。对于每个基础频率,都有一个对象可以被用于定义日期偏置。例如,每小时的频率可以使用Hour类来表示。
from pandas.tseries.offsets import Hour,Minute
hour = Hour()
hour
four_hours = Hour(4)
four_hours
pd.date_range(start='2019-4-1',periods=5,freq='4h')
pd.date_range(start='2019-4-1',periods=5,freq='1h30min')
月中某星期的日期week of month
例子:每月第三个星期五
rng = pd.date_range('2019-4-1','2019-7-5',freq='WOM-3FRI')
list(rng)
3. 移位(前向和后向)日期
“移位”是指将日期按时间向前移动或向后移动。Series和DataFrame都有一个shift方法用于进行简单的前向或后向移位,而不改变索引。
(1)shift
ts = pd.Series(np.random.randn(4),
index=pd.date_range('4/1/2019',periods=4,freq='M'))
ts
ts.shift(2)
ts.shift(-2)
由于简单移位并不改变索引,一些数据会被丢弃。因此,如果频率是已知的,则可以将频率传递给shift来推移时间戳而不是简单的数据:
ts.shift(2,freq='D')
ts.shift(2,freq='M') #'M'日历月末
ts.shift(2,freq='BM') #'BM'月内最后工作日
(2)使用偏置进行移位日期
from pandas.tseries.offsets import Day,MonthEnd
now = datetime.now()
now
now + 3 * Day()
如果添加锚定偏置量,比如MonthEnd,根据频率规则,第一个增量会将日期“前滚”到下一个日期:
now + MonthEnd()
now + MonthEnd(2)
锚定偏置可以使用rollforward和rollback分别显示地将日期向前或向后“滚动”;
offset = MonthEnd()
offset.rollforward(now)
offset.rollback(now)
将移位方法与groupby一起使用是日期偏置的一种创造性用法:
ts = pd.Series(np.random.randn(20),index=pd.date_range('4/1/2019',periods=20,freq='4d'))
ts
ts.groupby(offset.rollforward).mean()
resample可以得到同样的结果
ts.resample('M').mean()
三、时区处理
待用到时候再添加
四、时间区间和区间算术
1. Period、period_range
(1)Period
时间区间Period表示的是时间范围,比如数日、数月、数季、数年等。
定义一个时间区间Period
p = pd.Period(2019,freq='A-DEC')
p
通过加减整数可以实现对Period的移动
如果两个Period对象拥有相同频率,则它们的差就是它们之间的单位数量
pd.Period('2018',freq='A-DEC') - p
(2)period_range
参数:起始时间,结束时间,freq,periods(四选三)
freq='M'月,'D'天,'W',周,'Y'年
#生成月时期序列
dpm = pd.period_range('2019/01/01', freq='M', periods=12)
print(f'生成月时间序列:\n{dpm}')
#生成年时期序列,默认是以12月结尾,freq='Y-DEC'
dpy=pd.period_range('2008-01-01','2019-01-10',freq='Y')
print(f'生成年时间序列:\n{dpy}')
#生成日时期序列
dpd=pd.period_range('2018-01-01',freq='D',periods=10)
print(f'生成日时间序列:\n{dpd}')
#生成周时期序列,默认以sunday周日作为一周最后一日
#如要改成周一作为第一天,freq='W-SAT'
dpw=pd.period_range('2018-01-01',freq='W-SUN',periods=10)
print(f'生成周时间序列:\n{dpw}')
(3)PeriodIndex
PeriodIndex类的构造函数允许直接使用一组字符串表示一段时期
values = ['2001Q3','2002Q2','2003Q1']
index = pd.PeriodIndex(values,freq='Q-DEC')
index
2. 区间频率转换
- 高频数据向低频数据转换;
- 低频数据向高频数据转换。
主要函数:df.resample(),df代表pandas的DataFrame格式数据,resample方法的参数参数中,freq表示重采样频率,例如‘M’、‘5min’,Second(15),用于产生聚合值的函数名或数组函数,例如‘mean’、‘ohlc’、np.max等,默认是‘mean’,其他常用的有:‘first’、‘last’、‘median’、‘max’、‘min’axis=0默认是纵轴,横轴设置axis=1
(1)asfreq转换频率
Period和PeriodIndex对象可以通过asfreq方法被转换成别的频率。
假设有一个年度时期,希望将其转换为当年年初或年末的一个月度时期:
频率为‘A-DEC’表示一年的开始到结尾的每一条,'start'表示年初,'end'表示年末
【1】Period
对于一个不以12月结束的财政年度,月度子时期的归属情况就不一样了:
【2】PeriodIndex或TimeSeries的频率转换
举例:频率转换
#frq='W'代表周
df=pd.DataFrame(np.random.randn(5,4),
index=pd.date_range('1/4/2019',periods=5,freq='W'),
columns=['GZ','BJ','SH','SZ'])
df
低频数据向高频数据转换【周-日】
#将上述样本转换为日序列,缺失值使用前值补上
#如使用后值则用bfill()
df_daily=df.resample('D').ffill()
df_daily.head(10)
高频数据向低频数据转化【日-月】
df_daily1=df.resample('M').ffill()
df_daily1.head(10)
根据period来重采样
#根据period来重采样
df1=pd.DataFrame(np.random.randn(5,4),
index=pd.period_range('1/1/2017',periods=5,freq='W'),
columns=['GZ','BJ','SH','SZ'])
df1.head()
df2=pd.DataFrame(np.random.randn(2,4),
index=pd.period_range('1-2017','12-2018',freq='A'),
columns=['GZ','BJ','SH','SZ'])
df2.head()
3. 季度区间频率
季度型数据在会计、金融等领域中很常见,许多季度型数据都会涉及“财年末”的概念,通常是一年12个月中某月的最后一个日历日或工作日。就这一点来说,时期“2012Q4”根据财年末的不同会有不同的含义。pandas支持12种可能的季度型频率,即Q-JAN到Q-DEC:
2012Q4指的是2011年第四个季度,也就是2011.11.01-2012-01.31
在以1月结束的财年中,2012Q4是从11月到1月(将其转换为日型频率就明白了)
例如:要获取该季度倒数第二个工作日下午4点的时间戳:
period_range可以生成季度型范围。季度型范围的算术运算也跟上面是一样的:
4. 时间戳Timestamp与Period区间的转换
(1)to_period()
由于时期指的是非重叠时间区间,因此对于给定的频率,一个给定的时间戳只能属于一个时期。新PeriodIndex的频率默认是从时间戳推断而来的,你也可以指定任何别的频率。结果中语序存在重复时期:
(2)to_timestamp()
5. 通过数组创建PeriodIndex
固定频率的数据集通常会将时间信息分开存放在多个列中。例如:年度和季度就分布存放在不同的列中:
将这两个数组以及一个频率传入PeriodIndex,就可以将它们合并成DataFrame的一个索引:
参考文献:
【2】Pandas时间序列:时期(period)及其算术运算
pandas处理时间序列(2):DatetimeIndex、索引和选择、含有重复索引的时间序列、日期范围与频率和移位、时间区间和区间算术的更多相关文章
-
mysql索引之七:组合索引中选择合适的索引列顺序
组合索引(concatenated index):由多个列构成的索引,如create index idx_emp on emp(col1, col2, col3, ……),则我们称idx_emp索引为 ...
-
OGG复制进程延迟高,优化方法二(存在索引),SQL选择不好的索引
https://www.cnblogs.com/lvcha001/p/13469500.html 接前序,本次场景中有索引,但是OGG复制进程使用了低效率的索引? 类似SQL使用低效索引,如何让Or ...
-
【mysql】索引与排序、重复索引、冗余索引
索引与排序 排序可能发生2种情况: 1: 对于覆盖索引,直接在索引上查询时,就是有顺序的, using index 2: 先取出数据,形成临时表做filesort(文件排序,但文件可能在磁盘上,也可能 ...
-
mysql优化----大数据下的分页,延迟关联,索引与排序的关系,重复索引与冗余索引,索引碎片与维护
理想的索引,高效的索引建立考虑: :查询频繁度(哪几个字段经常查询就加上索引) :区分度要高 :索引长度要小 : 索引尽量能覆盖常用查询字段(如果把所有的列都加上索引,那么索引就会变得很大) : 索引 ...
-
Pandas索引和选择数据
在本章中,我们将讨论如何切割和丢弃日期,并获取Pandas中大对象的子集. Python和NumPy索引运算符"[]"和属性运算符".". 可以在广泛的用例中快 ...
-
Pandas | 13 索引和选择数据
Pandas现在支持三种类型的多轴索引; 编号 索引 描述 1 .loc() 基于标签 2 .iloc() 基于整数 3 .ix() 基于标签和整数 .loc() Pandas提供了各种方法来完成基于 ...
-
pandas 学习 第14篇:索引和选择数据
数据框和序列结构中都有轴标签,轴标签的信息存储在Index对象中,轴标签的最重要的作用是: 唯一标识数据,用于定位数据 用于数据对齐 获取和设置数据集的子集. 本文重点关注如何对序列(Series)和 ...
-
时间序列数据库(TSDB)初识与选择
时间序列数据库(TSDB)初识与选择 本文作者由 MageByte 团队的 「借来方向」编写,关注公众号 给你更多硬核技术 背景 这两年互联网行业掀着一股新风,总是听着各种高大上的新名词.大数据.人工 ...
-
时间序列数据库(TSDB)初识与选择(InfluxDB、OpenTSDB、Druid、Elasticsearch对比)
背景 这两年互联网行业掀着一股新风,总是听着各种高大上的新名词.大数据.人工智能.物联网.机器学习.商业智能.智能预警啊等等. 以前的系统,做数据可视化,信息管理,流程控制.现在业务已经不仅仅满足于这 ...
随机推荐
-
[LeetCode] Employees Earning More Than Their Managers 员工挣得比经理多
The Employee table holds all employees including their managers. Every employee has an Id, and there ...
-
缓存篇~第八回 Redis实现基于方法签名的数据集缓存~续(优化缓存中的key)
返回目录 上一讲主要是说如何将数据集存储到redis服务器里,而今天主要说的是缓存里的键名,我们习惯叫它key. redis或者其它缓存组件实现的存储机制里,它将很多方法对应的数据集存储在一个公共的空 ...
-
Android进阶笔记19:onInterceptTouchEvent、onTouchEvent与onTouch
1.onTouch方法:onTouch方法是View的 OnTouchListener借口中定义的方法,处理View及其子类被touch是的事件处理.当一个View绑定了OnTouchLister后, ...
-
20个linux命令行工具监视性能(上)
对于每一个系统管理员或网络管理员每天监视或调试linux系统的性能问题是一件非常困难的事,在it行业作为一个linux管理员五年之后,我开始知道监视和保持系统启动和运行有多么的困难.由于这个原因,我们 ...
-
10分钟精通SharePoint - SharePoint拓扑结构
SharePoint服务器角色:前端,应用程序和数据库服务器 应用程序服务:搜索.Office文档.User Profile和App等应用服务器 数据库类型:内容数据库.应用程序数据库和配置数据库 规 ...
-
[转]自定义alert弹框,title不显示域名
//(仅去掉网址) (function(){ window.alert = function(name){ var iframe = document.createElement("IFRA ...
-
事件委托在ios下面失效
$(document).on("click","目标class",function(){ //安卓下点击可以,ios下面失效 }) 百度了下说是H5新定义的, ...
-
python数据库编程小应用
python DB api 数据库连接对象connection数据库交互对象cursor数据库异常类exceptions 流程:开始创建connection获取cursor执行查询.执行命令.获取数据 ...
-
(算法)Trapping Rain Water I
题目: Given n non-negative integers representing an elevation map where the width of each bar is 1, co ...
-
Oracle正式发布VirtualBox 5.0.22版本
甲骨文(Oracle)正式发布了VirtualBox 5.0.22版本,该开源和跨平台虚拟化软件的最新维护版本已经面向所有支持平台开放,引入了诸多新特性和功能改善推荐用户尽早完成升级.新版本在Linu ...