FP报表整理技术,python3,pandas
我们在进行报表的时候,会遇到许多报表:
需要把下面这种表,按着姓名(身份证号)的方式,加入其中,以便查询:
下面代码实现了姓名均唯一的情况下,将小的数据表加入大的数据表。所以母表和子表,在预处理的时候,要求姓名必须对应且唯一(子表中有没有母表的姓名,不影响,但是母表中不能有2个张三,子表也不能有2个张三,可以根据身份证号或者户人数分别命名为张三1和张三2)。
代码如下:
import os
import pandas as pd
excelPath = 'E:\PythonTest\excel' #构建所有文件路径
theTablePath = '128户318人待上报.xls' #构建数据总表模板
name = '姓名' #以姓名为唯一标识(索引)
def toAll(bigPath,smallPath,name):
aTable = pd.DataFrame(pd.read_excel(bigPath)) #将数据总表模板 加载
bTable = pd.DataFrame(pd.read_excel(smallPath)) #将要加入的小表格加载
if bTable[name].index.is_unique: #如果name(姓名列)唯一 则继续加载
grouped = bTable
else:
grouped = bTable.groupby(name).sum() #如果姓名列不唯一 则以姓名为索引 将其他项目相加(这里待修改)
result = pd.merge(aTable, grouped, on=[name], how='left') #按着姓名对应的方式 将小表 加入 总表,但以总表为准
result.to_excel(theTablePath) #输出新的总表
print(aTable.shape) #看之前表的大小
print(result.shape) #看之后的表大小 看结构是否有变化
return
for filename in os.listdir(r'E:\PythonTest\excel'): #读取文件名称
targetPath = excelPath + '\\'+ filename #构造文件夹内每一个文件的绝对路径
print(targetPath)
toAll(theTablePath,targetPath,name) #更新表
i但上述代码加横线的地方待修改,因为子表中有可能有重名的,而且在真实的表格中,需要根据身份证号来修改。但实际工作中,身份证号也有输错的时候,所以可以考虑根据身份证号中的出生日期来一一修改姓名,或者根据户人数来修改姓名。逻辑是:首先将母表中重复的挑出来,根据身份证号(出生日期)或者户人数判断,如果一样则删掉一个只留一个唯一,如果不一样,则在姓名后加出生日期来进行甄别。同时生成新的对照表和母表,这时,母表就没有姓名重复的情况了,对照表也只有之前修改的重名的信息,比如对照表有:李四19600312,李四19650106之类的姓名。之后用对照表的身份证号前几位、同时还有姓名的前两个字符,与子表对,如果子表有这一行,则将相应的子表的姓名项改为对照表的姓名项,同时将新的子表合并到母表中。
改进办法:以身份证号为连接两侧的列,并删除带有姓名的列:
import os
import pandas as pd
filePath = '抚恤事业和计生' #子表所有文件所在的文件夹
tablePath = '抚恤事业和计生汇总.xls' #数据母表的模板
name = u'身份证号' #以身份证号连接两侧内容
def toAll(tablePath,fenPath,name):
zongTable = pd.DataFrame(pd.read_excel(tablePath)) # 将数据总表模板 加载
zongTable[name] = zongTable[name].apply(lambda x: x[:18].upper())
# 有的身份证号是残疾证号,多了2位,所以要将身份证号前18位截取,并将字母都变成大写,以便统一
fenTable = pd.DataFrame(pd.read_excel(fenPath, sheet_name=0)) # 将要加入的小表格加载
fenTable[name] = fenTable[name].apply((lambda x: str(x)[:18].upper()))
# 有的身份证号是残疾证号,多了2位,所以要将身份证号前18位截取,并将字母都变成大写,以便统一
result = pd.merge(zongTable, fenTable, on=[name], how='left') # 按着身份证号对应的方式 将小表 加入 总表,但以总表为准
result = result[result.columns.drop(list(result.filter(regex='姓名')))]
# 删除含有姓名的列
result.to_excel(tablePath) # 输出新的总表
print(result.shape)
return
for filename in os.listdir(filePath): #读取文件名称
targetPath = filePath + '/'+ filename #构造文件夹内每一个文件的绝对路径
print(targetPath)
toAll(tablePath,targetPath,name) #更新表