利用Python快速進行數據探查

工做中你是否碰見這樣的問題:mysql

  • 接手新業務時須要瞭解數十上百張的數據庫表結構;
  • 表中的數據量級均是百萬級以上;
  • 但願能夠批量快速生成以下表格。

file
數據探查結果表sql

若是你遇到了以上的問題,恭喜你,本文能夠幫助你解決!數據庫

一、解決思路

但有人會有疑問,Python進行數據探查不是很是簡單的事嗎,一個函數分分鐘搞定,還有必要專門介紹嗎。若是你這樣想就too yong too simple了。app

你能夠回想下,當咱們採用descirbe()函數時,默認的前提是已經將數據讀入了Python之中。但你可曾想過,實際工做中數據讀入也會成爲一種問題。對的,當數據量級一旦達到百萬以上甚至更多時,Python讀取數據的效率就很低了。讀取一張表可能就要半小時以上,幾十張表的話差很少就得一天了。這樣低效的方法,確定是不可取的。框架

本文就是來源於工做中的實際需求,在上述的方式行不通時,我轉變思路尋找了另外一種方式。具體的邏輯思路以下:機器學習

file

也就是說,爲了快速進行探查,咱們能夠不用進行全表讀入,只需對每一個表每一個字段進行分組查詢就能夠了。但如何將SQL查詢語句進行循環呢?採用字符串的格式化輸出!函數

二、代碼實現

首先咱們導入相關包學習

import pymysql 
import pandas as pd
import datetime as dt
start=dt.datetime.now()  #爲了計算程序執行時間

將數據庫的鏈接和查詢抽象成一個函數,在此我設置的是返回數據框格式數據fetch

#定義數據查詢函數
def sql_inquiry(sql):
  conn= pymysql.connect(host="localhost",port=****,user='****',
                            passwd='****',db="test_titanic",charset="utf8")
  cur=conn.cursor()
  cur.execute(sql)
  result=cur.fetchall()
  cols=[a[0] for a in cur.description] #得到字段名稱信息
  df=pd.DataFrame(result,columns=cols)
  conn.commit()
  cur.close()
  conn.close()
  return df

準備工做作好後,咱們能夠輸入咱們要進行探查的表名稱。ui

table_name=['test','train']

若是咱們想得到這些表的字段名稱、註釋、類型和行數的話,能夠經過數據框的信息表得到。這個地方要注意的就是:爲了便於循環,根據每一個表創建了一條SQL語句,把全部的語句組合成了一個列表。

table_sql=[]
for i in range(len(table_name)):
    table_sql.append('''select t1.table_name as table_name,t1.column_name as column_name,t1.column_type as column_type,
      t1.column_comment as column_comment ,t2.table_rows as table_rows
      from information_schema.columns as t1,information_schema.`tables` as t2
      where t1.table_schema=t2.table_schema and t1.table_name=t2.table_name and t1.table_name='{}' and t1.table_schema='test_titanic'
      '''.format(table_name[i]))

接下來,就是根據這個SQL列表進行查詢得到數據,而後繼續對字段進行循環查詢。

writer=pd.ExcelWriter("table_des.xlsx")#爲了導出數據
table_col_name=[]
row=0
for j in range(len(table_sql)):  #對錶SQL進行循環
    table_col_name.append(sql_inquiry(table_sql[j])) #將每一個表查詢獲得的數據框組成列表
    table_col_stat=[]
    col_sql=[]
    for s in range(len(table_col_name[j])): #對每一個表信息的字段進行循環
        col_sql.append('''select min({1}) as value_min, max({1}) as value_max,sum(case when {1} is not null then 1 end ) as num_classification,
          sum(case when {1} is null then num else 0 end) as null_num,sum(num) as rows_num
          from
            (select {1} ,count(1) as num
            from  
            {0} group by {1})t1'''.format(table_name[j],table_col_name[j].iloc[s,1]))
# 根據字段的SQL語句進行查詢並轉換成列表       
        col=sql_inquiry(col_sql[s]).iloc[0,:].tolist()
#將字段名稱拼接進列表中
        table_col_stat.append([table_col_name[j].iloc[s,1]]+col)
#轉換爲數據框
    table_des=pd.DataFrame(table_col_stat,columns=["name","value_min","value_max","num_classification","null_num","rows_num"])
#計算字段的空值率並以百分比形式顯示
    table_des["null_rate"]=table_des["null_num"]/table_des["rows_num"]
    table_des["null_rate"]=table_des["null_rate"].apply(lambda x :format(x,".2%"))
#合併數據框
    table_des=pd.merge(table_col_name[j],table_des,how="inner",left_on="column_name",right_on="name")
    table_des.drop(["table_rows","name"],axis=1,inplace=True)
#寫入Excel文檔
    table_des.to_excel(writer,startcol=1,startrow=row,index=False)
    row+=table_des.shape[0]+4
#保存文檔並計算程序用時
writer.save()
elapsed = (dt.datetime.now()- start)
print("Time used:",elapsed)
print ("\a")

完整執行完程序,最後你就能快速生成前文中的數據探查表了,即便表的量級很大。根據這些表,你能夠快速地瞭解表結構。其實代碼並不複雜,難的是咱們須要找到解決問題的有效思路。

本文僅供學習之用,版權歸原做者全部,若有侵權請聯繫刪除。

在學習Python的道路上確定會碰見困難,別慌,我這裏有一套學習資料,包含40+本電子書,800+個教學視頻,涉及Python基礎、爬蟲、框架、數據分析、機器學習等,不怕你學不會!
https://shimo.im/docs/JWCghr8... 《Python學習資料》

關注公衆號【Python圈子】,優質文章每日送達。

file

相關文章
相關標籤/搜索