Panda实现一表数据关联查询多表数据

背景:

接到一个任务,要把下面excel里面的内容全部填写完成,而数据来自于其他的文件夹下excel表格

需要完善的Excel:

python多表头处理 python 多表查询_数组


数据来源:

python多表头处理 python 多表查询_数组_02


python多表头处理 python 多表查询_根目录_03


所以手工查找的话,量大的同时又麻烦。

手工查询

这里我们讨论一下手工查找方法:

1.在该表中,我们可以知道姓名字段是主键(每一行都有姓名,同时是唯一的),我们先记下第一行要查询人的姓名,和年级班级。

2.到根目录下根据年级查找对应年级文件夹,并进入

3.到达年级文件夹下后,就可以看见每个班的Excel表,找到对应班级进入

4.进入表中后就可以根据刚刚的姓名查找到对应记录(行),然后找对应字段下的分数。也就是图中对应德育总分的字段。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M21ZuNdS-1586862250526)(C:\Users\Administrator\Desktop\桌面杂项\小结\微信图片_20200414172717.jpg)]

5.这样子一个人的信息就查询完了,然后重复以上操作,直到结束。

We don’t repeat ourselves

我们把手工操作在脚本编写中简化为三步操作并实现

1.遍历要填写的数据表,获得一行的数据(名字、年级班级)

2.根据一行的数据年级班级进入到对应的文件下,并打开Excel

3.进入Excel后,遍历Excel的所有数据,获得每一行的数据(姓名、德育分),当名字和我们要找的名字相同时,就返回当前的行的德育分。

全部代码

import pandas as pd
import os

def changeName(name):
    if len(name)==2:
        return name[0:1]+'  '+name[1:2]
    return name
#定义根目录的字典
RootUrlDict={'2017':'17德育总汇','2018':'18德育总汇'}

def getRootUrl(classinfo):
    if classinfo in RootUrlDict.keys():
        return RootUrlDict.get(classinfo)
    else:
        return -1

# 遍历根目录下的所有excel文件,查询名字为name的score:name:查询人姓名    Rooturl:为查询的根目录
def getStuScores(name,Rooturl):
    if Rooturl==-1:
        print('外键不存在')
        return
    fileLists = os.listdir(Rooturl)
    for file in fileLists:
        try:
            fileData = pd.read_excel(Rooturl+'/'+file, header=5, usecols=[2, 6],names=['名字','分数'])
            fileDatas=fileData.values
            for fileData in fileDatas:
                if(name==str(fileData[0])):
                    return fileData[1]
        except:
            print('Error========>'+file)

data=pd.read_excel("2019—2020第二学期拟发展名单(基础条件第一轮筛选).xlsx", header=1,usecols=[4,5,6,7,8,25,28],)
datas=data.values
newData=[]
for data in datas:
    if data[0]>89:
        break
    newRowData=[]
    newRowData.extend(data)
    score=getStuScores(data[1],getRootUrl(data[3][0:4]))
    if score is None:
        score=0
    newRowData.extend([score])
    newData.append(newRowData)

dt = pd.DataFrame(newData,columns=['序号','姓名','性别','班级','入党申请时间','第一次分数','第一次排名','读取分数'])
print(dt)
dt.to_excel("result_xlsx2.xlsx", index=0)

代码详解

(1)遍历查询数据
data=pd.read_excel("2019—2020第二学期拟发展名单(基础条件第一轮筛选).xlsx", header=1,usecols=[4,5,6,7,8,25,28],)
datas=data.values
newData=[]
for data in datas:
    if data[0]>89:
        break
    newRowData=[]
    newRowData.extend(data)
    score=getStuScores(data[1],getRootUrl(data[3][0:4]))
    if score is None:
        score=0
    newRowData.extend([score])
    newData.append(newRowData)
#保存数据至Excel
dt = pd.DataFrame(newData,columns=['序号','姓名','性别','班级','入党申请时间','第一次分数','第一次排名','读取分数'])
dt.to_excel("result_xlsx2.xlsx", index=0)

1.读取要查询的数据:

data=pd.read_excel("2019—2020第二学期拟发展名单(基础条件第一轮筛选).xlsx", header=1,usecols=[4,5,6,7,8,25,28],)

python多表头处理 python 多表查询_python多表头处理_04

结合最图,我们要取的是表的4、5、6、7、8、25、28列的字段数据,表的头为1,注意:计数从小标0开始

2.我们新建一个数组存放所有数据,之后遍历每一行的数据,那么在循环体中获得的data就是一个一维数组

我们进行以下两步操作:

1.我们再新建一个用来存放每行数据的数组,然后将一维数组用extend插入到新的行数组中

2.利用一维数组的下标取到姓名和年纪班级,获得后将数据代入到查询德育分的函数中,函数返回结果后,插入到新建的行数组中

这样行数组就包含了新的查询到的德育分数据,最后再每次遍历行时,append插入到新的数组中,形成二维数组。

关于append和extend的区别

a=[1,2,3]
b=[]

a.append(b)
a.extend(b)

#a结果[1,2,3,[5,6,7]]
#b结果[1,2,3,5,6,7]

3.对文件进行保存

dt = pd.DataFrame(newData,columns=['序号','姓名','性别','班级','入党申请时间','第一次分数','第一次排名','读取分数'])
dt.to_excel("result_xlsx2.xlsx", index=0)

这里columns可以设置字段名

(2)根据年级获得Url
#定义根目录的字典
RootUrlDict={'2017':'17德育总汇','2018':'18德育总汇'}

def getRootUrl(classinfo):
    if classinfo in RootUrlDict.keys():
        return RootUrlDict.get(classinfo)
    else:
        return -1

此处定义Url我们的目录结构是这样子的(文件名字乱取的懒得改)

-test.py
-17德育总汇
--17电商1班德育量化考核成绩汇总表.xls.xls
--17电商1班德育量化考核成绩汇总表.xls.xls
--17电商1班德育量化考核成绩汇总表.xls.xls
--17电商1班德育量化考核成绩汇总表.xls.xls
--17电商1班德育量化考核成绩汇总表.xls.xls
--17电商1班德育量化考核成绩汇总表.xls.xls
-18德育总汇
--18电商1班德育量化考核成绩汇总表.xls.xls
--18电商1班德育量化考核成绩汇总表.xls.xls
--18电商1班德育量化考核成绩汇总表.xls.xls
--18电商1班德育量化考核成绩汇总表.xls.xls
--18电商1班德育量化考核成绩汇总表.xls.xls
--18电商1班德育量化考核成绩汇总表.xls.xls

在遍历要查询数据时,此处传入的是查询目标的年级班级信息,如:2017信息1班XX,所以前四个字符可以用来做索引,所以该方法实现是从事先定义的索引字典中取Url,并返回。

(3)遍历年级文件夹下所有的表查询

为什么要遍历所有而不直接根据班级访问对应班级excel呢?因为这里每个班excel的命名方式不规范,编写代码困难,而且同名学生不存在,所以可以直接遍历文件夹下所有excel

# 遍历根目录下的所有excel文件,查询名字为name的score:name:查询人姓名    Rooturl:为查询的根目录
def getStuScores(name,Rooturl):
    if Rooturl==-1:
        print('外键不存在')
        return
    fileLists = os.listdir(Rooturl)
    for file in fileLists:
        try:
            fileData = pd.read_excel(Rooturl+'/'+file, header=5, usecols=[2, 6],names=['名字','分数'])
            fileDatas=fileData.values
            for fileData in fileDatas:
                if(name==str(fileData[0] or changeName(name)==str(fileData[0]))):
                    return fileData[1]
        except:
            print('Error========>'+file)

这里说明一下changename,因为有些人的名字是两个,因为表格做的不规范,两字的名字存在两种情况

例如:李文 和 李 文 这两个对计算机来说是不一样的,所以要兼容掉。