在日常數據分析的業務場景下,我們經常會遇到以下難題:
- 如何批量導入不同工作簿不同Sheet表下的數據?
- 如何將這些不同Sheet表下的數據合并為一個數據?
- 如何將合并的數據導入數據庫?
本文構造一組數據,批量合并后導入數據庫保存,下面一起來學習。
本文使用工具:Python 3.7.0
本文使用的模塊:pandas、os、pyMySQL
適用范圍:數據批量導入與合并,數據庫留存
批量數據導入并合并
首先構建10個工作簿,每個工作簿下面有三個Sheet表。
每一個分別Sheet表包含ID、number、sale三個字段。
導入相關的庫,在數據批量導入及合并的時候,使用到pandas和os兩個庫。
#導入相關的庫
import pandas as pd
import os
這里介紹一下os.listdir命令,他可以將一個數據文件內的所有文件名都讀取出來,如下圖就是讀取的文件名,包含那十個工作簿。
os.listdir(r'C:Users尚天強Desktop測試數據')
使用read_Excel命令讀取一個Excel文件。
df = pd.read_excel(r'C:Users尚天強Desktop測試數據測試數據1.xlsx')
df.head()
首先構建一個空的列表,里面沒有任何數值,同時,在開始部分就定義數據的導入路徑、導出路徑、以及保存的文件名。
import pandas as pd
import os
#構建一個空的列表
dfs = []
read_path=r'C:Users尚天強Desktop測試數據'
save_path=r'C:Users尚天強Desktop'
save_name='out_table.xlsx'
接下來是循環遍歷每一個文件的名稱,并且遍歷的文件名不能為保存的文件名,sheet_name=None表示讀取每一個Sheet表下的數據,skiprows=1,header=None取消標題,跳過第一行,只保留數據內容,使用extend命令將遍歷的這些數據內容上下拼接起來。
for fname in os.listdir(read_path):
if fname.endswith(".xlsx") and fname !=save_name:
df = pd.read_excel(read_path+"\"+fname,skiprows=1,header=None,sheet_name=None)
dfs.extend(df.values())
使用concat命令將每一個工作簿的數據拼接起來。
#合并
result = pd.concat(dfs)
在導出數據的時候,使用header命令給表格加一個標題,批量導入數據并合并的結果如下所示。
#導出數據
result.to_excel(save_path+"\"+save_name,index=False,header=['id','number','sale'])
使用第一種方法合并數據,發現有重復值,可以使用drop_duplicates參數去除重復值,使用sort_values參數進行排序,去除重復值并且排序的數據結果如下所示。
import pandas as pd
import os
dfs = []
read_path=r'C:Users尚天強Desktop測試數據'
save_path=r'C:Users尚天強Desktop'
save_name='out_table.xlsx'
for fname in os.listdir(read_path):
if fname.endswith(".xlsx") and fname !=save_name:
df = pd.read_excel(read_path+"\"+fname,skiprows=1,header=None,sheet_name=None,names=['id','number','sale']) #這里需要用names函數命名,不然沒法去重和排序
dfs.extend(df.values())
#合并
result = pd.concat(dfs)
#根據ID去除重復值
result.drop_duplicates(subset='id',keep='first',inplace=True)
#降序排列
result.sort_values(by='sale',ascending=False,inplace=True)
#導出數據
result.to_excel(save_path+"\"+save_name,index=False,header=['id','number','sale'])
數據導入數據庫
將數據導入數據庫,這里還是使用上面的數據文件,連接數據庫使用的模塊為pymysql。
#讀入數據
data = pd.read_csv(r'C:Users尚天強Desktopout_table.csv',engine='python')
data.head()
#導入需要使用到的數據模塊
import pandas as pd
import pymysql
數據庫連接,host為數據庫地址、user為用戶名、password為密碼、db為數據庫的名字、port為端口,默認為3306。
# 建立數據庫連接
con = pymysql.connect(host='127.0.0.1',
user='root',
password='123456',
db='demo',
port=3306)
獲取游標對象。
# 獲取游標對象
cursor = con.cursor()
用數據庫demo,'USE demo' 也是數據庫內的SQL語言。
#使用數據庫demo
cursor.execute('USE demo')
構造一個test表,包含ID、number、sale三個字段。
cursor.execute('create table if not exists test (
ID char(4) primary key,
number int,
sale float)'
)
向表test表內插入數據。
#插入數據語句
query = "insert into test(ID,number,sale)values (%s,%s,%s)"
迭代讀取每行數據,轉化數據類型,將其保存在values內。
#迭代讀取每行數據,values中元素有個類型的強制轉換,否則會出錯
for r in range(0, len(data)):
ID = data.iloc[r,0]
number = data.iloc[r,1]
sale = data.iloc[r,2]
values = (str(ID),int(number),float(sale))
cursor.execute(query, values)
關閉游標,提交,關閉數據庫連接。
#關閉游標,提交,關閉數據庫連接,如果沒有這些關閉操作,執行后在數據庫中查看不到數據
cursor.close()
con.commit()
con.close()
打印數據
# 建立數據庫連接
con = pymysql.connect(host='127.0.0.1',
user='root',
password='123456',
db='demo',
port=3306)
# 獲取游標對象
cursor = con.cursor()
首先執行SQL命令,'select * from test'表示查詢test表內的所有數據,循環遍歷數值,將它打印出來。
#查詢數據庫并打印內容
cursor.execute('select * from test')
result = cursor.fetchall()
for values in result:
print(values)
打印出來的結果可以看到,第一列是字符串,第二列是整型,第三列是浮點型。
#關閉
cursor.close()
con.commit()
con.close()
導入數據庫后的結果如下所示: