pandas是Python最常用的数据分析处理包,使用起来也非常方便,在此做下记录。
案例场景
客户公司使用我司系统,有部分数据需要从第三方公司的ERP系统获取,ERP系统没有程序接口获取数据,也不提供数据库访问权限,需要从不同报表导出数据经过处理匹配后才能导入到我司系统,由于人工处理和匹配工程量较大,因此希望通过python脚本提升效率。
分析案例主要需要以下几个步骤:
序号 | 步骤 | 说明 |
---|---|---|
1 | 从ERP导出EXCEL表 | 客户需要从ERP系统导出所需要的数据到EXCEL表,并放进制定目录 |
2 | 读取EXCEL表数据 | 脚本从制定目录读取所有数据到内存 |
3 | 将数据写入到一个临时数据库 | 由于多个EXCEL表数据匹配处理逻辑较复杂,我们将其写入到一个数据库,通过SQL语言进行计算查询 |
4 | 将计算结果输出 | 计算结果可以直接写入数据库指定表或输出成EXCEL |
案例脚本
首先,我们先引入需要使用到的两个包,pandas是数据处理包,SQLalchemy是数据库模型包;
import pandas as pd
#从SQLalchemy引入创建数据库连接的函数
from sqlalchemy import create_engine
然后编写从EXCEL读取数据并写入到数据库的函数;pandas读取EXCEL的函数是read_excel(),常用参数含义如下:
序号 | 参数 | 默认值 | 含义 |
---|---|---|---|
1 | io=file_dir | 无 | 要读取的文件路径 |
2 | sheet_name= 0 | 0 | 指定EXCEL的sheet,0代表第一个,也可以传sheet名称 |
pandas写入数据库的函数是to_sql(),常用参数含义如下:
序号 | 参数 | 默认值 | 含义 |
---|---|---|---|
1 | name=file[‘table_name’] | 无 | 写入的数据库表名 |
2 | con=con | 无 | 要写入的数据库连接 |
3 | if_exists=’replace’ | replace | 当表存在是执行的操作:fail代表不执行直接给报错,replace表示删掉表重新创建,append代表在表里面新增数据 |
4 | index=False | True | 是否将索引列插入数据库表 |
案例中使用sqlite数据库,读取数据写入数据库的函数写完后如下:
#传入参数是要读取的文件名和写入数据库的表名
def to_db(file):
#组合文件名和当前路径,形成文件全路径名称(文件要放在“./”目录下)
file_dir='./'+file['name']
#读取excel表数据
df=pd.read_excel(io = file_dir,sheet_name = 0)
#连接数据库
con = create_engine('sqlite:///yjsjdr.db')
#写入到数据库
#if_exists:{'fail','replace','append'},默认'fail'
df.to_sql(name=file['table_name'],con=con,if_exists='replace',index=False)
将要导入的EXCEL和对应导入后的表名做成字典加到一个list里面,循环执行上述函数可以导入所有表:
files=[
{"name":"业绩认定_05特殊业绩情况表.xlsx","table_name":"tsyj"},
{"name":"业绩认定_06合作项目业绩情况表.xlsx","table_name":"hzyj"},
{"name":"Export.xlsx","table_name":"hzyj_mx"},
{"name":"F054-各项目基础信息系统取数原始表单(实时).xlsx","table_name":"xmqd"},
{"name":"合作项目公司与平台公司对照.xlsx","table_name":"gsdz_zz_pt"},
{"name":"明源公司与悦家城市公司对照表.xlsx","table_name":"gsdz_yj_my"}
]
for file in files:
to_db(file)
数据导入到数据库后,通过执行SQL语句进行组合查询;pandas执行SQL语句查询结果的函数是read_sql_query(),常用参数含义如下:
序号 | 参数 | 默认值 | 含义 |
---|---|---|---|
1 | sql1 | 无 | 要执行的SQL语句 |
2 | con=con | 无 | 要查询的数据库连接 |
案例完成后的函数如下,由于目标表有两个,因此有两段SQL和查询数据插入:
def insert_data():
#SQL组合计算语句
sql1='''SELECT
x2.明源系统代码 project_number,
hm.年份 date_year,
hm.月份 date_month,
hm.套数 total_room,
hm."面积(㎡)" total_area,
hm."金额(万元)" * 10000 total_money,
CASE WHEN hm.审核状态 = '审核' THEN 1 ELSE 2 END audit_flag,
datetime('now') import_time,
1 flag
FROM
hzyj_mx hm
LEFT JOIN gsdz_zz_pt g2 ON
hm.公司名称 = g2.组织公司
LEFT JOIN xmqd x2 ON
g2.平台公司 = x2.公司名称
AND hm.项目名称 = x2.项目名称
'''
con = create_engine('sqlite:///yjsjdr.db')
#执行SQL语句获取数据
df1 = pd.read_sql_query(sql1,con=con)
#if_exists:{'fail','replace','append'},默认'fail'
df1.to_sql(name='my_cooperation_project_contract',con=con,if_exists='append',index= False)
sql2='''SELECT
DISTINCT
x2.明源系统代码 project_number,
hm.项目名称 project_name,
x2.项目推广名 project_spread_name,
gym.悦家公司ID city_company_id,
substr(IFNULL(x2.合作方,'未知'),1,100) cooperation_companys,
x2.我方股权比例/100 proportion,
CASE
WHEN x2.操盘方式 = '我司操盘' THEN 1
WHEN x2.操盘方式 = '合作方操盘' THEN 2
ELSE 3
END operate_type,
CASE
WHEN x2.并表方式 = '我司并表' THEN 1
WHEN x2.并表方式 = '合作方并表' THEN 2
ELSE 3
END consolidation_type ,
datetime('now') import_time,
1 flag
FROM
hzyj_mx hm
LEFT JOIN gsdz_zz_pt g2 ON
hm.公司名称 = g2.组织公司
LEFT JOIN gsdz_yj_my gym ON
hm.公司名称 = gym.明源组织公司
LEFT JOIN xmqd x2 ON
g2.平台公司 = x2.公司名称
AND hm.项目名称 = x2.项目名称
WHERE gym.悦家公司ID IS NOT NULL
'''
#获取数据
df2 = pd.read_sql_query(sql2,con=con)
#if_exists:{'fail','replace','append'},默认'fail'
df2.to_sql(name='my_cooperation_project',con=con,if_exists='append',index= False)
当导入系统有标准模板时,我们需要将数据整理成模板格式,并导出到EXCEL,pandas导出数据到EXCEL的函数是to_excel(),必要参数如下:
序号 | 参数 | 默认值 | 含义 |
---|---|---|---|
1 | excel_writer | 无 | 导入EXCEL的全路径名称 |
2 | sheet_name | 无 | 导入到EXCEL的那个sheet页面 |
本案例中导出到EXCEL的函数如下:
def to_excle():
sql3='''略,保障列和列名与导入模板一致'''
con=create_engine('sqlite:///yjsjdr.db')
df3=pd.read_sql_query(sql3,con=con)
df3.to_excel('./导入模板.xlsx',sheet_name = 'sheet1')