1. 程式人生 > 實用技巧 >pandas庫學習

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    suzhou
2 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.9857141   2  電腦科學與技術2017級  ...       0.1428572   3  電腦科學與技術2017級  ...       0.2857143   4  電腦科學與技術2017級  ...       0.8142864   5  電腦科學與技術2017級  ...       0.942857                        否

[5 rows x 14 columns]
    序號         專業\n年級  ...  總綜合測評分\n排名百分比 總綜合測評分\n排名是否位於\n專業年級前1/3
66  67  電腦科學與技術2017級  ...       1.00000067  68  電腦科學與技術2017級  ...       0.51428668  69  電腦科學與技術2017級  ...       0.05714369  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.1428572   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.9641091   263.1667932   253.5284193   234.3426304   209.884241         否
..         ...       ...
65  275.30953066  124.55313867  245.93891368  272.38600069  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

好了熄燈了,未完待續。。。