• 售前

  • 售后

热门帖子
入门百科

使用pandas按日期做分组运算的操纵

[复制链接]
wzyu638116 显示全部楼层 发表于 2021-10-26 13:36:49 |阅读模式 打印 上一主题 下一主题
原始数据
  1. TS PERIOD REQUEST STEPPED VALUE STATUS SECONDS
  2. 20-DEC-16 00:00:00.0 600 1 0  2.018 0 1482163200
  3. 20-DEC-16 00:01:00.0 600 1 0  2.019 0 1482163260
  4. 20-DEC-16 00:02:00.0 600 1 0  2.019 0 1482163320
  5. 20-DEC-16 00:03:00.0 600 1 0  2.019 0 1482163380
  6. 20-DEC-16 00:04:00.0 600 1 0  2.019 0 1482163440
  7. 20-DEC-16 00:05:00.0 600 1 0  2.020 0 1482163500
  8. 20-DEC-16 00:06:00.0 600 1 0  2.020 0 1482163560
复制代码
我们的目标是把TS列从
  1. 20-DEC-16 00:00:00.0
复制代码
变化为
  1. 20-DEC-16
复制代码
的格式,然后按天取均值。
导入包
  1. import numpy as np
  2. from pandas import DataFrame, Series
  3. import pandas as pd
  4. from datetime import datetime
复制代码
读入文件
  1. df = pd.read_csv('data/test.txt',sep='\t')
复制代码
这里没有办理中文路径名和绝对路径的题目.
转化为数据框
  1. df = DataFrame(df)
复制代码
转化为时间格式

将TS列转化为时间格式,并生存为新的一列DATE,之后,只留下DATE和VALUE两列,其他齐备不要。
  1. df['DATE'] = pd.to_datetime(df['TS'])
  2. df = df[['DATE','VALUE']]
复制代码
关键一步

把形如‘2017-9-4 00:00:00'转化为‘2017-9-4 '
  1. df['DATE'] = [datetime.strftime(x,'%Y-%m-%d') for x in df['DATE']]
复制代码
strftime有多少参数,其中Y表现四位数的年,m表现两位数的月。
旋转数据框
  1. df =df.pivot_table(index='DATE',aggfunc='mean')
复制代码
增补:利用Pandas和Numpy按时间戳将数据以Groupby方式分组
首先说一下需求,我须要将数据以分钟为单位举行分组,然后每一分钟内的数据作为一行输出,由于差别时间的数据量不一样,所以所有数据按照最长的那组数据为准,不敷的数据以各自的末了一个数据举行补足。
之后要先容一下我的数据源,之前没用的数据列已经去除,我只留下要用到的数据data列和时间戳time列,时间戳是以秒计的,可以看到一共是407454行。
  1.    data   time
  2. 0  6522.50 1.530668e+09
  3. 1  6522.66 1.530668e+09
  4. 2  6523.79 1.530668e+09
  5. 3  6523.79 1.530668e+09
  6. 4  6524.82 1.530668e+09
  7. 5  6524.35 1.530668e+09
  8. 6  6523.66 1.530668e+09
  9. 7  6522.64 1.530668e+09
  10. 8  6523.25 1.530668e+09
  11. 9  6523.88 1.530668e+09
  12. 10  6525.30 1.530668e+09
  13. 11  6525.70 1.530668e+09
  14. ...   ...   ...
  15. 407443 6310.69 1.531302e+09
  16. 407444 6310.55 1.531302e+09
  17. 407445 6310.42 1.531302e+09
  18. 407446 6310.40 1.531302e+09
  19. 407447 6314.03 1.531302e+09
  20. 407448 6314.04 1.531302e+09
  21. 407449 6312.84 1.531302e+09
  22. 407450 6312.57 1.531302e+09
  23. 407451 6312.56 1.531302e+09
  24. 407452 6314.04 1.531302e+09
  25. 407453 6314.04 1.531302e+09
  26. [407454 rows x 2 columns]
复制代码
开始举行数据处置处罚,界说一个函数,输入为一个DataFrame和时间列的定名。
  1. def getdata_time(dataframe,name):
  2. dataframe[name] = dataframe[name]/60 #将时间转换为分钟
  3. dataframe[name] = dataframe[name].astype('int64')
  4. datalen = dataframe.groupby(name).count().max()  #获取数据最大长度
  5. timeframe = dataframe.groupby(name).count().reset_index()#为了获取时间将分组后时间转换为DataFrame
  6. timeseries = timeframe['time']
  7. array = []  #建立一个空数组以便存值
  8. for time, group in dataframe.groupby(name):
  9. tmparray = numpy.array(group['data']) #将series转换为数组并添加到总数组中
  10. array.append(tmparray)
  11. notimedata = pandas.DataFrame(array)
  12. notimedata = notimedata.fillna(method='ffill',axis = 1,limit=datalen[0]) #将缺失值补全
  13. notimedata[datalen[0]+1] = timeseries #把时间添加到最后一列
  14. return notimedata
复制代码
下面将逐行举行分析,首先要以每分钟为依据举行分组,那么将秒计的时间戳除以60变为分钟,转换为int型是为了观察方便(更改类型是否会导致数据精度缺失影响结果并不清楚,假如有相识的人看到接待指出,谢谢)。
datalen是我们要用到的每分钟中最大的数据长度,用来作为标齐依据。DataFrame.groupby.count()是分别表现每组数据的个数,并不是表现有多少个分组,假如想要获取分组后每一组的index就须要用到下一行的reset_index方法,之所以不直接用reset_index而是在count()方法后调用是由于groupby分组后的结果不是一个DataFrame,而颠末count()(不光仅是count,对分组数据操作的方法都可以,只要得出的结果是与每一组的index一一对应即可)操作后就可以得到一个以index为一列,另一列是count结果的DataFrame。
以下为直接举行reset_index操作的报错:
  1. AttributeError: Cannot access callable attribute 'reset_index' of 'DataFrameGroupBy' objects, try using the 'apply' method
复制代码
以下为颠末count操作后的reset_index方法表现结果,可以看到一共分为了10397组:
  1.    time data
  2. 0  25511135 33
  3. 1  25511136 18
  4. 2  25511137 25
  5. 3  25511138 42
  6. 4  25511139 36
  7. 5  25511140  7
  8. 6  25511141 61
  9. 7  25511142 45
  10. 8  25511143 46
  11. 9  25511144 19
  12. 10  25511145 21
  13. ...   ... ...
  14. 10387 25521697  3
  15. 10388 25521698  9
  16. 10389 25521699 16
  17. 10390 25521700 13
  18. 10391 25521701  4
  19. 10392 25521702 34
  20. 10393 25521703 124
  21. 10394 25521704 302
  22. 10395 25521705 86
  23. 10396 25521706 52
  24. [10397 rows x 2 columns]
复制代码
提取的timeseries将在末了数据整适时利用。
如今开始将每组数据提取,首先建立一个空的数组用来存放,然后利用for循环获取每一组的信息,time即为分组的index,group即为每一分组的内容,将数据从group['data']中取出并添加到之前建立的空数组里,循环操作过后转换为DataFrame,当然这个DataFrame中包罗了大量缺失值,由于它的列数是以最长的数据为准。
如下:
  1.    0  1  2  3  ... 1143 1144 1145 1146
  2. 0  6522.50 6522.66 6523.79 6523.79 ... NaN NaN NaN NaN
  3. 1  6523.95 6524.90 6525.00 6524.35 ... NaN NaN NaN NaN
  4. 2  6520.87 6520.00 6520.45 6520.46 ... NaN NaN NaN NaN
  5. 3  6516.34 6516.26 6516.21 6516.21 ... NaN NaN NaN NaN
  6. 4  6513.28 6514.00 6514.00 6514.00 ... NaN NaN NaN NaN
  7. 5  6511.98 6511.98 6511.99 6513.00 ... NaN NaN NaN NaN
  8. 6  6511.00 6511.00 6511.00 6511.00 ... NaN NaN NaN NaN
  9. 7  6511.70 6511.78 6511.99 6511.99 ... NaN NaN NaN NaN
  10. 8  6509.51 6510.00 6510.80 6510.80 ... NaN NaN NaN NaN
  11. 9  6511.36 6510.00 6510.00 6510.00 ... NaN NaN NaN NaN
  12. 10  6507.00 6507.00 6507.00 6507.00 ... NaN NaN NaN NaN
  13. ...  ...  ...  ...  ... ... ... ... ... ...
  14. 10386 6333.77 6331.31 6331.30 6333.19 ... NaN NaN NaN NaN
  15. 10387 6331.68 6331.30 6331.68  NaN ... NaN NaN NaN NaN
  16. 10388 6331.30 6331.30 6331.00 6331.00 ... NaN NaN NaN NaN
  17. 10389 6330.93 6330.92 6330.92 6330.93 ... NaN NaN NaN NaN
  18. 10390 6330.83 6330.83 6330.90 6330.80 ... NaN NaN NaN NaN
  19. 10391 6327.57 6326.00 6326.00 6325.74 ... NaN NaN NaN NaN
  20. 10392 6327.57 6329.70 6328.85 6328.85 ... NaN NaN NaN NaN
  21. 10393 6323.54 6323.15 6323.15 6322.77 ... NaN NaN NaN NaN
  22. 10394 6311.00 6310.83 6310.83 6310.50 ... NaN NaN NaN NaN
  23. 10395 6311.45 6311.32 6310.01 6310.01 ... NaN NaN NaN NaN
  24. 10396 6310.46 6310.46 6310.56 6311.61 ... NaN NaN NaN NaN
  25. [10397 rows x 1147 columns]
复制代码
可以看到行数是分组个数,一共1147列也是最多的那组数据长度。
之后我们通过调用fillna方法将缺失值举行添补,method='ffill'是指以缺失值前一个数据为依据,axis = 1是以行为单位,limit是指最大添补长度。最终,把我们之前取得的timeseries添加到末了一列,就得到了需求的最闭幕果。
  1.    0  1  2  ...  1145  1146  1148
  2. 0  6522.50 6522.66 6523.79 ...  6522.14 6522.14 25511135
  3. 1  6523.95 6524.90 6525.00 ...  6520.00 6520.00 25511136
  4. 2  6520.87 6520.00 6520.45 ...  6517.00 6517.00 25511137
  5. 3  6516.34 6516.26 6516.21 ...  6514.00 6514.00 25511138
  6. 4  6513.28 6514.00 6514.00 ...  6511.97 6511.97 25511139
  7. 5  6511.98 6511.98 6511.99 ...  6511.00 6511.00 25511140
  8. 6  6511.00 6511.00 6511.00 ...  6510.90 6510.90 25511141
  9. 7  6511.70 6511.78 6511.99 ...  6512.09 6512.09 25511142
  10. 8  6509.51 6510.00 6510.80 ...  6512.09 6512.09 25511143
  11. 9  6511.36 6510.00 6510.00 ...  6507.04 6507.04 25511144
  12. 10  6507.00 6507.00 6507.00 ...  6508.57 6508.57 25511145
  13. 11  6507.16 6507.74 6507.74 ...  6506.35 6506.35 25511146
  14. ...  ...  ...  ... ...   ...  ...  ...
  15. 10388 6331.30 6331.30 6331.00 ...  6331.00 6331.00 25521698
  16. 10389 6330.93 6330.92 6330.92 ...  6330.99 6330.99 25521699
  17. 10390 6330.83 6330.83 6330.90 ...  6327.58 6327.58 25521700
  18. 10391 6327.57 6326.00 6326.00 ...  6325.74 6325.74 25521701
  19. 10392 6327.57 6329.70 6328.85 ...  6325.00 6325.00 25521702
  20. 10393 6323.54 6323.15 6323.15 ...  6311.00 6311.00 25521703
  21. 10394 6311.00 6310.83 6310.83 ...  6315.00 6315.00 25521704
  22. 10395 6311.45 6311.32 6310.01 ...  6310.00 6310.00 25521705
  23. 10396 6310.46 6310.46 6310.56 ...  6314.04 6314.04 25521706
  24. [10397 rows x 1148 columns]
复制代码
以上为个人经验,盼望能给各人一个参考,也盼望各人多多支持脚本之家。如有错误或未思量完全的地方,望不吝见教。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作