影刀RPA Excel数据透视表:分组统计基础

影刀RPA Excel数据透视表:分组统计基础

影刀RPA Excel数据透视表:分组统计基础

作者:林焱

什么情况用什么

有一张几万行的销售明细表,需要按地区统计销售额、按月份统计订单数、按产品类别统计占比——手动做透视表每次都要重新拖拽。在影刀RPA里用pandas的pivot_table可以自动完成分组统计,比Excel透视表更灵活、更快,还能批量处理多个文件。

适用场景:销售数据按地区/产品/时间汇总、考勤数据按部门统计天数、财务数据按科目汇总金额、多维度交叉分析。

怎么做

基础分组统计

importpandasaspd# 读取销售明细df=pd.read_excel(r"C:\Data\sales_detail.xlsx")# 按地区统计销售额和订单数result=df.groupby('地区').agg(订单数=('订单ID','count'),[video(video-dTWvvdps-1783501587232)(type-csdn)(url-https://live.csdn.net/v/embed/525000)(image-https://v-blog.csdnimg.cn/asset/23da3fe1f67a47106d725406cfde9a97/cover/Cover0.jpg)(title-拼多多店群自动化上架方案)]总金额=('金额','sum'),平均金额=('金额','mean'),最大金额=('金额','max')).reset_index()result.to_excel(r"C:\Data\sales_by_region.xlsx",index=False)

透视表(交叉分析)

# 按地区(行)× 产品类别(列)交叉统计销售额pivot=pd.pivot_table(df,values='金额',# 要统计的值index='地区',# 行分组columns='产品类别',# 列分组aggfunc='sum',# 聚合方式fill_value=0,# 空值填充0margins=True,# 添加合计行/列margins_name='总计')pivot.to_excel(r"C:\Data\sales_pivot.xlsx")

多维度分组

# 按地区+月份+产品类别三级分组df['月份']=pd.to_datetime(df['日期']).dt.to_period('M').astype(str)result=df.groupby(['地区','月份','产品类别']).agg(订单数=('订单ID','count'),总金额=('金额','sum')).reset_index()# 生成多层表头Excelresult.to_excel(r"C:\Data\multi_dim_report.xlsx",index=False)

在影刀RPA中的完整流程

1. 【打开Excel文件】→ 读取销售明细 2. 【执行Python代码】→ pandas分组统计 3. 【执行Python代码】→ 生成透视表 4. 【写入Excel文件】→ 保存结果 5. 【发送邮件】→ 自动发送报表

完整代码:

importpandasaspdimportopenpyxlfromopenpyxl.stylesimportFont,PatternFill,Alignment,Border,Sidedefgenerate_pivot_report(input_path,output_path):"""生成数据透视报表"""# 1. 读取数据df=pd.read_excel(input_path)# 2. 数据预处理df['日期']=pd.to_datetime(df['日期'],errors='coerce')df['月份']=df['日期'].dt.to_period('M').astype(str)df['金额']=pd.to_numeric(df['金额'],errors='coerce').fillna(0)# 3. 生成多个统计表withpd.ExcelWriter(output_path,engine='openpyxl')aswriter:# 表1:按地区统计by_region=df.groupby('地区').agg(订单数=('订单ID','count'),总金额=('金额','sum'),平均金额=('金额','mean')).round(2).reset_index()by_region.to_excel(writer,sheet_name='按地区统计',index=False)# 表2:按月份统计趋势by_month=df.groupby('月份').agg(订单数=('订单ID','count'),总金额=('金额','sum')).reset_index()by_month.to_excel(writer,sheet_name='按月趋势',index=False)# 表3:交叉透视表pivot=pd.pivot_table(df,values='金额',index='地区',columns='产品类别',aggfunc='sum',fill_value=0,margins=True,margins_name='合计')pivot.to_excel(writer,sheet_name='交叉分析')# 表4:TOP10产品top10=df.groupby('产品名称').agg(总金额=('金额','sum'),订单数=('订单ID','count')).sort_values('总金额',ascending=False).head(10).reset_index()top10.to_excel(writer,sheet_name='TOP10产品',index=False)# 4. 美化格式wb=openpyxl.load_workbook(output_path)forwsinwb.worksheets:# 表头样式forcellinws[1]:cell.font=Font(name='微软雅黑',size=11,bold=True,color='FFFFFF')cell.fill=PatternFill(start_color='1F4E79',end_color='1F4E79',fill_type='solid')cell.alignment=Alignment(horizontal='center',vertical='center')# 列宽自适应forcolinws.columns:max_length=max(len(str(cell.valueor''))forcellincol)ws.column_dimensions[col[0].column_letter].width=min(max_length+4,30)wb.save(output_path)returnoutput_path# 在影刀【执行Python代码】节点中调用generate_pivot_report(r"C:\Data\sales_detail.xlsx",r"C:\Data\sales_report.xlsx")

动态分组统计

不固定分组字段,根据配置文件动态选择:

defdynamic_groupby(df,group_cols,agg_config):""" 动态分组统计 agg_config: {'列名': '聚合方式'} 如 {'金额': 'sum', '订单ID': 'count'} """agg_dict={}forcol,funcinagg_config.items():iffunc=='count':agg_dict[col]=(col,'count')eliffunc=='sum':agg_dict[col]=(col,'sum')eliffunc=='mean':agg_dict[col]=(col,'mean')![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3e597d97a4554890b392b90fc2837d3c.png#pic_center)result=df.groupby(group_cols).agg(**agg_dict).reset_index()returnresult# 使用df=pd.read_excel(r"C:\Data\sales.xlsx")result=dynamic_groupby(df,group_cols=['地区','产品类别'],agg_config={'金额':'sum','订单ID':'count'})

有什么坑

坑1:分组后索引变成MultiIndex

groupby多个列后,结果的索引变成多层索引,直接to_excel格式很乱:

# 问题:多列分组后索引变成MultiIndexresult=df.groupby(['地区','月份']).agg({'金额':'sum'})# result的索引是(地区, 月份)的MultiIndex# 解决:加reset_index()result=df.groupby(['地区','月份']).agg({'金额':'sum'}).reset_index()# 现在地区和月份是普通列

坑2:agg函数列名混乱

TEMU店群如何管理运营?

聚合后列名变成元组或多层列名,不好处理:

# 问题:这种方式生成的列名是('金额', 'sum')这种多层列名result=df.groupby('地区').agg({'金额':['sum','mean','count']})# 解决:用命名聚合(pandas 0.25+)result=df.groupby('地区').agg(总金额=('金额','sum'),平均金额=('金额','mean'),订单数=('金额','count')# 或 ('订单ID', 'count')).reset_index()

坑3:透视表的合计行排序

pivot_table加了margins=True后,"合计"行排在最后是按字母排序的,中文"合计"可能排到中间:

# 问题:margins_name='合计',但"合计"按拼音排序可能不在最后pivot=pd.pivot_table(df,values='金额',index='地区',columns='产品',aggfunc='sum',fill_value=0,margins=True,margins_name='合计')# 解决:生成后手动调整行顺序row_order=[rforrinpivot.indexifr!='合计']+['合计']pivot=pivot.loc[row_order]

坑4:日期分组时NaT导致报错

日期列有空值时,转period会生成NaT,groupby会报错或产生意外分组:

# 问题:日期列有空值df['日期']=pd.to_datetime(df['日期'],errors='coerce')df['月份']=df['日期'].dt.to_period('M')# 空值变NaT# groupby时NaT会被忽略,但可能导致分组数变少result=df.groupby('月份').agg({'金额':'sum'})# 解决:先处理空值df=df.dropna(subset=['日期'])# 删掉日期为空的行# 或者df['月份']=df['月份'].fillna('未知月份').astype(str)

坑5:大数据量内存溢出

几十万行数据做透视表,pandas默认会把所有数据加载到内存,可能内存不够:

# 方案1:只读取需要的列df=pd.read_excel(file_path,usecols=['地区','产品','金额','日期'])# 方案2:分块读取后合并chunks=pd.read_excel(file_path,chunksize=50000)results=[]forchunkinchunks:![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e4107841f0624c92b6c6b50dfb3248e6.png#pic_center)![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/8f687766fdbb4a0c9bf7e0f85217873b.png#pic_center)r=chunk.groupby('地区').agg({'金额':'sum'})results.append(r)final=pd.concat(results).groupby(level=0).sum()# 合并各块的统计结果# 方案3:用dtype优化内存df=pd.read_excel(file_path,dtype={'地区':'category','产品':'category'})