最近因工做緣由,須要處理一些數據,順便學習一下動態圖表的繪製。本質是使具備源頭的流動信息可以準確找到其上下級關係和流向。html
數據來源是csv文件 導入成爲dataframe以後,列爲其車輛的各部件供應商公司名稱或其自身的屬性。node
導入後通過處理指望是看到整個工業的供應鏈和市場份額.python
結果的部分截圖: 架構
數據來源:app
核心是將以上數據處理成接口須要的兩個數據,一個是全部節點的名稱。另外一個是節點之間互相連接的值,見下圖echarts
NODE: 全部桑基圖的節點集合ide
link: 每個數據流的起始,結束,與值。學習
核心統計原理是:spa
先肯定從左到右的統計大綱:在本次案例中爲:excel
接下來就是找大綱序列中當前大類中對應下一級的小類的數目,例: 案例第一步即找最高車速段中 最高車速能力在<180km/h的篩選出來,同時找出低速度段且續駛里程>80km的數量.
統計代碼:
# link 數據架構 link=[] for i in range(len(title)): temp0=list(class_item) for j in list(class_item[temp0[i]]): try: for k in list(class_item[temp0[i+1]]): df1=df[df[temp0[i]]==j] df2=df1[df1[temp0[i+1]]==k] temp_value=len(df2) if temp_value!=0: link.append({'source':j, 'target':k, 'value':temp_value}) del df1 del df2 except: continue
總代碼:
# 數據架構 總領數據架構-品牌-車輛用途- import matplotlib.pyplot as plt from pyecharts import Pie,Bar,Page,Bar3D,Overlap,Line,Boxplot,Surface3D,Sankey,EffectScatter import pandas as pd import numpy as np df=pd.read_excel(r'C:\Users\wenzhe.tian\Desktop\數據分析\北理新能源數據v2\02_20190301\2EV_v2.xlsx','Sheet1') df_ori=df.copy() #數據處理部分 添加項目,替換重複 格式統一 去掉空格 等 df=df[df.技術類型.str.contains('EV',regex=False)] df=df.reset_index() df=df.drop('index',axis=1) #數據格式處理 df['車型分類']=df['車型分類'].fillna('nan') df=df[~df['車型分類'].isin(['nan'])] # 江淮ES8供應商數據大量缺失,故排除 也可drop df['電動汽車續駛里程(工況法,km)']=df['電動汽車續駛里程(工況法,km)'].fillna(0) df['車輛品牌']=df['車輛品牌'].map(str).replace('傳祺(Trumpchi)牌','傳祺(Trumpchi)牌') df['通用名稱'][df['電動汽車續駛里程(工況法,km)']==0]='ES8' df['電動汽車續駛里程(工況法,km)'][df['電動汽車續駛里程(工況法,km)']==0]=355 df['電動汽車續駛里程(工況法,km)'][df['電動汽車續駛里程(工況法,km)']=='155(對應整備質量750kg),165(對應整備質量700kg)']=165 df['電動汽車續駛里程(工況法,km)'][df['電動汽車續駛里程(工況法,km)']==170203203]=255 df['電動汽車續駛里程(工況法,km)']=df['電動汽車續駛里程(工況法,km)'].fillna(0) df['最高車速']=df['最高車速'].astype(int) df['電動汽車續駛里程(工況法,km)']=df['電動汽車續駛里程(工況法,km)'].astype(int) df['最高車速段']=df['最高車速'].astype(str) df['續駛里程段']=df['電動汽車續駛里程(工況法,km)'].astype(str) #df['電池能量密度']=df['電池容量']*df['儲能裝置總成標稱電壓(V)']/df['儲能裝置總成質量(kg)'] df['整備質量(kg)'][(df['整備質量(kg)'].isnull()) | (df["整備質量(kg)"].apply(lambda x: str(x).isspace()))]=2390 # 去掉先後空格 title=list(df) df['儲能裝置單體質量(kg)']=df['儲能裝置單體質量(kg)'].astype(str) for i in title: try: df[i]=df[i].map(str.strip) except: continue #重複值處理 df=df.replace('比亞迪汽車工業有限公司,比亞迪汽車工業有限公司', '比亞迪汽車工業有限公司') df=df.replace('比亞迪汽車工業有限公司/比亞迪汽車工業有限公司', '比亞迪汽車工業有限公司') df=df.replace('山東德洋電子科技有限公司,山東德洋電子科技有限公司', '山東德洋電子科技有限公司') df=df.replace('深圳市大地和電氣股份有限公司(軟件)/深圳市大地和電氣股份有限公司(硬件)', '大地和電氣') df['最高車速段'][(df['最高車速']<=180)]='<180km/h' df['最高車速段'][((df['最高車速']<=200)& (df['最高車速']>180))]='180-200km/h' df['最高車速段'][(df['最高車速']>200)]='>200km/h' df['續駛里程段'][(df['電動汽車續駛里程(工況法,km)']<=60)]='<60km' df['續駛里程段'][((df['電動汽車續駛里程(工況法,km)']<=80)& (df['電動汽車續駛里程(工況法,km)']>60))]='60-80km' df['續駛里程段'][(df['電動汽車續駛里程(工況法,km)']>80)]='>80km' title=['最高車速段','續駛里程段','車輛用途','企業名稱','車型分類','車輛品牌', '電機生產商','電動汽車整車控制器生產企業','電動汽車車載充電機生產企業','儲能裝置總成生產企業','車載能源管理系統生產企業'] #無效值處理 for i in title: df[i]=df[i].astype(str) df[i]=df[i].map(lambda x: x.replace('有限公司','').replace('股份','').replace('公司','').replace('分','').replace(' Company','').replace(' company','').replace('牌','品牌').replace('北京新能源汽車','北汽新能源')) df[i]=df[i].map(lambda x: x.replace('浙江','').replace('山東','').replace('廣州汽車集團乘用車','廣汽').replace('杭州','').replace('江西','').replace('合肥','')) df[i]=df[i].map(lambda x: x.replace('深圳市','').replace('永康市','').replace('珠海','').replace('鄭州','').replace('軟件:','').replace('硬件:','').replace('北京:','').replace('長沙市','').replace('金華市','')) df[i]=df[i].map(lambda x: x.replace('nan','北汽新能源').replace('(','(').replace(')',')').replace('()','').replace('/深圳市大地和電氣','').replace('開發企業','').replace('生產企業','').replace('福建省汽車工業集團雲度新能源汽車','雲度新能源')) df[i]=df[i].map(lambda x: x.replace('電機1:華域汽車電動系統/電機2:華域汽車電動系統','華域汽車電動系統').replace('前:蔚然(南京)動力科技/後:蔚然(南京)動力科技','蔚然(南京)動力科技')) if i =='最高車速段': str_item='最高車速' elif i =='續駛里程段': str_item='續航里程' elif i =='電機生產商': str_item='MOT' elif i =='電動汽車整車控制器生產企業': str_item='MC' elif i =='電動汽車車載充電機生產企業': str_item='OBC' elif i =='儲能裝置總成生產企業': str_item='BAT' elif i =='車載能源管理系統生產企業': str_item='BMS' else: str_item='' df[i]=df[i].map(lambda x: str_item+x) class_item={} for i in title: class_item[i]=df[i].drop_duplicates() node=[] for i in title: for j in list(class_item[i]): node.append({'name':j}) # link 數據架構 link=[] for i in range(len(title)): temp0=list(class_item) for j in list(class_item[temp0[i]]): try: for k in list(class_item[temp0[i+1]]): df1=df[df[temp0[i]]==j] df2=df1[df1[temp0[i+1]]==k] temp_value=len(df2) if temp_value!=0: link.append({'source':j, 'target':k, 'value':temp_value}) del df1 del df2 except: continue sankey = Sankey("EV供應商鏈統計",width=6000, height=700) sankey.use_theme('roma') #roma wonderland sankey.add( "EV供應商統計", node, link, line_opacity=0.2, line_curve=0.3, line_color='source', sankey_node_gap=13, is_label_show=True, label_pos="right", is_legend_show =False, label_text_size=11 ) sankey.render('EV供應商統計_All.html') del sankey sankey = Sankey("EV供應商鏈統計",width=6000, height=1500) sankey.use_theme('roma') #roma wonderland sankey.add( "EV供應商統計", node, link, line_opacity=0.2, line_curve=0.3, # line_color='source', sankey_node_gap=13, is_label_show=True, label_pos="right", is_legend_show =False, label_text_size=12 ) sankey.render('EV供應商統計_All_v2.html')
(以前是用plotly,後來發現pyecharts接口稍微簡單些,其實都差很少,但plotyly能夠一些特殊地圖繪製比pyecharts來的精細,因此看繪圖需求吧)
附上連接:https://plot.ly/python/ https://pyecharts.org/#/zh-cn/intro 用於查閱須要繪製的圖的種類