Python和Excel的完美结合:常用操作汇总(案例详析)
在以前,商業分析對應的英文單詞是Business Analysis,大家用的分析工具是Excel,后來數據量大了,Excel應付不過來了(Excel最大支持行數為1048576行),人們開始轉向python和R這樣的分析工具了,這時候商業分析對應的單詞是Business Analytics。
其實python和Excel的使用準則一樣,都是[We don’t repeat ourselves],都是盡可能用更方便的操作替代機械操作和純體力勞動。
用python做數據分析,離不開著名的pandas包,經過了很多版本的迭代優化,pandas現在的生態圈已經相當完整了,官網還給出了它和其他分析工具的對比:
本文用的主要也是pandas,繪圖用的庫是plotly,實現的Excel的常用功能有:
- Python和Excel的交互
- vlookup函數
- 數據透視表
- 繪圖
以后如果發掘了更多Excel的功能,會回來繼續更新和補充。開始之前,首先按照慣例加載pandas包:
import numpy as np import pandas as pd pd.set_option('max_columns', 10) pd.set_option('max_rows', 20) pd.set_option('display.float_format', lambda x: '%.2f' % x) # 禁用科學計數法Python和Excel的交互
pandas里最常用的和Excel I/O有關的四個函數是read_csv/ read_excel/ to_csv/ to_excel,它們都有特定的參數設置,可以定制想要的讀取和導出效果。比如說想要讀取這樣一張表的左上部分:
可以用pd.read_excel(“test.xlsx”, header=1, nrows=17, usecols=3),返回結果:
df Out[]: 工號 姓名 性別 部門 0 A0001 張偉 男 工程 1 A0002 王秀英 女 人事 2 A0003 王芳 女 行政 3 A0004 鄭勇 男 市場 4 A0005 張麗 女 研發 5 A0006 王艷 女 后勤 6 A0007 李勇 男 市場 7 A0008 李娟 女 工程 8 A0009 張靜 女 人事 9 A0010 王磊 男 行政 10 A0011 李娜 女 市場 11 A0012 劉詩雯 女 研發 12 A0013 王剛 男 后勤 13 A0014 葉倩 女 后勤 14 A0015 金雯雯 女 市場 15 A0016 王超杰 男 工程 16 A0017 李軍 男 人事輸出函數也同理,使用多少列,要不要index,標題怎么放,都可以控制。
vlookup函數
vlookup號稱是Excel里的神器之一,用途很廣泛,下面的例子來自豆瓣,VLOOKUP函數最常用的10種用法,你會幾種?
案例一
問題:A3:B7單元格區域為字母等級查詢表,表示60分以下為E級、6069分為D級、7079分為C級、80~89分為B級、90分以上為A級。D:G列為初二年級1班語文測驗成績表,如何根據語文成績返回其字母等級?
方法:在H3:H13單元格區域中輸入=VLOOKUP(G3, $A3:3:3:B$7, 2)
python實現:
df = pd.read_excel("test.xlsx", sheet_name=0) def grade_to_point(x):if x >= 90:return 'A'elif x >= 80:return 'B'elif x >= 70:return 'C'elif x >= 60:return 'D'else:return 'E'df['等級'] = df['語文'].apply(grade_to_point) dfOut[]: 學號 姓名 性別 語文 等級 0 101 王小麗 女 69 D 1 102 王寶勤 男 85 B 2 103 楊玉萍 女 49 E 3 104 田東會 女 90 A 4 105 陳雪蛟 女 73 C 5 106 楊建豐 男 42 E 6 107 黎梅佳 女 79 C 7 108 張興 男 91 A 8 109 馬進春 女 48 E 9 110 魏改娟 女 100 A 10 111 王冰研 女 64 D案例二
問題:在Sheet1里面如何查找折舊明細表中對應編號下的月折舊額?(跨表查詢)
方法:在Sheet1里面的C2:C4單元格輸入 =VLOOKUP(A2, 折舊明細表!A2:2:2:G$12, 7, 0)
python實現:使用merge將兩個表按照編號連接起來就行
df1 = pd.read_excel("test.xlsx", sheet_name='折舊明細表') df2 = pd.read_excel("test.xlsx", sheet_name=1) #題目里的sheet1 df2.merge(df1[['編號', '月折舊額']], how='left', on='編號') Out[]: 編號 資產名稱 月折舊額 0 YT001 電動門 1399 1 YT005 桑塔納轎車 1147 2 YT008 打印機 51案例三
問題:類似于案例二,但此時需要使用近似查找
方法:在B2:B7區域中輸入公式=VLOOKUP(A2&"*", 折舊明細表!$B$2:$G$12, 6, 0)
python實現:這個比起上一個要麻煩一些,需要用到一些pandas的使用技巧
df1 = pd.read_excel("test.xlsx", sheet_name='折舊明細表') df3 = pd.read_excel("test.xlsx", sheet_name=3) #含有資產名稱簡寫的表 df3['月折舊額'] = 0 for i in range(len(df3['資產名稱'])):df3['月折舊額'][i] = df1[df1['資產名稱'].map(lambda x:df3['資產名稱'][i] in x)]['月折舊額']df3 Out[]: 資產名稱 月折舊額 0 電動 1399 1 貨車 2438 2 惠普 132 3 交聯 10133 4 桑塔納 1147 5 春蘭 230案例四
問題:在Excel中錄入數據信息時,為了提高工作效率,用戶希望通過輸入數據的關鍵字后,自動顯示該記錄的其余信息,例如,輸入員工工號自動顯示該員工的信命,輸入物料號就能自動顯示該物料的品名、單價等。
如圖所示為某單位所有員工基本信息的數據源表,在“2010年3月員工請假統計表”工作表中,當在A列輸入員工工號時,如何實現對應員工的姓名、身份證號、部門、職務、入職日期等信息的自動錄入?
方法:使用VLOOKUP+MATCH函數,在“2010年3月員工請假統計表”工作表中選擇B3:F8單元格區域,輸入下列公式=IF(A3="","",VLOOKUP(A3="","",VLOOKUP(A3="","",VLOOKUP(A3,員工基本信息!A:A:A:H,MATCH(B$2,員工基本信息!$2:$2,0),0)),按下【Ctrl+Enter】組合鍵結束。
python實現:上面的Excel的方法用得很靈活,但是pandas的想法和操作更簡單方便些
df4 = pd.read_excel("test.xlsx", sheet_name='員工基本信息表') df5 = pd.read_excel("test.xlsx", sheet_name='請假統計表') df5.merge(df4[['工號', '姓名', '部門', '職務', '入職日期']], on='工號') Out[]: 工號 姓名 部門 職務 入職日期 0 A0004 龔夢娟 后勤 主管 2006-11-20 1 A0003 趙敏 行政 文員 2007-02-16 2 A0005 黃凌 研發 工程師 2009-01-14 3 A0007 王維 人事 經理 2006-07-24 4 A0016 張君寶 市場 工程師 2007-08-14 5 A0017 秦羽 人事 副經理 2008-03-06案例五
問題:用VLOOKUP函數實現批量查找,VLOOKUP函數一般情況下只能查找一個,那么多項應該怎么查找呢?如下圖,如何把張一的消費額全部列出?
方法:在C9:C11單元格里面輸入公式=VLOOKUP(B$9&ROW(A1),IF({1,0},$B$2:$B$6&COUNTIF(INDIRECT("b2:b"&ROW($2:$6)),B$9),$C$2:$C$6),2,),按SHIFT+CTRL+ENTER鍵結束。
python實現:vlookup函數有兩個不足(或者算是特點吧),一個是被查找的值一定要在區域里的第一列,另一個是只能查找一個值,剩余的即便能匹配也不去查找了,這兩點都能通過靈活應用if和indirect函數來解決,不過pandas能做得更直白一些。
df6 = pd.read_excel("test.xlsx", sheet_name='消費額') df6[df6['姓名'] == '張一'][['姓名', '消費額']] Out[]: 姓名 消費額 0 張一 100 2 張一 300 4 張一 1000數據透視表
數據透視表是Excel的另一個神器,本質上是一系列的表格重組整合的過程。這里用的案例來自知乎,Excel數據透視表有什么用途:(https://www.zhihu.com/question/22484899/answer/39933218 )
問題:需要匯總各個區域,每個月的銷售額與成本總計,并同時算出利潤
通過Excel的數據透視表的操作最終實現了下面這樣的效果:
python實現:對于這樣的分組的任務,首先想到的就是pandas的groupby,代碼寫起來也簡單,思路就是把剛才Excel的點鼠標的操作反映到代碼命令上:
df = pd.read_excel('test.xlsx', sheet_name='銷售統計表') df['訂購月份'] = df['訂購日期'].apply(lambda x:x.month) df2 = df.groupby(['訂購月份', '所屬區域'])[['銷售額', '成本']].agg('sum') df2['利潤'] = df2['銷售額'] - df2['成本'] df2Out[]: 銷售額 成本 利潤 訂購月份 所屬區域 1 南京 134313.61 94967.84 39345.77常熟 177531.47 163220.07 14311.40無錫 316418.09 231822.28 84595.81昆山 159183.35 145403.32 13780.03蘇州 287253.99 238812.03 48441.96 2 南京 187129.13 138530.42 48598.71常熟 154442.74 126834.37 27608.37無錫 464012.20 376134.98 87877.22昆山 102324.46 86244.52 16079.94蘇州 105940.34 91419.54 14520.80... ... ... 11 南京 286329.88 221687.11 64642.77常熟 2118503.54 1840868.53 277635.01無錫 633915.41 536866.77 97048.64昆山 351023.24 342420.18 8603.06蘇州 1269351.39 1144809.83 124541.56 12 南京 894522.06 808959.32 85562.74常熟 324454.49 262918.81 61535.68無錫 1040127.19 856816.72 183310.48昆山 1096212.75 951652.87 144559.87蘇州 347939.30 302154.25 45785.05[60 rows x 3 columns]也可以使用pandas里的pivot_table函數來實現:
df3 = pd.pivot_table(df, values=['銷售額', '成本'], index=['訂購月份', '所屬區域'] , aggfunc='sum') df3['利潤'] = df3['銷售額'] - df3['成本'] df3 Out[]: 成本 銷售額 利潤 訂購月份 所屬區域 1 南京 94967.84 134313.61 39345.77常熟 163220.07 177531.47 14311.40無錫 231822.28 316418.09 84595.81昆山 145403.32 159183.35 13780.03蘇州 238812.03 287253.99 48441.96 2 南京 138530.42 187129.13 48598.71常熟 126834.37 154442.74 27608.37無錫 376134.98 464012.20 87877.22昆山 86244.52 102324.46 16079.94蘇州 91419.54 105940.34 14520.80... ... ... 11 南京 221687.11 286329.88 64642.77常熟 1840868.53 2118503.54 277635.01無錫 536866.77 633915.41 97048.64昆山 342420.18 351023.24 8603.06蘇州 1144809.83 1269351.39 124541.56 12 南京 808959.32 894522.06 85562.74常熟 262918.81 324454.49 61535.68無錫 856816.72 1040127.19 183310.48昆山 951652.87 1096212.75 144559.87蘇州 302154.25 347939.30 45785.05[60 rows x 3 columns]pandas的pivot_table的參數index/ columns/ values和Excel里的參數是對應上的(當然,我這話說了等于沒說,數據透視表里不就是行/列/值嗎還能有啥。)
但是我個人還是更喜歡用groupby,因為它運算速度非常快。我在打kaggle比賽的時候,有一張表是貸款人的行為信息,大概有2700萬行,用groupby算了幾個聚合函數,幾秒鐘就完成了。
groupby的功能很全面,內置了很多aggregate函數,能夠滿足大部分的基本需求,如果你需要一些其他的函數,可以搭配使用apply和lambda。
不過pandas的官方文檔說了,groupby之后用apply速度非常慢,aggregate內部做過優化,所以很快,apply是沒有優化的,所以建議有問題先想想別的方法,實在不行的時候再用apply。
我打比賽的時候,為了生成一個新變量,用了groupby的apply,寫了這么一句:ins['weight'] = ins[['SK_ID_PREV', 'DAYS_ENTRY_PAYMENT']].groupby('SK_ID_PREV').apply(lambda x: 1-abs(x)/x.sum().abs()).iloc[:,1],1000萬行的數據,足足算了十多分鐘,等得我心力交瘁。
繪圖
因為Excel畫出來的圖能夠交互,能夠在圖上進行一些簡單操作,所以這里用的python的可視化庫是plotly,案例就用我這個學期發展經濟學課上的作業吧,當時的圖都是用Excel畫的,現在用python再畫一遍。開始之前,首先加載plotly包。
import plotly.offline as off import plotly.graph_objs as go off.init_notebook_mode()柱狀圖
當時用Excel畫了很多的柱狀圖,其中的一幅圖是
下面用plotly來畫一下
df = pd.read_excel("plot.xlsx", sheet_name='高等教育入學率') trace1 = go.Bar(x=df['國家'],y=df[1995],name='1995',opacity=0.6,marker=dict(color='powderblue'))trace2 = go.Bar(x=df['國家'],y=df[2005],name='2005',opacity=0.6,marker=dict(color='aliceblue',))trace3 = go.Bar(x=df['國家'],y=df[2014],name='2014',opacity=0.6,marker=dict(color='royalblue'))layout = go.Layout(barmode='group') data = [trace1, trace2, trace3] fig = go.Figure(data, layout) off.plot(fig)雷達圖
用Excel畫的:
用python畫的:
df = pd.read_excel('plot.xlsx', sheet_name='政治治理') theta = df.columns.tolist() theta.append(theta[0]) names = df.index df[''] = df.iloc[:,0] df = np.array(df)trace1 = go.Scatterpolar(r=df[0],theta=theta,name=names[0])trace2 = go.Scatterpolar(r=df[1],theta=theta,name=names[1])trace3 = go.Scatterpolar(r=df[2],theta=theta,name=names[2])trace4 = go.Scatterpolar(r=df[3],theta=theta,name=names[3])data = [trace1, trace2, trace3, trace4] layout = go.Layout(polar=dict(radialaxis=dict(visible=True,range=[0,1])),showlegend=True) fig = go.Figure(data, layout) off.plot(fig)畫起來比Excel要麻煩得多。
總體而言,如果畫簡單基本的圖形,用Excel是最方便的,如果要畫高級一些的或者是需要更多定制化的圖形,使用python更合適。
作者:廖致君
鏈接:https://www.jianshu.com/p/9bc9f473dd22
文源網絡,僅供學習之用,如有侵權請聯系刪除。
在學習Python的道路上肯定會遇見困難,別慌,我這里有一套學習資料,包含40+本電子書,800+個教學視頻,涉及Python基礎、爬蟲、框架、數據分析、機器學習等,不怕你學不會!
https://shimo.im/docs/JWCghr8prjCVCxxK/ 《Python學習資料》
關注公眾號【Python圈子】,優質文章每日送達。
總結
以上是生活随笔為你收集整理的Python和Excel的完美结合:常用操作汇总(案例详析)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 图片 变清晰_python
- 下一篇: 算法之排序算法-直接插入排序