用pandas批量分组处理excel数据

需求比较简单,按照指定字段分组,计算指定字段的和或均值。
用SQL处理的话就一个groupby,可是没有数据库环境,只好用python(比起SQL真的是一点也不方便)处理excel文件。
学习了:

  1. 批量读取一个文件夹下所有excel文件,读、追加写入excel文件。
  2. 用pandas的groupby方法,还是比不上SQL,只找到了在分组时加过滤条件的方法,没有找到在计算时加过滤条件的方法,这样的话就跟用pivot_table没什么区别,还更复杂费代码,在生成多级列名时也麻烦些。
  3. 学习了pandas.concat里生成多级表头(或者行名、列名)的方法。
  4. 用pandas的透视表pivot_table方法,处理一般需求都够用,代码量少。
  5. 用matplotlib.pylot画图,画出的图也是动态的,但是一保存就成静态的了。
  6. 用pyecharts画图,画出的图像股票K线图一样好用,可以保存成html的动态的图。
  7. 尝试了网友的减少DataFrame占用的内存的方法,有效,但是未解决python.exe占用太多内存的原因。
  8. 学习了DataFrame里过滤数据,增加新列,补齐填充数据的方法。
  9. 学习了用apply, lambda处理DataFrame里时间字段date转str的方法。
  10. 使用了接受ctl+c跳出循环的方法
  11. 尝试了modin.pandas,的确可以起多个线程充分利用多核CPU进行计算,但是遇到处理不了的错误,还是放弃使用了。

python代码

#import modin.pandas as pd
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pyecharts.charts import Line
from pyecharts import options as opt
import os
import timecol_year = 'V04001'
col_month = 'V04002'
col_day = 'V04003'
col_hour = 'V04004'calcColumn1 = 'V13019'
calcColumn2 = 'V12001'filesDir = input("请输入要分组计算的excel文件所在的路径(如e:\\data1):")
if filesDir == '':filesDir=r'E:\data1'
pilotPic = input("是否要画matpilot图,是输入1,否输入0:")
if pilotPic == '':pilotPic=0
echartPic = input("是否要画echart图,是输入1,否输入0:")
if echartPic == '':echartPic=0NAlist = []
#网友的减少DataFrame占用的内存的方法,props是properties,代表DF
def reduce_mem_usage(props):# 计算当前内存start_mem_usg = props.memory_usage().sum() / 1024 ** 2print("Memory usage of the dataframe is :", start_mem_usg, "MB")# 哪些列包含空值,空值用-999填充。why:因为np.nan当做float处理NAlist = []for col in props.columns:# 这里只过滤了objectd格式,如果你的代码中还包含其他类型,请一并过滤if (props[col].dtypes != object):  # Exclude stringsprint("**************************")print("columns: ", col)print("dtype before", props[col].dtype)# 判断是否是int类型isInt = Falsemmax = props[col].max()mmin = props[col].min()# Integer does not support NA, therefore Na needs to be filledif not np.isfinite(props[col]).all():NAlist.append(col)props[col].fillna(0, inplace=True) # 用0填充# test if column can be converted to an integerasint = props[col].fillna(0).astype(np.int64)result = np.fabs(props[col] - asint)result = result.sum()if result < 0.01: # 绝对误差和小于0.01认为可以转换的,要根据task修改isInt = True# make interger / unsigned Integer datatypesif isInt:if mmin >= 0: # 最小值大于0,转换成无符号整型if mmax <= 255:props[col] = props[col].astype(np.uint8)elif mmax <= 65535:props[col] = props[col].astype(np.uint16)elif mmax <= 4294967295:props[col] = props[col].astype(np.uint32)else:props[col] = props[col].astype(np.uint64)else: # 转换成有符号整型if mmin > np.iinfo(np.int8).min and mmax < np.iinfo(np.int8).max:props[col] = props[col].astype(np.int8)elif mmin > np.iinfo(np.int16).min and mmax < np.iinfo(np.int16).max:props[col] = props[col].astype(np.int16)elif mmin > np.iinfo(np.int32).min and mmax < np.iinfo(np.int32).max:props[col] = props[col].astype(np.int32)elif mmin > np.iinfo(np.int64).min and mmax < np.iinfo(np.int64).max:props[col] = props[col].astype(np.int64)  else: # 注意:这里对于float都转换成float16,需要根据你的情况自己更改props[col] = props[col].astype(np.float16)print("dtype after", props[col].dtype)print("********************************")print("___MEMORY USAGE AFTER COMPLETION:___")mem_usg = props.memory_usage().sum() / 1024**2 print("Memory usage is: ",mem_usg," MB")print("This is ",100*mem_usg/start_mem_usg,"% of the initial size")print("_________________\n")print("Warning: the following columns have missing values filled with '0': ")print(NAlist)print("_________________\n")return props, NAlist#获取目录下的所有xlsx文件,遍历处理
for root, dirs, files in os.walk(filesDir):print('root_dir:', root)  # 当前目录路径print('sub_dirs:', dirs)  # 当前路径下所有子目录print('files:', files)  # 当前路径下所有非目录子文件for filename in files:filepath = root+"\\"+filenametime1 = time.time()try:#print('建writer')writer = pd.ExcelWriter(filepath, mode='a', engine='openpyxl') #可以追加写入 # pylint: disable=abstract-class-instantiated#print('read_excel')data = pd.read_excel(writer,sheet_name=0)#data, NAlist = reduce_mem_usage(data)  #减少内存占用except KeyboardInterrupt:writer.close()os._exit(-1)except (IOError,KeyError) as e1:print("%s can't be read. File may be corrupt." %filepath )#logging.exception(e1)continuetime2 = time.time()print("读取表格%s耗时%d秒." %(filename, int(time2-time1)))#过滤掉999999,999998数据异常的数据data = data[(~data[calcColumn1].isin([999999,999998]))&(True^data[calcColumn2].isin([999999,999998]))]#增加date列,拼接年月日字段,并把月日字段用0左补齐为2位#data['date']=data[col_year].map(str)+data[col_month].map(lambda x : "%02d"%x)+data[col_day].map(lambda x : "%02d"%x) # pylint: disable=abstract-class-instantiated#增加偏移日期列,data['shift_datetime']=pd.to_datetime(data['OB_TIME'].map(str))+pd.DateOffset(hours=3)data['shift_yyyymmdd']=data['shift_datetime'].apply(lambda x: x.strftime('%Y%m%d'))data['shift_HH']=data['shift_datetime'].apply(lambda x: int(x.strftime('%H')))  #转成int型才能判断大小groupbylist = ['V01301', 'shift_yyyymmdd']#data.to_excel(writer, sheet_name='newdata')'''#分组计算方法一:建透视图data1=data[ (data[col_hour] >= 8) & (data[col_hour] <= 20) ]data2=data[ (data[col_hour] > 20) | (data[col_hour] < 8) ]result1=data1.pivot_table(index=groupbylist,values=[calcColumn1,calcColumn2],aggfunc={calcColumn1:np.sum, calcColumn2:[min, max, np.mean]})result2=data2.pivot_table(index=groupbylist,values=[calcColumn1,calcColumn2],aggfunc={calcColumn1:np.sum, calcColumn2:[min, max, np.mean]})result=pd.concat([result1,result2],axis=1)#把透视图保存到新一页result.to_excel(writer, sheet_name='pilot1')''' #分组计算方法二:调用groupby,合并成一张表#print('分组计算')group_all1 = data[ (data['shift_HH'] >= 0) & (data['shift_HH'] <= 11) ].groupby(groupbylist)#可以用 group_all1 = data[lambda x: (x[col_hour] >= 8) & (x[col_hour] <= 20)].groupby(groupbylist)df1_sum = group_all1[calcColumn1].sum()#df1_mean= group_all1[calcColumn2].mean()#df1_concat = pd.concat([df1_sum,df1_mean],axis=1,keys=[('day','sum'),('day','mean')])group_all2 = data[ (data['shift_HH'] >= 12) & (data['shift_HH'] <= 23) ].groupby(groupbylist)df2_sum = group_all2[calcColumn1].sum()#df2_mean= group_all2[calcColumn2].mean()#df2_concat = pd.concat([df2_sum,df2_mean],axis=1,keys=[('night','sum'),('night','mean')])df3_sum = data.groupby(groupbylist)[calcColumn1].sum()#result = pd.concat([df1_concat,df2_concat],axis=1)result = pd.concat([df1_sum,df2_sum,df3_sum],axis=1,keys=['20-08时','08-20时','20-20时'])#add column for date#result['date']=result.index.to_list()#把分组汇总数据追加保存到原表的新一页print('写入表格')result.to_excel(writer, sheet_name='groupby1')#print('关闭writer')writer.close()time3 = time.time()print("写入表格耗时 %d seconds." %int(time3-time2))if pilotPic == 1:#用matplotlib.pyplot画折线图plt.xlabel("Date(YYYMMDD)")  # X轴标签plt.ylabel("Sum")  # Y轴标签plt.plot(result.index.get_level_values('date'), result[calcColumn1]['sum'], 'r--', linewidth=3, label='Sum of %s'%calcColumn1)plt.legend()#plt.savefig(root+"\\"+filename.split('.')[0]+"_V13019_sum.png")  # 保存图plt.show()plt.ylabel("Mean")  # Y轴标签plt.plot(result.index.get_level_values('date'), result[calcColumn2]['mean'], 'r--', linewidth=3, label='Mean of %s'%calcColumn2)plt.legend()#plt.savefig(root+"\\"+filename.split('.')[0]+"_V12001_mean.png")  # 保存图,要先保存再显示,不然是空的。plt.show()#用pandas.plot画折线图#result.plot(kind='line',x='date',y='V13019',linestyle='-', marker='o', markerfacecolor='red', color='green', figsize=(8,4), title='Picture 1 : Trend of V13019\n')#result.plot(kind='line',x='date',y='V12001',linestyle='-', marker='o', markerfacecolor='red', color='green', figsize=(8,4), title='Picture 2 : Trend of V12001\n')#print(result)#用pyecharts画折线图if echartPic == 1:result.sort_index(inplace=True)line = Line()line.add_xaxis(result['date'])line.add_yaxis('%s求和'%calcColumn1,result[calcColumn1])line.add_yaxis('%s求均值'%calcColumn2,result[calcColumn2])line.set_global_opts(xaxis_opts=opt.AxisOpts(type_='category'),title_opts=opt.TitleOpts(title='日折线图'),tooltip_opts=opt.TooltipOpts(trigger='axis',axis_pointer_type='cross') #展示动态十字标)line.render(root+"\\"+filename.split('.')[0]+'日折线图.html')

遇到的问题

用pandas的ExcelWriter读excel,并期望可以追加数据到原文件时,发现2个问题:

  1. 不加engine时在我的电脑可以执行,但是在别人的电脑提示错误,百度到其他人的经验是默认用xlwt不支持追加,要指定engine为openpyxl,这样修改后可以执行
    pd.ExcelWriter(filepath, mode=‘a’, engine=‘openpyxl’)
    ExcelWriter
  2. 加了engine在我电脑也运行正常,但是今天尝试直接用python IDLE执行,居然报错,如下:
    writer = pd.ExcelWriter(filepath, mode='a', engine='openpyxl') #可以追加写入 # pylint: disable=abstract-class-instantiatedFile "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\io\excel\_openpyxl.py", line 25, in __init__book = load_workbook(self.path)File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\openpyxl\reader\excel.py", line 314, in load_workbookreader.read()File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\openpyxl\reader\excel.py", line 273, in readself.read_manifest()File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\openpyxl\reader\excel.py", line 134, in read_manifestsrc = self.archive.read(ARC_CONTENT_TYPES)File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\zipfile.py", line 1475, in readwith self.open(name, "r", pwd) as fp:File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\zipfile.py", line 1514, in openzinfo = self.getinfo(name)File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\zipfile.py", line 1441, in getinforaise KeyError(
KeyError: "There is no item named '[Content_Types].xml' in the archive"

发现是一个excel文件在中断读写时被破坏了,于是加了个例外处理以规避:

except (IOError,KeyError) as e1:print("%s can't be read. File may be corrupt." %filepath )#logging.exception(e1)continue

中断读写excel文件容易损坏文件的问题

在批量处理excel文件时发现中途如果要ctl+c中断程序,特别容易导致文件被破坏,只有3K大小了,加了例外处理也还是会有破坏的情况,目前不知如何完美规避,只知道别拼命多按ctl+c,只按一下,等待程序终止,这样貌似pandas可以慢慢回写完数据,不容易损坏文件。

except KeyboardInterrupt:writer.close()os._exit(-1)

用pandas批量分组处理excel数据相关推荐

  1. python《pandas入门》实现Excel数据字段的拆分

    ** python<pandas入门>实现Excel数据字段的拆分 ,简单说一下自己为什么写博客,主要原因如下: 1,先简单介绍下自己,我是药学本科毕业,工作几年了.在这几年里做过药物相关 ...

  2. R语言批量读取写入Excel数据 r导出输出写入excel多个sheet 导出excel 导入 excel 读入excel 表格

    前一段,写过一篇:R语言中写入Excel的不同sheet表格,最近学习了tidyverse的方法,感觉需要总结一下,更新一下知识结构. 本文准备用实际数据,做一下操作: 「批量读取:」 批量读取多个E ...

  3. R语言批量读取写入Excel数据

    本文准备用实际数据,做一下操作: 「批量读取:」 批量读取多个Excel数据 批量读取一个Excel数据的不同表格 「批量写入」 批量写入Excel数据 1,批量写入到不同的Excel中 2,批量写入 ...

  4. Python批量处理大量excel数据(含完整代码)

    Python批量处理excel数据(含完整代码) pandas库可以有效的处理excel.csv和txt文件,并能多格式将数据重新保存为excel.csv和txt文件. 一.导入数据 利用pandas ...

  5. python pandas csv读取_如何用 pandas 读取 csv 和 Excel 数据

    本文采用真实的股票数据作为案例,教你如何在Python中读取常用的数据文件. 内容: 读取csv数据 读取Excel数据 合并多张表 数据文件下载地址: 读取csv数据 csv文件用逗号来分隔数值,是 ...

  6. python用pandas读取excel_Python 中利用Pandas处理复杂的Excel数据

    关于Excel数据处理,很多同学可能使用过Pyhton的pandas模块,用它可以轻松地读取和转换Excel数据.但是实际中Excel表格结构可能比较杂乱,数据会分散不同的工作表中,而且在表格中分布很 ...

  7. 数据分析三、pandas库 分组聚合与数据可视化

    分组聚合与数据可视化 一.分组聚合 1.1.单层分组聚合:df.groupby(by)['列索引'].mean(). 1.1.1单层分组:df.groupby(by) 1.1.2聚合操作:['列索引' ...

  8. pandas访问分组里面的数据_实战用pandas+PyQt5制作一款数据分组透视处理工具

    早起导读:pandas是Python数据处理的利器,如果每天都要使用pandas执行同样的操作,如何制作一个有界面的软件更高效的完成?本文提供了一种基于PyQt5的实现思路. 关键词:pandas P ...

  9. python用pandas读取excel_浅谈python之利用pandas和openpyxl读取excel数据

    在学接口自动化测试时, 需要从excel中读取测试用例的数据, 假如我的数据是这样的: 最好是每行数据对应着一条测试用例, 为方便取值, 我选择使用pandas库, 先安装 pip install p ...

最新文章

  1. smali to java_Smali —— 数学运算,条件判断,循环
  2. AlexNet:深度卷积神经网络的ImageNet分类
  3. 新信号!阿里 AI 工程师趋于年轻化,高端AI人才严重短缺
  4. bash魔法堂:History用法详解
  5. 中科大计算机应用,中科大2012计算机应用专业考研初试考什么
  6. Linux上装vscode需要认证,linux系统安装vscode方法 ubuntu等系统上部署VisualStudioCode
  7. 高等数学下-赵立军-北京大学出版社-题解-练习8.5
  8. stm32f103r6最小系统原理图_超强PCB布线设计经验谈附原理图
  9. ES6高级使用技巧(reduce,filter篇)
  10. matlab 实现 kmeans聚类,gscatter的应用
  11. 12_通过上下文操作私有目录模式说明
  12. 脉宽调制功能(PWM)
  13. 作为大数据技术面试官,我喜欢什么样的应届毕业生?
  14. backdrop-filter: blur() safari 浏览器 无效 解决
  15. 自己的电脑不能连接打印机打印怎么办
  16. 专业英语---短语篇
  17. 峰值检测电路和精密整流电路
  18. Win11校园网无法连接怎么办?Win11连接不到校园网的解决方法
  19. YOLO-V5 算法和代码解析系列 —— 学习路线规划综述
  20. CDC CClientDC CPen CBrush使用

热门文章

  1. 读书分享:《数学之美》中的一些关键名词
  2. MySQL DQL操作之基础查询
  3. 安卓和鸿蒙系统,对标Apple Watch!魅族推首款智能手表,官宣接入华为鸿蒙系统...
  4. 前端面试之浏览器原理篇
  5. `Error:(11) No resource identifier found for attribute 'srcCompat' in package 'com.codifythings.ligh
  6. cups ipp oracle,CUPS cups/ipp.c空指针引用拒绝服务漏洞
  7. Facebook 如何存储150亿张、1.5PB的照片
  8. python 会计分录模板_财务月末结账会计分录
  9. 双硬盘安装win10和linux双系统,双硬盘安装win10+ubuntu18心得
  10. 创业教父YC创始人Paul Graham就很烦鼓动年轻创业的