做为一个几乎天天与时间序列数据打交道的人员,我发现panda Python包在时间序列的操做和分析方面有强大优点。html
这篇关于panda时间序列数据处理的基本介绍能够带你入门时间序列分析。本文将主要介绍如下操做:python
接下来咱们一块儿步入正题。若是想要处理已有的实际数据,你可能考虑从使用panda read_csv将文件读入数据框开始,然而在这里,咱们将直接从处理生成的数据开始。api
首先导入咱们将会使用到的库,而后用它们建立日期范围框架
import pandas as pd from datetime import datetime import numpy as np date_rng = pd.date_range(start='1/1/2018', end='1/08/2018', freq='H')
这个日期范围的时间戳为每小时一次。若是咱们调用date_rng,咱们会看到以下所示:dom
DatetimeIndex(['2018-01-01 00:00:00', '2018-01-01 01:00:00', '2018-01-01 02:00:00', '2018-01-01 03:00:00', '2018-01-01 04:00:00', '2018-01-01 05:00:00', '2018-01-01 06:00:00', '2018-01-01 07:00:00', '2018-01-01 08:00:00', '2018-01-01 09:00:00', ... '2018-01-07 15:00:00', '2018-01-07 16:00:00', '2018-01-07 17:00:00', '2018-01-07 18:00:00', '2018-01-07 19:00:00', '2018-01-07 20:00:00', '2018-01-07 21:00:00', '2018-01-07 22:00:00', '2018-01-07 23:00:00', '2018-01-08 00:00:00'], dtype='datetime64[ns]', length=169, freq='H')
咱们能够检查第一个元素的类型:post
type(date_rng[0]) #returns pandas._libs.tslib.Timestamp
让咱们用时间戳数据的建立一个示例数据框,并查看前15个元素:spa
df = pd.DataFrame(date_rng, columns=['date']) df['data'] = np.random.randint(0,100,size=(len(date_rng))) df.head(15)
若是想进行时间序列操做,咱们须要一个日期时间索引。这样一来,数据框即可以在时间戳上创建索引。unix
将数据框索引转换为datetime索引,而后显示第一个元素:code
df['datetime'] = pd.to_datetime(df['date']) df = df.set_index('datetime') df.drop(['date'], axis=1, inplace=True) df.head()
若是数据中的“时间”戳其实是字符串类型和数值类型相比较,该怎么办呢?咱们能够将date_rng转换为字符串列表,而后将字符串转换为时间戳。orm
string_date_rng = [str(x) for x in date_rng] string_date_rng #returns ['2018-01-01 00:00:00', '2018-01-01 01:00:00', '2018-01-01 02:00:00', '2018-01-01 03:00:00', '2018-01-01 04:00:00', '2018-01-01 05:00:00', '2018-01-01 06:00:00', '2018-01-01 07:00:00', '2018-01-01 08:00:00', '2018-01-01 09:00:00',...
能够经过推断字符串的格式将其转换为时间戳,而后查看这些值:
timestamp_date_rng = pd.to_datetime(string_date_rng, infer_datetime_format=True) timestamp_date_rng #returns DatetimeIndex(['2018-01-01 00:00:00', '2018-01-01 01:00:00', '2018-01-01 02:00:00', '2018-01-01 03:00:00', '2018-01-01 04:00:00', '2018-01-01 05:00:00', '2018-01-01 06:00:00', '2018-01-01 07:00:00', '2018-01-01 08:00:00', '2018-01-01 09:00:00', ... '2018-01-07 15:00:00', '2018-01-07 16:00:00', '2018-01-07 17:00:00', '2018-01-07 18:00:00', '2018-01-07 19:00:00', '2018-01-07 20:00:00', '2018-01-07 21:00:00', '2018-01-07 22:00:00', '2018-01-07 23:00:00', '2018-01-08 00:00:00'], dtype='datetime64[ns]', length=169, freq=None)
可是若是须要转换一个惟一的字符串格式呢?
咱们能够建立一个任意的字符串形式的日期列表,并将它们转换为时间戳:
string_date_rng_2 = ['June-01-2018', 'June-02-2018', 'June-03-2018'] timestamp_date_rng_2 = [datetime.strptime(x,'%B-%d-%Y') for x in string_date_rng_2] timestamp_date_rng_2 #returns [datetime.datetime(2018, 6, 1, 0, 0), datetime.datetime(2018, 6, 2, 0, 0), datetime.datetime(2018, 6, 3, 0, 0)]
若是把它放到数据框中,将会如何?
df2 = pd.DataFrame(timestamp_date_rng_2, columns=['date']) df2
回到最初的数据框架,让咱们经过解析时间戳索引来查看数据:
假设只想查看本月2号的数据,可使用以下索引。
df[df.index.day == 2]
顶部如图所示:
也能够经过数据框索引直接调用想查看的日期:
df['2018-01-03']
如何在特定日期之间选择数据?
df['2018-01-04':'2018-01-06']
咱们填充的基本数据框提供了频率以小时计的数据,但一样能够以不一样的频率从新采样数据,并指定如何计算新样本频率的汇总统计信息。咱们能够取天天频率下数据的最小值、最大值、平均值、总和等,而不是每小时的频率,以下面的例子,计算天天数据的平均值:
df.resample('D').mean()
那么诸如滚动平均值或滚动和之类的窗口统计信息呢?
让咱们在原来的df中建立一个新列,计算3个窗口周期内的滚动和,而后查看数据框的顶部:
df ['rolling_sum'] = df.rolling(3).sum() df.head(10)
能够看到,在这个正确的计算中,只有当存在三个周期能够回顾时,它才开始具备有效值。
这能够有效地帮咱们了解到,当处理丢失的数据值时,如何向前或向后“滚动”数据。
这是咱们的df,但有一个新的列,采起滚动求和并向后“滚动”数据:
df['rolling_sum'] = df.rolling(3).sum() df.head(10)
采用诸如平均时间之类的实际值用于填补丢失的数据,这种方法一般来讲是有效的。但必定谨记,若是你正处理一个时间序列的问题,而且但愿数据是切合实际的,那么你不该该向后“滚动”数据。由于这样一来,你须要的关于将来的信息就永远不可能在那个时间获取到。你可能更但愿频繁地向前“滚动”数据,而不是向后“滚动”。
在处理时间序列数据时,可能会遇到Unix时间中的时间值。Unix时间,也称为Epoch时间,是自协调世界时(UTC) 1970年1月1日星期四00:00:00之后通过的秒数。使用Unix时间有助于消除时间戳的歧义,这样咱们就不会被时区、夏令时等混淆。
下面是一个时间t在Epoch时间的例子,它将Unix/Epoch时间转换为UTC中的常规时间戳:
epoch_t = 1529272655 real_t = pd.to_datetime(epoch_t, unit='s') real_t #returns Timestamp('2018-06-17 21:57:35')
若是我想把UTC中的时间转换为本身的时区,能够简单地作如下操做:
real_t.tz_localize('UTC').tz_convert('US/Pacific') #returns Timestamp('2018-06-17 14:57:35-0700', tz='US/Pacific')
掌握了这些基础知识后,就能够开始处理时间序列数据了。
如下是一些处理时间序列数据时要记住的技巧和常见的陷阱:
本文为云栖社区原创内容,未经容许不得转载。