当前位置: 首页 > 后端技术 > Python

PythonOA|自动更新非对称表

时间:2023-03-25 23:56:27 Python

作者:陈曦来源:早起Python大家好,又到了pythonOA的话题了。之前我们详细讲解了如何使用Python自动更新Excel表格和调整样式。在上一个自动化案例中,两个或多个Excel表格数据需要匹配/对称才能自动更新。今天我们就来解决数据不一致的问题。如何在对称的情况下自动更新表,这是比较常见的情况,也是我遇到的具体需求。需求分析现在我们有一个记录神奇宝贝名称的分组列表,如下所示:(不是全部显示,实际上有A-U组+1个“未分组”)现在有一个更新的列表(只有名称)需要基于这个新列表更新原来的总表,即新列表中的名字按照总表的分组进行更新,不在新列表中的名字被淘汰,不在新列表中的名字被剔除出现在新榜单中的分为“未分组”,如上图所示,读者“早起”的需求是一个需要长时间重复的任务,每隔一次就会得到一个新榜单过一会儿,需要调整总表。如果使用Excel操作,可能需要反复查找新列表的名称在哪个组,如果不存在,会手动添加到“未分组”,如果存在,则会标记.最后,只需删除未标记的名称,然后删除空白即可。整个过程非常繁琐,如果总名单有几千万个名字,工作量会非常大。因此,这个工作非常适合Python辅助自动化。第一步是导入所需的库并设置路径。我还是习惯用函数定位在桌面上,方便复用。importosimportpandasaspdimportnumpyasnpdefGetDesktopPath():returnos.path.join(os.path.expanduser("~"),'Desktop')path=GetDesktopPath()+'data'然后读取两个文件df1=pd.read_excel(path+'totallist.xlsx',encoding='utf-8',sheet_name=0,skiprows=1)df2=df1.iloc[:,1:23]df3=pd.read_excel(path+'newlist.xlsx',encoding='utf-8',sheet_name=0)下一步是根据新列表中出现的名称在总表中找到组。思路是使用np.where,如下图np.where(df2=='DeathBoard')(array([7],dtype=int64),array([5],dtype=int64))返回一个元组,并且行列信息都在里面了,那么用下面的命令获取groupcol=np.where(df2=='Deathboard')1df2.columns[col]'GroupF'有了思路,可以写一个函数,用apply对新列表中的名字一一应用。这里要注意,新列表中的名字可能不在总列表中,所以需要先判断再取最内层的数字,否则会报错deffind(x):results=np.where(df2==x)[1]try:returndf2.columns[results[0]]except:return'ungrouped'df3['remarks']=df3['latestlist'].apply(find)接下来的操作是根据分组结果“拆分”上述数据框results_lst=[]forindex,iinenumerate(df2.columns):results=df3.iloc[np.where(df3['note']==i)[0].tolist(),0]重置索引很重要,为什么重要的是往下看results=results.reset_index(drop=True)results_lst.append(results)results_lst可以看到result是一个Series的列表。这不就是pd.concat的对象吗?由于下一步是横向合并,所以EachSeries需要重新设置索引,保证从0开始df_final=pd.concat(results_lst,axis=1)记得恢复列名df_final.columns=df2.columns的整个需求大致完成(两个非宝可梦的生物也能识别)df_final.to_excel(f'{path}sortedform.xlsx',encoding='gbk',#编码不一定是gbkindex=False,header=True)最后保存保存结果以excel形式输出,如上图所示,我们已经使用Python成功完成了一个Excel非对称表的自动更新,接下来要使用openpyxl修改样式,这部分就是在上一篇文章中有详细解释。不再展开