您好,欢迎访问一九零五行业门户网

Python时间序列数据操作的常用方法总结

时间序列数据是一种在一段时间内收集的数据类型,它通常用于金融、经济学和气象学等领域,经常通过分析来了解随着时间的推移的趋势和模式
pandas是python中一个强大且流行的数据操作库,特别适合处理时间序列数据。它提供了一系列工具和函数可以轻松加载、操作和分析时间序列数据。
在本文中,我们介绍时间序列数据的索引和切片、重新采样和滚动窗口计算以及其他有用的常见操作,这些都是使用pandas操作时间序列数据的关键技术。
数据类型python在python中,没有专门用于表示日期的内置数据类型。一般情况下都会使用datetime模块提供的datetime对象进行日期时间的操作。
import datetime t = datetime.datetime.now() print(ftype: {type(t)} and t: {t}) #type: and t: 2022-12-26 14:20:51.278230
一般情况下我们都会使用字符串的形式存储日期和时间。所以在使用时我们需要将这些字符串进行转换成datetime对象。
一般情况下时间的字符串有以下格式:
yyyy-mm-dd (e.g. 2022-01-01)yyyy/mm/dd (e.g. 2022/01/01)dd-mm-yyyy (e.g. 01-01-2022)dd/mm/yyyy (e.g. 01/01/2022)mm-dd-yyyy (e.g. 01-01-2022)mm/dd/yyyy (e.g. 01/01/2022)hh:mm:ss (e.g. 11:30:00)hh:mm:ss am/pm (e.g. 11:30:00 am)hh:mm am/pm (e.g. 11:30 am)strptime 函数以字符串和格式字符串作为参数,返回一个datetime对象。
string = '2022-01-01 11:30:09' t = datetime.datetime.strptime(string, %y-%m-%d %h:%m:%s) print(ftype: {type(t)} and t: {t}) #type: and t: 2022-01-01 11:30:09
格式字符串如下:
还可以使用strftime函数将datetime对象转换回特定格式的字符串表示。
t = datetime.datetime.now() t_string = t.strftime(%m/%d/%y, %h:%m:%s) #12/26/2022, 14:38:47 t_string = t.strftime(%b/%d/%y, %h:%m:%s) #dec/26/2022, 14:39:32
unix时间(posix时间或epoch时间)是一种将时间表示为单个数值的系统。它表示自1970年1月1日星期四00:00:00协调世界时(utc)以来经过的秒数。
unix时间和时间戳通常可以互换使用。unix时间是创建时间戳的标准版本。一般情况下使用整数或浮点数据类型用于存储时间戳和unix时间。
我们可以使用time模块的mktime方法将datetime对象转换为unix时间整数。也可以使用datetime模块的fromtimestamp方法。
#convert datetime to unix time import time from datetime import datetime t = datetime.now() unix_t = int(time.mktime(t.timetuple())) #1672055277 #convert unix time to datetime unix_t = 1672055277 t = datetime.fromtimestamp(unix_t) #2022-12-26 14:47:57
使用dateutil模块来解析日期字符串获得datetime对象。
from dateutil import parser date = parser.parse(29th of october, 1923) #datetime.datetime(1923, 10, 29, 0, 0)
pandaspandas提供了三种日期数据类型:
1、timestamp或datetimeindex:它的功能类似于其他索引类型,但也具有用于时间序列操作的专门函数。
t = pd.to_datetime(29/10/1923, dayfirst=true) #timestamp('1923-10-29 00:00:00') t = pd.timestamp('2019-01-01', tz = 'europe/berlin') #timestamp('2019-01-01 00:00:00+0100', tz='europe/berlin') t = pd.to_datetime([04/23/1920, 10/29/1923]) #datetimeindex(['1920-04-23', '1923-10-29'], dtype='datetime64[ns]', freq=none)
2、period或periodindex:一个有开始和结束的时间间隔。它由固定的间隔组成。
t = pd.to_datetime([04/23/1920, 10/29/1923]) period = t.to_period(d) #periodindex(['1920-04-23', '1923-10-29'], dtype='period[d]')
3、timedelta或timedeltaindex:两个日期之间的时间间隔。
delta = pd.timedeltaindex(data =['1 days 03:00:00', '2 days 09:05:01.000030']) timedeltaindex(['1 days 02:00:00', '1 days 06:05:01.000030'], dtype='timedelta64[ns]', freq=none)
在pandas中,可以使用to_datetime方法将对象转换为datetime数据类型或进行任何其他转换。
import pandas as pd df = pd.read_csv(dataset.txt) df.head() date value 0 1991-07-01 3.526591 1 1991-08-01 3.180891 2 1991-09-01 3.252221 3 1991-10-01 3.611003 4 1991-11-01 3.565869 df.info() rangeindex: 204 entries, 0 to 203 data columns (total 2 columns): # column non-null count dtype --- ------ -------------- ----- 0 date 204 non-null object 1 value 204 non-null float64 dtypes: float64(1), object(1) memory usage: 3.3+ kb # convert to datetime df[date] = pd.to_datetime(df[date], format = %y-%m-%d) df.info() rangeindex: 204 entries, 0 to 203 data columns (total 2 columns): # column non-null count dtype --- ------ -------------- ----- 0 date 204 non-null datetime64[ns] 1 value 204 non-null float64 dtypes: datetime64[ns](1), float64(1) memory usage: 3.3 kb # convert to unix df['unix_time'] = df['date'].apply(lambda x: x.timestamp()) df.head() date value unix_time 0 1991-07-01 3.526591 678326400.0 1 1991-08-01 3.180891 681004800.0 2 1991-09-01 3.252221 683683200.0 3 1991-10-01 3.611003 686275200.0 4 1991-11-01 3.565869 688953600.0 df[date_converted_from_unix] = pd.to_datetime(df[unix_time], unit = s) df.head() date value unix_time date_converted_from_unix 0 1991-07-01 3.526591 678326400.0 1991-07-01 1 1991-08-01 3.180891 681004800.0 1991-08-01 2 1991-09-01 3.252221 683683200.0 1991-09-01 3 1991-10-01 3.611003 686275200.0 1991-10-01 4 1991-11-01 3.565869 688953600.0 1991-11-01
我们还可以使用parse_dates参数在任何文件加载时直接声明日期列。
df = pd.read_csv(dataset.txt, parse_dates=[date]) df.info() rangeindex: 204 entries, 0 to 203 data columns (total 2 columns): # column non-null count dtype --- ------ -------------- ----- 0 date 204 non-null datetime64[ns] 1 value 204 non-null float64 dtypes: datetime64[ns](1), float64(1) memory usage: 3.3 kb
如果是单个时间序列的数据,最好将日期列作为数据集的索引。
df.set_index(date,inplace=true) value date 1991-07-01 3.526591 1991-08-01 3.180891 1991-09-01 3.252221 1991-10-01 3.611003 1991-11-01 3.565869 ... ... 2008-02-01 21.654285 2008-03-01 18.264945 2008-04-01 23.107677 2008-05-01 22.912510 2008-06-01 19.431740
numpy也有自己的datetime类型np.datetime64。特别是在大型数据集时,向量化是非常有用的,应该优先使用。
import numpy as np arr_date = np.array('2000-01-01', dtype=np.datetime64) arr_date #array('2000-01-01', dtype='datetime64[d]') #broadcasting arr_date = arr_date + np.arange(30) array(['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04', '2000-01-05', '2000-01-06', '2000-01-07', '2000-01-08', '2000-01-09', '2000-01-10', '2000-01-11', '2000-01-12', '2000-01-13', '2000-01-14', '2000-01-15', '2000-01-16', '2000-01-17', '2000-01-18', '2000-01-19', '2000-01-20', '2000-01-21', '2000-01-22', '2000-01-23', '2000-01-24', '2000-01-25', '2000-01-26', '2000-01-27', '2000-01-28', '2000-01-29', '2000-01-30'], dtype='datetime64[d]')
有用的函数下面列出的是一些可能对时间序列有用的函数。
df = pd.read_csv(dataset.txt, parse_dates=[date]) df[date].dt.day_name() 0 monday 1 thursday 2 sunday 3 tuesday 4 friday ... 199 friday 200 saturday 201 tuesday 202 thursday 203 sunday name: date, length: 204, dtype: object
datareaderpandas_datareader是pandas库的一个辅助库。它提供了许多常见的金融时间序列数据。
#pip install pandas-datareader from pandas_datareader import wb #gdp per capita from world bank df = wb.download(indicator='ny.gdp.pcap.kd', country=['us', 'fr', 'gb', 'dk', 'no'], start=1960, end=2019) ny.gdp.pcap.kd country year denmark 2019 57203.027794 2018 56563.488473 2017 55735.764901 2016 54556.068955 2015 53254.856370 ... ... united states 1964 21599.818705 1963 20701.269947 1962 20116.235124 1961 19253.547329 1960 19135.268182 [300 rows x 1 columns]
日期范围我们可以使用pandas的date_range方法定义一个日期范围。
pd.date_range(start=2021-01-01, end=2022-01-01, freq=d) datetimeindex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08', '2021-01-09', '2021-01-10', ... '2021-12-23', '2021-12-24', '2021-12-25', '2021-12-26', '2021-12-27', '2021-12-28', '2021-12-29', '2021-12-30', '2021-12-31', '2022-01-01'], dtype='datetime64[ns]', length=366, freq='d') pd.date_range(start=2021-01-01, end=2022-01-01, freq=bm) datetimeindex(['2021-01-29', '2021-02-26', '2021-03-31', '2021-04-30', '2021-05-31', '2021-06-30', '2021-07-30', '2021-08-31', '2021-09-30', '2021-10-29', '2021-11-30', '2021-12-31'], dtype='datetime64[ns]', freq='bm') fridays= pd.date_range('2022-11-01', '2022-12-31', freq=w-fri) datetimeindex(['2022-11-04', '2022-11-11', '2022-11-18', '2022-11-25', '2022-12-02', '2022-12-09', '2022-12-16', '2022-12-23', '2022-12-30'], dtype='datetime64[ns]', freq='w-fri')
我们可以使用timedelta_range方法创建一个时间序列。
t = pd.timedelta_range(0, periods=10, freq=h) timedeltaindex(['0 days 00:00:00', '0 days 01:00:00', '0 days 02:00:00', '0 days 03:00:00', '0 days 04:00:00', '0 days 05:00:00', '0 days 06:00:00', '0 days 07:00:00', '0 days 08:00:00', '0 days 09:00:00'], dtype='timedelta64[ns]', freq='h')
格式化我们dt.strftime方法改变日期列的格式。
df[new_date] = df[date].dt.strftime(%b %d, %y) df.head() date value new_date 0 1991-07-01 3.526591 jul 01, 1991 1 1991-08-01 3.180891 aug 01, 1991 2 1991-09-01 3.252221 sep 01, 1991 3 1991-10-01 3.611003 oct 01, 1991 4 1991-11-01 3.565869 nov 01, 1991
解析解析datetime对象并获得日期的子对象。
df[year] = df[date].dt.year df[month] = df[date].dt.month df[day] = df[date].dt.day df[calendar] = df[date].dt.date df[hour] = df[date].dt.time df.head() date value year month day calendar hour 0 1991-07-01 3.526591 1991 7 1 1991-07-01 00:00:00 1 1991-08-01 3.180891 1991 8 1 1991-08-01 00:00:00 2 1991-09-01 3.252221 1991 9 1 1991-09-01 00:00:00 3 1991-10-01 3.611003 1991 10 1 1991-10-01 00:00:00 4 1991-11-01 3.565869 1991 11 1 1991-11-01 00:00:00
还可以重新组合它们。
df[date_joined] = pd.to_datetime(df[[year,month,day]]) print(df[date_joined]) 0 1991-07-01 1 1991-08-01 2 1991-09-01 3 1991-10-01 4 1991-11-01 ... 199 2008-02-01 200 2008-03-01 201 2008-04-01 202 2008-05-01 203 2008-06-01 name: date_joined, length: 204, dtype: datetime64[ns]
过滤查询使用loc方法来过滤dataframe。
df = df.loc[2021-01-01:2021-01-10]
truncate 可以查询两个时间间隔中的数据
df_truncated = df.truncate('2021-01-05', '2022-01-10')
常见数据操作下面就是对时间序列数据集中的值执行操作。我们使用yfinance库创建一个用于示例的股票数据集。
#get google stock price data import yfinance as yf start_date = '2020-01-01' end_date = '2023-01-01' ticker = 'googl' df = yf.download(ticker, start_date, end_date) df.head() date open high low close adj close volume 2020-01-02 67.420502 68.433998 67.324501 68.433998 68.433998 27278000 2020-01-03 67.400002 68.687500 67.365997 68.075996 68.075996 23408000 2020-01-06 67.581497 69.916000 67.550003 69.890503 69.890503 46768000 2020-01-07 70.023003 70.175003 69.578003 69.755501 69.755501 34330000 2020-01-08 69.740997 70.592499 69.631500 70.251999 70.251999 35314000
计算差值diff函数可以计算一个元素与另一个元素之间的插值。
#subtract that day's value from the previous day df[diff_close] = df[close].diff() #subtract that day's value from the day's value 2 days ago df[diff_close_2days] = df[close].diff(periods=2)
累计总数df[volume_cumulative] = df[volume].cumsum()
滚动窗口计算滚动窗口计算(移动平均线)。
df[close_rolling_14] = df[close].rolling(14).mean() df.tail()
可以对我们计算的移动平均线进行可视化
常用的参数:
center:决定滚动窗口是否应以当前观测值为中心。min_periods:窗口中产生结果所需的最小观测次数。s = pd.series([1, 2, 3, 4, 5]) #the rolling window will be centered on each observation rolling_mean = s.rolling(window=3, center=true).mean() 0 nan 1 2.0 2 3.0 3 4.0 4 nan dtype: float64 explanation: first window: [na 1 2] = na second window: [1 2 3] = 2 # the rolling window will not be centered, #and will instead be anchored to the left side of the window rolling_mean = s.rolling(window=3, center=false).mean() 0 nan 1 nan 2 2.0 3 3.0 4 4.0 dtype: float64 explanation: first window: [na na 1] = na second window: [na 1 2] = na third window: [1 2 3] = 2
平移pandas有两个方法,shift()和tshift(),它们可以指定倍数移动数据或时间序列的索引。shift()移位数据,而tshift()移位索引。
#shift the data df_shifted = df.shift(5,axis=0) df_shifted.head(10) #shift the indexes df_tshifted = df.tshift(periods = 4, freq = 'd') df_tshifted.head(10)
df_shifted
df_tshifted
时间间隔转换在 pandas 中,操 to_period 函数允许将日期转换为特定的时间间隔。可以获取具有许多不同间隔或周期的日期
df[period] = df[date].dt.to_period('w')
频率asfreq方法用于将时间序列转换为指定的频率。
monthly_data = df.asfreq('m', method='ffill')
常用参数:
freq:数据应该转换到的频率。这可以使用字符串别名(例如,'m'表示月,'h'表示小时)或pandas偏移量对象来指定。
method:如何在转换频率时填充缺失值。这可以是'ffill'(向前填充)或'bfill'(向后填充)之类的字符串。
采样resample可以改变时间序列频率并重新采样。我们可以进行上采样(到更高的频率)或下采样(到更低的频率)。因为我们正在改变频率,所以我们需要使用一个聚合函数(比如均值、最大值等)。
resample方法的参数:
rule:数据重新采样的频率。这可以使用字符串别名(例如,'m'表示月,'h'表示小时)或pandas偏移量对象来指定。
#down sample monthly_data = df.resample('m').mean()
#up sample minute_data = data.resample('t').ffill()
百分比变化使用pct_change方法来计算日期之间的变化百分比。
df[pct] = df[close].pct_change(periods=2) print(df[pct]) date 2020-01-02 nan 2020-01-03 nan 2020-01-06 0.021283 2020-01-07 0.024671 2020-01-08 0.005172 ... 2022-12-19 -0.026634 2022-12-20 -0.013738 2022-12-21 0.012890 2022-12-22 -0.014154 2022-12-23 -0.003907 name: pct, length: 752, dtype: float64
总结在pandas和numpy等库的帮助下,可以对时间序列数据执行广泛的操作,包括过滤、聚合和转换。本文介绍的是一些在工作中经常遇到的常见操作,希望对你有所帮助。
以上就是python时间序列数据操作的常用方法总结的详细内容。
其它类似信息

推荐信息