python--boss直聘資料視覺化
阿新 • • 發佈:2018-12-02
python 資料視覺化
本文中主要使用matplotlib和Pandas對資料進行視覺化
資料來源:爬取的BOOS直聘資料分析資料
資料展示
本文中針對以上資料,對salary,company_info,work_time,education這幾個資訊進行資料視覺化,做出直方圖和餅圖
整體框架
先看一下使用的包吧
import re #正則表示式模組 import json #json模組 import pandas as pd #pandas模組 from nltk import FreqDist #nltk模組,用於分析詞頻 import matplotlib.pyplot as plt #matplotlib模組 from numpy import nan as NAN #numpy 模組
指定matplotlib中的字型
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定預設字型
plt.rcParams['axes.unicode_minus'] = False # 解決儲存影象是負號'-'顯示為方塊的問題
初始化,構造DataFrame資料
由於資料是從爬蟲返回的JSON檔案中匯出的,而爬蟲返回的JSON檔案中JSON格式不標準,需要對格式進行處理,然後再loads為Python物件
def __init__(self): #讀出檔案中的內容 self.fp = open("boss_fp.json",'r',encoding='utf-8').read() #在每一行資料中新增逗號, self.fp_re = re.sub(r"}","},",self.fp) #取出最後一個逗號,並在首尾新增方括號,構造為一個標準的JSON資料 self.fp_re = "["+self.fp_re[:-2]+"]" #loads為Python物件資料 self.json_str = json.loads(self.fp_re) self.df = pd.DataFrame(self.json_str)
資料清洗
在這個專案中,資料清洗時比較簡單的,這裡只從整體上來清洗,細節上的在各自模組進行清洗,只需要刪除為空的資訊即可【刪除所有包含空null的行資料】
#刪除為空的資料,any表示只要包含null則刪除整行
self.dataf = self.df.dropna(axis=0,how='any')
資料分析
分析salary資訊
由於salary資訊的格式為:15K-10K這種,所以分析salary資訊時,按照區間值的最低值和最高值分別進行分析,先取出最值,然後對區間進行劃分,新建一個列,儲存劃分之後的區間值。然後進行統計分析。
#取出區間最低值 self.dataf['salary_down'] = list(map(lambda x:x.split("-")[0],self.dataf['salary'])) #對最低值進行分割槽 self.dataf['salary_down_1'] = list(map(self.ana_salary_data,self.dataf['salary_down'])) #分析出區間中各種類的值 salary_d = FreqDist(self.dataf['salary_down_1']) #按最高值進行分析 #按照薪資區間最高分析 self.dataf['salary_up'] = list(map(lambda x:x.split("-")[1],self.dataf['salary'])) self.dataf['salary_up_1'] = list(map(self.ana_salary_data,self.dataf['salary_up'])) salary_ud = FreqDist(self.dataf['salary_up_1']) #分類介面如下: def ana_salary_data(self,data_list): num = int(data_list.split('K')[0]) if num <=4: data_list = "0k-4k" elif num <=10: data_list = "5k-10k" elif num <=15: data_list = "11k-15k" elif num <=25: data_list = "16k-25k" elif num <=50: data_list = "26k-50k" else: data_list = "50k以上" return data_list
最後返回一個dict型別的資料:如下:
字典的key為區間值,value為數量
這樣就可以畫圖了,畫圖介面在後面展示
畫圖
self.do_bar_plot(dict(salary_d),"薪資區間","數量","薪資區間最低分析")
self.do_pie_plot(dict(salary_d),"薪資區間最低分析")
self.do_bar_plot(dict(salary_ud),"薪資區間","數量","薪資區間最高分析")
self.do_pie_plot(dict(salary_ud),"薪資區間最高分析")
工作年限分析
由於工作年限資訊中還有其他欄位,首先先提取年限欄位,然後對年限自段,進行分類統計
self.dataf['work_time_o'] = list(map(lambda x:x.split(":")[1],self.dataf['work_time']))
worktime = FreqDist(self.dataf['work_time_o'])
這樣就會返回一個如上一樣的字典資料
畫圖
self.do_bar_plot(dict(worktime),"工作年限","數量","工作年限時間圖")
self.do_pie_plot(dict(worktime),"工作年限時間圖")
公司資訊提取
這一塊需要提取公司人數和公司行業兩項資料,公司資訊資料是一個列表,包含三項資料,分別為公司名稱,公司人數,和公司行業。直接取出即可
#公司人數
#如果資訊中有缺失,則設定為空,然後刪除
self.dataf['info'] = list(map(lambda x: x[1] if len(x) == 3 else NAN, self.dataf['company_info']))
self.dataf = self.dataf.dropna()
infos = FreqDist(self.dataf['info'])
#公司行業
self.dataf['info_3'] = list(map(lambda x: x[-1], self.dataf['company_info']))
infos_3 = FreqDist(self.dataf['info_3'])
畫圖
self.do_bar_plot(dict(infos_3),"行業","數量","行業資訊圖")
self.do_pie_plot(dict(infos_3),"行業資訊圖")
self.do_bar_plot(dict(infos),"規模","數量","規模資訊圖")
self.do_pie_plot(dict(infos),"規模資訊圖")
學歷分析:
學歷分析和公司資訊分析基本一致
self.dataf['education_0'] = list(map(lambda x: x.split(":")[1], self.dataf['education']))
edu_dist = FreqDist(self.dataf['education_0'])
edu_dict = dict(edu_dist)
畫圖
self.do_bar_plot(edu_dict,"學歷","數量","學歷直方圖")
self.do_pie_plot(edu_dict,"學歷分佈圖")
作圖介面
本文中作圖介面分為兩個,柱狀圖和餅圖兩種:
柱狀圖
傳入引數為:字典資料,x,y軸標籤,和表頭
def do_bar_plot(self,data_dict,xlabel,ylabel,title):
plt.figure()
x_val = list(data_dict.keys())
y_val = list(data_dict.values())
plt.bar(x_val,y_val,width=0.3)
plt.xticks(rotation=60)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
for x in range(len(x_val)):
plt.text(x_val[x], y_val[x] + 0.05, '%.0f' % y_val[x], ha='center', va='bottom', fontsize=7)
plt.title(title)
plt.show()
餅圖介面
傳入引數為:字典資料,和表頭
def do_pie_plot(self,data_dict,title):
plt.figure()
x_val = list(data_dict.keys())
y_val = list(data_dict.values())
explode = (0, 0, 0, 0)
plt.pie(y_val,labels=x_val,autopct='%1.1f%%')
plt.axis('equal')
plt.legend(loc='upper left', bbox_to_anchor=(-0.1, 1))
plt.title(title)
plt.show()