一、时间序列基础

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}')

画以时间为x轴的图,pandas的DataFrame自动将index列作为x轴
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)

锚定偏置可以使用rollforwardrollback分别显示地将日期向前或向后“滚动”;

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转换频率

PeriodPeriodIndex对象可以通过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的一个索引:

参考文献:

【1】【手把手教你】Python处理金融数据

【2】Pandas时间序列:时期(period)及其算术运算

【3】pandas 快速处理 date_time 日期格式

pandas处理时间序列(2):DatetimeIndex、索引和选择、含有重复索引的时间序列、日期范围与频率和移位、时间区间和区间算术的更多相关文章

  1. mysql索引之七:组合索引中选择合适的索引列顺序

    组合索引(concatenated index):由多个列构成的索引,如create index idx_emp on emp(col1, col2, col3, ……),则我们称idx_emp索引为 ...

  2. OGG复制进程延迟高,优化方法二(存在索引),SQL选择不好的索引

    https://www.cnblogs.com/lvcha001/p/13469500.html 接前序,本次场景中有索引,但是OGG复制进程使用了低效率的索引?  类似SQL使用低效索引,如何让Or ...

  3. 【mysql】索引与排序、重复索引、冗余索引

    索引与排序 排序可能发生2种情况: 1: 对于覆盖索引,直接在索引上查询时,就是有顺序的, using index 2: 先取出数据,形成临时表做filesort(文件排序,但文件可能在磁盘上,也可能 ...

  4. mysql优化----大数据下的分页,延迟关联,索引与排序的关系,重复索引与冗余索引,索引碎片与维护

    理想的索引,高效的索引建立考虑: :查询频繁度(哪几个字段经常查询就加上索引) :区分度要高 :索引长度要小 : 索引尽量能覆盖常用查询字段(如果把所有的列都加上索引,那么索引就会变得很大) : 索引 ...

  5. Pandas索引和选择数据

    在本章中,我们将讨论如何切割和丢弃日期,并获取Pandas中大对象的子集. Python和NumPy索引运算符"[]"和属性运算符".". 可以在广泛的用例中快 ...

  6. Pandas | 13 索引和选择数据

    Pandas现在支持三种类型的多轴索引; 编号 索引 描述 1 .loc() 基于标签 2 .iloc() 基于整数 3 .ix() 基于标签和整数 .loc() Pandas提供了各种方法来完成基于 ...

  7. pandas 学习 第14篇:索引和选择数据

    数据框和序列结构中都有轴标签,轴标签的信息存储在Index对象中,轴标签的最重要的作用是: 唯一标识数据,用于定位数据 用于数据对齐 获取和设置数据集的子集. 本文重点关注如何对序列(Series)和 ...

  8. 时间序列数据库(TSDB)初识与选择

    时间序列数据库(TSDB)初识与选择 本文作者由 MageByte 团队的 「借来方向」编写,关注公众号 给你更多硬核技术 背景 这两年互联网行业掀着一股新风,总是听着各种高大上的新名词.大数据.人工 ...

  9. 时间序列数据库(TSDB)初识与选择(InfluxDB、OpenTSDB、Druid、Elasticsearch对比)

    背景 这两年互联网行业掀着一股新风,总是听着各种高大上的新名词.大数据.人工智能.物联网.机器学习.商业智能.智能预警啊等等. 以前的系统,做数据可视化,信息管理,流程控制.现在业务已经不仅仅满足于这 ...

随机推荐

  1. idea 下 encodings.xml 的正确位置

    在多个module存在的情况下 encodings.xml在 project 下的.idea 下面         这个就是最父级project

  2. 构建基于Suricata+Splunk的IDS入侵检测系统

    一.什么是IDS和IPS? IDS(Intrusion Detection Systems):入侵检测系统,是一种网络安全设备或应用软件,可以依照一定的安全策略,对网络.系统的运行状况进行监视,尽可能 ...

  3. 科普知识普及 - 桥接VS中继

    首先要说明一个很多人理解的误区,中继比桥接好用,真的是这么回事么? 答案是否定的. 我们在说桥接和中继的时候我们要先了解,桥接和中继的工作原理.还有一个问题,估计很多人都想不明白:为什么中继搜到的信号 ...

  4. idea当配置eclipse快捷键时,全局替换的快捷键是什么?

    简介   每次为了新版本新建一个分支的时候,都要改每个maven的版本号,好麻烦,有么有?如下图: 当idea配置eclipse快捷键时,默认是没有全局替换快捷键的,需要设置 步骤 首先打开setti ...

  5. layui form表单自定义sm格式

    1. 新建以下sm样式,保存为layform_sm.css文件名,然后导入到layui.css的后面. .layui-input-sm,.layui-select-sm,.layui-textarea ...

  6. Linux常用的基础组件

    Linux服务器(新机器) yum install gcc gcc-c++ glibc-devel make ncurses-devel openssl-devel autoconf git yum  ...

  7. 12 Best Live Chat Software for Small Business Compared (2019) 最佳的wordpress在线聊天工具推荐插件 来帮你和潜在客户互动

    12 Best Live Chat Software for Small Business Compared (2019)     Did you know that more than 67% of ...

  8. java生成txt文件,读txt文件

    1.方法1 public static void main(String[] args) { try { FileWriter fileWriter = new FileWriter("c: ...

  9. mac xmind 激活

    下载地址 https://www.jb51.net/softjc/624167.html 打开压缩包中的[K].zip  按里面的READ ME!.rtf 文件来操作 嗯,就这样

  10. 如何在Linux下修改Mysql的用户(root)密码

    下面给大家分享下在Linux下如何修改Mysql的用户(root)的密码,分两种情况:第一种当拥有原来的mysql的root密码,第二种情况忘记原来的mysql的root的密码. 修改的用户都以roo ...