利用Pandas和Numpy按时间戳将数据以Groupby方式分组
首先说一下需求,我需要将数据以分钟为单位进行分组,然后每一分钟内的数据作为一行输出,因为不同时间的数据量不一样,所以所有数据按照最长的那组数据为准,不足的数据以各自的最后一个数据进行补足。
之后要介绍一下我的数据源,之前没用的数据列已经去除,我只留下要用到的数据data列和时间戳time列,时间戳是以秒计的,可以看到一共是407454行。
datatime 06522.501.530668e+09 16522.661.530668e+09 26523.791.530668e+09 36523.791.530668e+09 46524.821.530668e+09 56524.351.530668e+09 66523.661.530668e+09 76522.641.530668e+09 86523.251.530668e+09 96523.881.530668e+09 106525.301.530668e+09 116525.701.530668e+09 ......... 4074436310.691.531302e+09 4074446310.551.531302e+09 4074456310.421.531302e+09 4074466310.401.531302e+09 4074476314.031.531302e+09 4074486314.041.531302e+09 4074496312.841.531302e+09 4074506312.571.531302e+09 4074516312.561.531302e+09 4074526314.041.531302e+09 4074536314.041.531302e+09 [407454rowsx2columns]
开始进行数据处理,定义一个函数,输入为一个DataFrame和时间列的命名。
defgetdata_time(dataframe,name): dataframe[name]=dataframe[name]/60#将时间转换为分钟 dataframe[name]=dataframe[name].astype('int64') datalen=dataframe.groupby(name).count().max()#获取数据最大长度 timeframe=dataframe.groupby(name).count().reset_index()#为了获取时间将分组后时间转换为DataFrame timeseries=timeframe['time'] array=[]#建立一个空数组以便存值 fortime,groupindataframe.groupby(name): tmparray=numpy.array(group['data'])#将series转换为数组并添加到总数组中 array.append(tmparray) notimedata=pandas.DataFrame(array) notimedata=notimedata.fillna(method='ffill',axis=1,limit=datalen[0])#将缺失值补全 notimedata[datalen[0]+1]=timeseries#把时间添加到最后一列 returnnotimedata
下面将逐行进行分析,首先要以每分钟为依据进行分组,那么将秒计的时间戳除以60变为分钟,转换为int型是为了观察方便(更改类型是否会导致数据精度缺失影响结果并不清楚,如果有了解的人看到欢迎指出,谢谢)。
datalen是我们要用到的每分钟中最大的数据长度,用来作为标齐依据。DataFrame.groupby.count()是分别显示每组数据的个数,并不是显示有多少个分组,如果想要获取分组后每一组的index就需要用到下一行的reset_index方法,之所以不直接用reset_index而是在count()方法后调用是因为groupby分组后的结果不是一个DataFrame,而经过count()(不仅仅是count,对分组数据操作的方法都可以,只要得出的结果是与每一组的index一一对应即可)操作后就可以得到一个以index为一列,另一列是count结果的DataFrame。以下为直接进行reset_index操作的报错:
AttributeError:Cannotaccesscallableattribute'reset_index'of'DataFrameGroupBy'objects,tryusingthe'apply'method
以下为经过count操作后的reset_index方法显示结果,可以看到一共分为了10397组:
timedata 02551113533 12551113618 22551113725 32551113842 42551113936 5255111407 62551114161 72551114245 82551114346 92551114419 102551114521 ......... 10387255216973 10388255216989 103892552169916 103902552170013 10391255217014 103922552170234 1039325521703124 1039425521704302 103952552170586 103962552170652 [10397rowsx2columns]
提取的timeseries将在最后数据整合时使用。现在开始将每组数据提取,首先建立一个空的数组用来存放,然后利用for循环获取每一组的信息,time即为分组的index,group即为每一分组的内容,将数据从group['data']中取出并添加到之前建立的空数组里,循环操作过后转换为DataFrame,当然这个DataFrame中包含了大量缺失值,因为它的列数是以最长的数据为准。如下:
0123...1143114411451146 06522.506522.666523.796523.79...NaNNaNNaNNaN 16523.956524.906525.006524.35...NaNNaNNaNNaN 26520.876520.006520.456520.46...NaNNaNNaNNaN 36516.346516.266516.216516.21...NaNNaNNaNNaN 46513.286514.006514.006514.00...NaNNaNNaNNaN 56511.986511.986511.996513.00...NaNNaNNaNNaN 66511.006511.006511.006511.00...NaNNaNNaNNaN 76511.706511.786511.996511.99...NaNNaNNaNNaN 86509.516510.006510.806510.80...NaNNaNNaNNaN 96511.366510.006510.006510.00...NaNNaNNaNNaN 106507.006507.006507.006507.00...NaNNaNNaNNaN .............................. 103866333.776331.316331.306333.19...NaNNaNNaNNaN 103876331.686331.306331.68NaN...NaNNaNNaNNaN 103886331.306331.306331.006331.00...NaNNaNNaNNaN 103896330.936330.926330.926330.93...NaNNaNNaNNaN 103906330.836330.836330.906330.80...NaNNaNNaNNaN 103916327.576326.006326.006325.74...NaNNaNNaNNaN 103926327.576329.706328.856328.85...NaNNaNNaNNaN 103936323.546323.156323.156322.77...NaNNaNNaNNaN 103946311.006310.836310.836310.50...NaNNaNNaNNaN 103956311.456311.326310.016310.01...NaNNaNNaNNaN 103966310.466310.466310.566311.61...NaNNaNNaNNaN [10397rowsx1147columns]
可以看到行数是分组个数,一共1147列也是最多的那组数据长度。
之后我们通过调用fillna方法将缺失值进行填充,method='ffill'是指以缺失值前一个数据为依据,axis=1是以行为单位,limit是指最大填充长度。最终,把我们之前取得的timeseries添加到最后一列,就得到了需求的最终结果。
012...114511461148 06522.506522.666523.79...6522.146522.1425511135 16523.956524.906525.00...6520.006520.0025511136 26520.876520.006520.45...6517.006517.0025511137 36516.346516.266516.21...6514.006514.0025511138 46513.286514.006514.00...6511.976511.9725511139 56511.986511.986511.99...6511.006511.0025511140 66511.006511.006511.00...6510.906510.9025511141 76511.706511.786511.99...6512.096512.0925511142 86509.516510.006510.80...6512.096512.0925511143 96511.366510.006510.00...6507.046507.0425511144 106507.006507.006507.00...6508.576508.5725511145 116507.166507.746507.74...6506.356506.3525511146 ........................ 103886331.306331.306331.00...6331.006331.0025521698 103896330.936330.926330.92...6330.996330.9925521699 103906330.836330.836330.90...6327.586327.5825521700 103916327.576326.006326.00...6325.746325.7425521701 103926327.576329.706328.85...6325.006325.0025521702 103936323.546323.156323.15...6311.006311.0025521703 103946311.006310.836310.83...6315.006315.0025521704 103956311.456311.326310.01...6310.006310.0025521705 103966310.466310.466310.56...6314.046314.0425521706 [10397rowsx1148columns]
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。