pandas庫學習
引言:pandas庫基於NumPy 的一種工具,該工具是為了解決資料分析任務而建立的。Pandas納入了大量庫和一些標準的資料模型,提供了高效地操作大型資料集所需的工具。pandas提供了大量能使我們快速便捷地處理資料的函式和方法。
1.建立資料
pandas庫建立資料主要通過兩種方式:讀取本地檔案和手動建立資料
1.1讀取本地檔案(支援csv,xlsx,xls等等)
data=pandas.read_excel("learn.xls")
其中learn.xls是我放在當前目錄下一個excel檔案,本文將以該檔案作為例子介紹pandas庫。
該excel檔案是某所大學官網提供的當年保研學生成績相關公示資訊。(僅供學習所用,不作商業用途)
1.2手動建立資料:
data2={ 'name':["sky","gw","cmm"], 'age':[18,20,23], 'location':["yangzhou","suzhou","suqian"] } data_pandas=pandas.DataFrame(data2)
首先建立一個data2的字典,再將字典模式轉換成對應的DataFrame型別,其中DataFrame型別就相當於一個矩陣,其中每一列資料都是series型別。
列印一下:
name age location 0 sky 18 yangzhou 1 gw 20 suzhou2 cmm 23 suqian
第一列表示序號,從0開始,其餘都是字典中一一對應的key和value。
2.pandas常用函式方法:
#函式方法 print(type(data)) print(data.dtypes) print(data.shape)#矩陣的大小 print(data.columns)#列名
其中type(data)是整個資料的型別對應DataFrame,
而data.dtype對應的是每個series的型別,即每一列元素的資料型別。
結果如下:
<class 'pandas.core.frame.DataFrame'> 序號 int64 專業\n年級 object 專業年級\n人數 int64 姓名 object 學號 int64 是否申請推免研究生 object 第一學年\n綜合測評分 float64 第二學年\n綜合測評分 float64 第三學年\n綜合測評分 float64 第四學年\n綜合測評分 float64 總綜合\n測評分 float64 總綜合測\n評分排名 int64 總綜合測評分\n排名百分比 float64 總綜合測評分\n排名是否位於\n專業年級前1/3 object dtype: object (70, 14) Index(['序號', '專業\n年級', '專業年級\n人數', '姓名', '學號', '是否申請推免研究生', '第一學年\n綜合測評分', '第二學年\n綜合測評分', '第三學年\n綜合測評分', '第四學年\n綜合測評分', '總綜合\n測評分', '總綜合測\n評分排名', '總綜合測評分\n排名百分比', '總綜合測評分\n排名是否位於\n專業年級前1/3'], dtype='object')
由於我是直接匯入的excel檔案所以,列名中存在一些換行符即\n。
3.取資料相關方法:
其中DataFrame物件有head()和tail()方法,來獲取資料集中前n行資料和後n行資料:
print(data.head(5))#前5個 print(data.tail(4))#後4個
結果如下:
序號 專業\n年級 ... 總綜合測評分\n排名百分比 總綜合測評分\n排名是否位於\n專業年級前1/3 0 1 電腦科學與技術2017級 ... 0.985714 否 1 2 電腦科學與技術2017級 ... 0.142857 是 2 3 電腦科學與技術2017級 ... 0.285714 是 3 4 電腦科學與技術2017級 ... 0.814286 否 4 5 電腦科學與技術2017級 ... 0.942857 否 [5 rows x 14 columns] 序號 專業\n年級 ... 總綜合測評分\n排名百分比 總綜合測評分\n排名是否位於\n專業年級前1/3 66 67 電腦科學與技術2017級 ... 1.000000 否 67 68 電腦科學與技術2017級 ... 0.514286 否 68 69 電腦科學與技術2017級 ... 0.057143 是 69 70 電腦科學與技術2017級 ... 0.400000 否 [4 rows x 14 columns]
因為內容過多,我選用IDE中的pycharm進行編譯,中間內容被省略了;如果安裝了anaconda,可以使用j編譯;
說句廢話,我之所以用pycharm而不用後者,原因是pycharm檢視原始碼比較方便,便於初學者學習。
迴歸正題,我們取到前5行資料和後4行資料,當然我們還可以指定獲取某一行資料:
print(data.loc[0])#取第一個樣本資料 print(data.loc[1:2])#取第二個和第三個樣本 grade=data["總綜合\n測評分"]#列印某一列資料 print(grade)
結果如下:
序號 1 專業\n年級 電腦科學與技術2017級 專業年級\n人數 70 姓名 馬佳 學號 1413022013 是否申請推免研究生 否 第一學年\n綜合測評分 50.997 第二學年\n綜合測評分 56.0876 第三學年\n綜合測評分 60.8795 第四學年\n綜合測評分 NaN 總綜合\n測評分 167.964 總綜合測\n評分排名 69 總綜合測評分\n排名百分比 0.985714 總綜合測評分\n排名是否位於\n專業年級前1/3 否 Name: 0, dtype: object 序號 專業\n年級 ... 總綜合測評分\n排名百分比 總綜合測評分\n排名是否位於\n專業年級前1/3 1 2 電腦科學與技術2017級 ... 0.142857 是 2 3 電腦科學與技術2017級 ... 0.285714 是 0 167.964109 1 263.166793 2 253.528419 3 234.342630 4 209.884241 ... 65 275.309530 66 124.553138 67 245.938913 68 272.386000 69 248.137000
當列印第一行資料時,資料量較少內容全部展示出來,列印某一列資料也能夠展示如上圖,我們驗證一下它的型別是否是之前介紹的series:
print(type(grade))
<class 'pandas.core.series.Series'>
確實是series型別,當然series也有不少函式方法,但是幾乎都能通過DataFrame中方法實現,所以不再一一贅述。
列印幾列資料時,可以把列名放入一個數組傳入:
list=["總綜合\n測評分","是否申請推免研究生"]#列印幾列資料 listdata=data[list] print(listdata)
總綜合\n測評分 是否申請推免研究生 0 167.964109 否 1 263.166793 否 2 253.528419 否 3 234.342630 否 4 209.884241 否 .. ... ... 65 275.309530 是 66 124.553138 否 67 245.938913 否 68 272.386000 否 69 248.137000 否 [70 rows x 2 columns]
4.資料預處理
細心的朋友可能發現了,這個excel表中第67行缺少資料,缺失的是第一學年的成績,可能是因為各種原因沒有完成相關學業。
這樣一來我們發現他的綜測總分只有124分,和別的同學差了一大截,這對於資料分析來說很致命。
當然我們有兩組解決途徑:
一是:當所有NaN即缺失值設為0,這種做法優點在於簡單易操作,但缺點是造成資料波動很大,不利於資料分析。
二是:將缺失值設定為該列非缺失值的平均值,用均值才代替缺失值。
我採用了第二種方法通過一個函式實現:
#空值處理,用不含空值的均值填充 def deal_nan(data): cols=data.columns.tolist()#將所有列放入列表 for col in cols:#遍歷每一列 if data[col].dtype != 'object':#缺失值資料型別不為object型別時用均值替代 col_is_null=pandas.isnull(data[col])#判斷該列中每一行資料是否為空 validaverage=data[col][col_is_null==False].mean()#將該列中非空的值取均值 data[col].fillna(validaverage, inplace=True)#將缺失值用均值替代。 else: data[col].fillna('缺失資料', inplace=True)#object型別,用缺失資料替代 print(data["第一學年\n綜合測評分"]) deal_nan(data)
通過這個函式直接完成了資料的預處理,object型別與python面向物件那個object不同,這裡的object把它理解成string型別更容易理解;
fillna函式用來填充NaN值,inplace表示是否替代NaN。
直接顯示下結果:
0 50.997000
1 85.584375
2 83.699950
3 80.287850
4 65.183775
...
65 88.214525
66 80.312378
67 77.029400
68 90.260000
69 79.240000
因為下標從0開始,所以對應66號,得分為80.312378,可見第一學年該專業參加考試的均分為80.312378。
我們之後的資料處理,都將用均值來填充NaN。
這組資料中,只有三年的總分,卻沒有平均分,所以資料比較起來差距有些大,我們不妨用三年均分來表現各個學生的學生狀況,
所以我們計算並且把計算的結果放入到DataFrame這個資料集中:
averagegrade=(data["第一學年\n綜合測評分"]+data["第二學年\n綜合測評分"]+data["第三學年\n綜合測評分"])/3 data["average"]=averagegrade; print(data["average"])
新產生的列取名‘average’列印一下:
0 55.988036
1 87.722264
2 84.509473
3 78.114210
4 69.961414
...
65 91.769843
66 68.288505
67 81.979638
68 90.795333
69 82.712333
得到了各個學生的三年綜測均分。
5.資料排序篩選
這個資料集是針對學生保研情況,保研通常選取較為優秀的學生,所以我們需要根據學生三年的綜測均分進行排序:
data.sort_values("average",inplace=True)#從小到大 print(data[['學號','姓名','average']])
學號 姓名 average 0 1413022013 馬佳 55.988036 57 1713021050 宋益濤 67.361837 13 1713021008 李傑 68.123348 66 1713021060 潘科亦 68.288505 4 1615032107 汪邦國 69.961414 .. ... ... ... 37 1626022054 金王煜 89.854018 68 1726021007 許星波 90.795333 15 1713021010 楊金宇 90.987460 65 1713021059 沈天任 91.769843 5 1615062105 袁鈺 93.156638
inplace=True表示根據排序後資料進行更新。
最好的學生放到最後那可不行,我們試試倒序:
data.sort_values("average",inplace=True,ascending=False)#從大到小 print(data[['學號','姓名','average']])
ascending=False,這個在資料庫裡也很常見用於倒序:
[70 rows x 3 columns] 學號 姓名 average 5 1615062105 袁鈺 93.156638 65 1713021059 沈天任 91.769843 15 1713021010 楊金宇 90.987460 68 1726021007 許星波 90.795333 37 1626022054 金王煜 89.854018 .. ... ... ... 4 1615032107 汪邦國 69.961414 66 1713021060 潘科亦 68.288505 13 1713021008 李傑 68.123348 57 1713021050 宋益濤 67.361837 0 1413022013 馬佳 55.988036
好了熄燈了,未完待續。。。