时间序列数据是一种在一段时间内收集的数据类型,它通常用于金融、经济学和气象学等领域,经常通过分析来了解随着时间的推移的趋势和模式 Pandas是Python中一个强大且流行的数据操作库,特别适合处理时间序列数据。它提供了一系列工具和函数可以轻松加载、操作和分析时间序列数据。 在本文中,我们介绍时间序列数据的索引和切片、重新采样和滚动窗口计算以及其他有用的常见操作,这些都是使用Pandas操作时间序列数据的关键技术。数据类型 Python 在Python中,没有专门用于表示日期的内置数据类型。一般情况下都会使用datetime模块提供的datetime对象进行日期时间的操作。importdatetimetdatetime。datetime。now()print(ftype:{type(t)}andt:{t})type:classdatetime。datetimeandt:2022122614:20:51。278230 一般情况下我们都会使用字符串的形式存储日期和时间。所以在使用时我们需要将这些字符串进行转换成datetime对象。 一般情况下时间的字符串有以下格式:YYYYMMDD(e。g。20220101)YYYYMMDD(e。g。20220101)DDMMYYYY(e。g。01012022)DDMMYYYY(e。g。01012022)MMDDYYYY(e。g。01012022)MMDDYYYY(e。g。01012022)HH:MM:SS(e。g。11:30:00)HH:MM:SSAMPM(e。g。11:30:00AM)HH:MMAMPM(e。g。11:30AM) strptime函数以字符串和格式字符串作为参数,返回一个datetime对象。string2022010111:30:09tdatetime。datetime。strptime(string,YmdH:M:S)print(ftype:{type(t)}andt:{t})type:classdatetime。datetimeandt:2022010111:30:09 格式字符串如下: 还可以使用strftime函数将datetime对象转换回特定格式的字符串表示。tdatetime。datetime。now()tstringt。strftime(mdY,H:M:S)12262022,14:38:47tstringt。strftime(bdY,H:M:S)Dec262022,14:39:32 Unix时间(POSIX时间或epoch时间)是一种将时间表示为单个数值的系统。它表示自1970年1月1日星期四00:00:00协调世界时(UTC)以来经过的秒数。 Unix时间和时间戳通常可以互换使用。Unix时间是创建时间戳的标准版本。一般情况下使用整数或浮点数据类型用于存储时间戳和Unix时间。 我们可以使用time模块的mktime方法将datetime对象转换为Unix时间整数。也可以使用datetime模块的fromtimestamp方法。convertdatetimetounixtimeimporttimefromdatetimeimportdatetimetdatetime。now()unixtint(time。mktime(t。timetuple()))1672055277convertunixtimetodatetimeunixt1672055277tdatetime。fromtimestamp(unixt)2022122614:47:57 使用dateutil模块来解析日期字符串获得datetime对象。fromdateutilimportparserdateparser。parse(29thofOctober,1923)datetime。datetime(1923,10,29,0,0) Pandas Pandas提供了三种日期数据类型: 1、Timestamp或DatetimeIndex:它的功能类似于其他索引类型,但也具有用于时间序列操作的专门函数。tpd。todatetime(29101923,dayfirstTrue)Timestamp(1923102900:00:00)tpd。Timestamp(20190101,tzEuropeBerlin)Timestamp(2019010100:00:000100,tzEuropeBerlin)tpd。todatetime(〔04231920,10291923〕)DatetimeIndex(〔19200423,19231029〕,dtypedatetime64〔ns〕,freqNone) 2、period或PeriodIndex:一个有开始和结束的时间间隔。它由固定的间隔组成。tpd。todatetime(〔04231920,10291923〕)periodt。toperiod(D)PeriodIndex(〔19200423,19231029〕,dtypeperiod〔D〕) 3、Timedelta或TimedeltaIndex:两个日期之间的时间间隔。deltapd。TimedeltaIndex(data〔1days03:00:00,2days09:05:01。000030〕)TimedeltaIndex(〔1days02:00:00,1days06:05:01。000030〕,dtypetimedelta64〔ns〕,freqNone) 在Pandas中,可以使用todatetime方法将对象转换为datetime数据类型或进行任何其他转换。importpandasaspddfpd。readcsv(dataset。txt)df。head()datevalue0199107013。5265911199108013。1808912199109013。2522213199110013。6110034199111013。565869df。info()classpandas。core。frame。DataFrameRangeIndex:204entries,0to203Datacolumns(total2columns):ColumnNonNullCountDtype0date204nonnullobject1value204nonnullfloat64dtypes:float64(1),object(1)memoryusage:3。3KBConverttodatetimedf〔date〕pd。todatetime(df〔date〕,formatYmd)df。info()classpandas。core。frame。DataFrameRangeIndex:204entries,0to203Datacolumns(total2columns):ColumnNonNullCountDtype0date204nonnulldatetime64〔ns〕1value204nonnullfloat64dtypes:datetime64〔ns〕(1),float64(1)memoryusage:3。3KBConverttoUnixdf〔unixtime〕df〔date〕。apply(lambdax:x。timestamp())df。head()datevalueunixtime0199107013。526591678326400。01199108013。180891681004800。02199109013。252221683683200。03199110013。611003686275200。04199111013。565869688953600。0df〔dateconvertedfromunix〕pd。todatetime(df〔unixtime〕,units)df。head()datevalueunixtimedateconvertedfromunix0199107013。526591678326400。0199107011199108013。180891681004800。0199108012199109013。252221683683200。0199109013199110013。611003686275200。0199110014199111013。565869688953600。019911101 我们还可以使用parsedates参数在任何文件加载时直接声明日期列。dfpd。readcsv(dataset。txt,parsedates〔date〕)df。info()classpandas。core。frame。DataFrameRangeIndex:204entries,0to203Datacolumns(total2columns):ColumnNonNullCountDtype0date204nonnulldatetime64〔ns〕1value204nonnullfloat64dtypes:datetime64〔ns〕(1),float64(1)memoryusage:3。3KB 如果是单个时间序列的数据,最好将日期列作为数据集的索引。df。setindex(date,inplaceTrue)Valuedate199107013。526591199108013。180891199109013。252221199110013。611003199111013。565869。。。。。。2008020121。6542852008030118。2649452008040123。1076772008050122。9125102008060119。431740 Numpy也有自己的datetime类型np。Datetime64。特别是在大型数据集时,向量化是非常有用的,应该优先使用。importnumpyasnparrdatenp。array(20000101,dtypenp。datetime64)arrdatearray(20000101,dtypedatetime64〔D〕)broadcastingarrdatearrdatenp。arange(30)array(〔20000101,20000102,20000103,20000104,20000105,20000106,20000107,20000108,20000109,20000110,20000111,20000112,20000113,20000114,20000115,20000116,20000117,20000118,20000119,20000120,20000121,20000122,20000123,20000124,20000125,20000126,20000127,20000128,20000129,20000130〕,dtypedatetime64〔D〕)有用的函数 下面列出的是一些可能对时间序列有用的函数。dfpd。readcsv(dataset。txt,parsedates〔date〕)df〔date〕。dt。dayname()0Monday1Thursday2Sunday3Tuesday4Friday。。。199Friday200Saturday201Tuesday202Thursday203SundayName:date,Length:204,dtype:object DataReader Pandasdatareader是pandas库的一个辅助库。它提供了许多常见的金融时间序列数据pipinstallpandasdatareaderfrompandasdatareaderimportwbGDPperCapitaFromWorldBankdfwb。download(indicatorNY。GDP。PCAP。KD,country〔US,FR,GB,DK,NO〕,start1960,end2019)NY。GDP。PCAP。KDcountryyearDenmark201957203。027794201856563。488473201755735。764901201654556。068955201553254。856370。。。。。。UnitedStates196421599。818705196320701。269947196220116。235124196119253。547329196019135。268182〔300rowsx1columns〕 日期范围 我们可以使用pandas的daterange方法定义一个日期范围。pd。daterange(start20210101,end20220101,freqD)DatetimeIndex(〔20210101,20210102,20210103,20210104,20210105,20210106,20210107,20210108,20210109,20210110,。。。20211223,20211224,20211225,20211226,20211227,20211228,20211229,20211230,20211231,20220101〕,dtypedatetime64〔ns〕,length366,freqD)pd。daterange(start20210101,end20220101,freqBM)DatetimeIndex(〔20210129,20210226,20210331,20210430,20210531,20210630,20210730,20210831,20210930,20211029,20211130,20211231〕,dtypedatetime64〔ns〕,freqBM)fridayspd。daterange(20221101,20221231,freqWFRI)DatetimeIndex(〔20221104,20221111,20221118,20221125,20221202,20221209,20221216,20221223,20221230〕,dtypedatetime64〔ns〕,freqWFRI) 我们可以使用timedeltarange方法创建一个时间序列。tpd。timedeltarange(0,periods10,freqH)TimedeltaIndex(〔0days00:00:00,0days01:00:00,0days02:00:00,0days03:00:00,0days04:00:00,0days05:00:00,0days06:00:00,0days07:00:00,0days08:00:00,0days09:00:00〕,dtypetimedelta64〔ns〕,freqH) 格式化 我们dt。strftime方法改变日期列的格式。df〔newdate〕df〔date〕。dt。strftime(bd,Y)df。head()datevaluenewdate0199107013。526591Jul01,19911199108013。180891Aug01,19912199109013。252221Sep01,19913199110013。611003Oct01,19914199111013。565869Nov01,1991 解析 解析datetime对象并获得日期的子对象。df〔year〕df〔date〕。dt。yeardf〔month〕df〔date〕。dt。monthdf〔day〕df〔date〕。dt。daydf〔calendar〕df〔date〕。dt。datedf〔hour〕df〔date〕。dt。timedf。head()datevalueyearmonthdaycalendarhour0199107013。5265911991711991070100:00:001199108013。1808911991811991080100:00:002199109013。2522211991911991090100:00:003199110013。61100319911011991100100:00:004199111013。56586919911111991110100:00:00 还可以重新组合它们。df〔datejoined〕pd。todatetime(df〔〔year,month,day〕〕)print(df〔datejoined〕)019910701119910801219910901319911001419911101。。。1992008020120020080301201200804012022008050120320080601Name:datejoined,Length:204,dtype:datetime64〔ns〕 过滤查询 使用loc方法来过滤DataFrame。dfdf。loc〔20210101:20210110〕 truncate可以查询两个时间间隔中的数据dftruncateddf。truncate(20210105,20220110) 常见数据操作 下面就是对时间序列数据集中的值执行操作。我们使用yfinance库创建一个用于示例的股票数据集。getgooglestockpricedataimportyfinanceasyfstartdate20200101enddate20230101tickerGOOGLdfyf。download(ticker,startdate,enddate)df。head()DateOpenHighLowCloseAdjCloseVolume2020010267。42050268。43399867。32450168。43399868。433998272780002020010367。40000268。68750067。36599768。07599668。075996234080002020010667。58149769。91600067。55000369。89050369。890503467680002020010770。02300370。17500369。57800369。75550169。755501343300002020010869。74099770。59249969。63150070。25199970。25199935314000 计算差值 diff函数可以计算一个元素与另一个元素之间的插值。subtractthatdaysvaluefromthepreviousdaydf〔DiffClose〕df〔Close〕。diff()Subtractthatdaysvaluefromthedaysvalue2daysagodf〔DiffClose2Days〕df〔Close〕。diff(periods2) 累计总数df〔VolumeCumulative〕df〔Volume〕。cumsum() 滚动窗口计算 滚动窗口计算(移动平均线)。df〔CloseRolling14〕df〔Close〕。rolling(14)。mean()df。tail() 可以对我们计算的移动平均线进行可视化 常用的参数:center:决定滚动窗口是否应以当前观测值为中心。minperiods:窗口中产生结果所需的最小观测次数。spd。Series(〔1,2,3,4,5〕)therollingwindowwillbecenteredoneachobservationrollingmeans。rolling(window3,centerTrue)。mean()0NaN12。023。034。04NaNdtype:float64Explanation:firstwindow:〔na12〕nasecondwindow:〔123〕2therollingwindowwillnotbecentered,andwillinsteadbeanchoredtotheleftsideofthewindowrollingmeans。rolling(window3,centerFalse)。mean()0NaN1NaN22。033。044。0dtype:float64Explanation:firstwindow:〔nana1〕nasecondwindow:〔na12〕nathirdwindow:〔123〕2 平移 Pandas有两个方法,shift()和tshift(),它们可以指定倍数移动数据或时间序列的索引。Shift()移位数据,而tshift()移位索引。shiftthedatadfshifteddf。shift(5,axis0)dfshifted。head(10)shifttheindexesdftshifteddf。tshift(periods4,freqD)dftshifted。head(10) dfshifted dftshifted 时间间隔转换 在Pandas中,操toperiod函数允许将日期转换为特定的时间间隔。可以获取具有许多不同间隔或周期的日期df〔Period〕df〔Date〕。dt。toperiod(W) 频率 Asfreq方法用于将时间序列转换为指定的频率。monthlydatadf。asfreq(M,methodffill) 常用参数: freq:数据应该转换到的频率。这可以使用字符串别名(例如,M表示月,H表示小时)或pandas偏移量对象来指定。 method:如何在转换频率时填充缺失值。这可以是ffill(向前填充)或bfill(向后填充)之类的字符串。 采样 resample可以改变时间序列频率并重新采样。我们可以进行上采样(到更高的频率)或下采样(到更低的频率)。因为我们正在改变频率,所以我们需要使用一个聚合函数(比如均值、最大值等)。 resample方法的参数: rule:数据重新采样的频率。这可以使用字符串别名(例如,M表示月,H表示小时)或pandas偏移量对象来指定。downsamplemonthlydatadf。resample(M)。mean() upsampleminutedatadata。resample(T)。ffill() 百分比变化 使用pctchange方法来计算日期之间的变化百分比。df〔PCT〕df〔Close〕。pctchange(periods2)print(df〔PCT〕)Date20200102NaN20200103NaN202001060。021283202001070。024671202001080。005172。。。202212190。026634202212200。013738202212210。012890202212220。014154202212230。003907Name:PCT,Length:752,dtype:float64总结 在Pandas和NumPy等库的帮助下,可以对时间序列数据执行广泛的操作,包括过滤、聚合和转换。本文介绍的是一些在工作中经常遇到的常见操作,希望对你有所帮助。 作者:OkanYenign