04_Python 使用Pandas進(jìn)行統(tǒng)計(jì)分析與數(shù)據(jù)預(yù)處理

2019.5.18

人生苦短,我用Python。最近關(guān)于Python的學(xué)習(xí)是真的多,我也只能多線程地來學(xué)習(xí)了。今天丁燁老師上傳了最新的教案pdf,所以從今天開始,我又往我近期的列表里append了Pandas的學(xué)習(xí)。


Pandas

一.Pandas模塊


1. 概述

Pandas官網(wǎng)

pandas 是一個(gè)開源的,BSD許可的庫,為Python編程語言提供高性能,易于使用的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)分析工具Python長期以來一直非常適合數(shù)據(jù)整理和準(zhǔn)備,但對于數(shù)據(jù)分析和建模則不那么重要。pandas有助于填補(bǔ)這一空白,使您能夠在Python中執(zhí)行整個(gè)數(shù)據(jù)分析工作流程,而無需切換到更像域的特定語言,如R語言。

簡而言之,pandas是超越了numpy的一個(gè)數(shù)據(jù)處理和數(shù)據(jù)建模的模塊它具備了對數(shù)據(jù)的預(yù)處理,生成單列數(shù)據(jù),以及比numpy更為強(qiáng)大的數(shù)據(jù)結(jié)構(gòu),并且可以做出類似于SQL數(shù)據(jù)庫的操作,并可以直接使用numpy的值,更可以將數(shù)據(jù)導(dǎo)出成csv、Excel表等強(qiáng)大功能。



2.用法


  1. 兩種建模方式
    • Series:一維的、可帶標(biāo)簽的同構(gòu)數(shù)組對象(類似于數(shù)據(jù)庫中的一個(gè)字段,即一列)
    • DataFrame: 二維的、可帶標(biāo)簽的同構(gòu)數(shù)組。每一列必須同構(gòu),不同列可以異構(gòu)。(類似于數(shù)據(jù)庫中的一個(gè)關(guān)系表)
    • tips:Pandas不適合處理高維的數(shù)據(jù)。

  1. 創(chuàng)建對象

    Series可以通過列表或者元組來初始化,DataFrame可以通過一個(gè)Numpy數(shù)組或者字典來初始化下面使用到的pandas.date_range()是用于生成日期范圍的函數(shù),在這個(gè)例子中,用于生成作為索引的日期。

    import numpy as np
    import pandas as pd
    # 直接利用一個(gè)列表來初始化Series,其中numpy.nan是類似于NULL的存在
    s = pd.Series([1, 3, 5, np.nan, 6, 8])
    print(s)
    """Output
    0    1.0
    1    3.0
    2    5.0
    3    NaN # 輸出空值
    4    6.0
    5    8.0
    dtype: float64 #數(shù)值默認(rèn)為float型
    """
    dates = pd.date_range('20130101', periods=6) # 生成日期范圍的函數(shù),起始日期為2013/01/01,時(shí)期為6天
    print(dates)
    """Output
    DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
                '2013-01-05', '2013-01-06'],
               dtype='datetime64[ns]', freq='D')
    """
    # 通過Numpy數(shù)組來生成DataFrame對象,并以上面生成的日期范圍作為索引,屬性列也命名為'ABCD'這四個(gè)值。
    df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
    print(df)
    """Output
                   A          B         C         D
    2013-01-01 -1.970029  2.080632 -0.450484 -0.149300
    2013-01-02  0.202809 -2.384539 -0.295012 -0.419630
    2013-01-03  0.436642 -0.214195 -1.677464  0.545785
    2013-01-04  0.809162 -0.489416  0.379824  1.168125
    2013-01-05 -0.846945  1.277425 -1.383941 -1.921999
    2013-01-06 -0.174712 -0.063350 -0.265923 -0.233885
    """
    # 你還可以用通過一個(gè)字典來初始化DataFrame對象,Timestamp是一個(gè)時(shí)間戳函數(shù)
    df2 = pd.DataFrame({'A': 1., 'B': pd.Timestamp('20130102'), 'C': pd.Series(1, index=list(range(4)), dtype='float32'), 'D': np.array([3] * 4, dtype='int32'), 'E': pd.Categorical(["test", "train", "test", "train"]), 'F': 'foo'})
    print(df2) # 可以看到,字典的鍵成為了列的屬性名。
    """Output
        A      B        C   D     E    F
    0  1.0 2013-01-02  1.0  3   test  foo
    1  1.0 2013-01-02  1.0  3  train  foo
    2  1.0 2013-01-02  1.0  3   test  foo
    3  1.0 2013-01-02  1.0  3  train  foo
    """
    print(df2.dtypes) # DataFrame很像關(guān)系型數(shù)據(jù)庫的一張關(guān)系表,每一列可以異構(gòu),但同一列必須同構(gòu)
    """Output
    A           float64
    B    datetime64[ns]
    C           float32
    D             int32
    E          category
    F            object
    dtype: object
    """
    

  1. 數(shù)據(jù)的訪問

    DataFrame對象中許多的方法可以對其中的特定數(shù)據(jù)進(jìn)行訪問。例如head()、tail()等,其中又有很多屬性可以訪問特定的值。以下會(huì)舉一些常用的例子。DataFrame提供了一個(gè)可以讓自己轉(zhuǎn)換為Numpy數(shù)據(jù)的函數(shù)to_numpy()* ,但Pandas 和 NumPy 有結(jié)構(gòu)上的本質(zhì)區(qū)別*: Pandas 允許 DataFrame 中的每一列數(shù)據(jù)設(shè)置為不同的數(shù)據(jù)結(jié)構(gòu);而 NumPy 要求整個(gè)數(shù)組同構(gòu)。 當(dāng)使用 DataFrame.to_numpy() 時(shí),Pandas 將尋找 NumPy 中最近的能表達(dá)原始數(shù)據(jù)dtype。如果 dtype 不同,Pandas 將對每一個(gè)數(shù)據(jù)元素調(diào)用格式轉(zhuǎn)換函數(shù)因此,當(dāng) DataFrame 元素較多的時(shí)候,此函數(shù)將消耗大量時(shí)間

    print(df.head()) # 輸出DataFrame對象的開頭幾行。默認(rèn)是前5行,可以自定義
    """Output
                    A         B         C         D
    2013-01-01 -1.970029  2.080632 -0.450484 -0.149300
    2013-01-02  0.202809 -2.384539 -0.295012 -0.419630
    2013-01-03  0.436642 -0.214195 -1.677464  0.545785
    2013-01-04  0.809162 -0.489416  0.379824  1.168125
    2013-01-05 -0.846945  1.277425 -1.383941 -1.921999
    """
    print(df.tail(2)) # 輸出DataFrame對象的末尾幾行。與head()一樣輸出的行數(shù)可以自定義,這里自定義為輸出最后兩行
    """Output
                    A         B         C         D
    2013-01-05 -0.846945  1.277425 -1.383941 -1.921999
    2013-01-06 -0.174712 -0.063350 -0.265923 -0.233885
    """
    print(df.index) # 輸出索引值
    """Output
    DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
                '2013-01-05', '2013-01-06'],
               dtype='datetime64[ns]', freq='D')
    """
    print(df.columns) # 輸出列屬性名
    """Output
    Index(['A', 'B', 'C', 'D'], dtype='object')
    """
    print(df.to_numpy()) # 將DataFrame轉(zhuǎn)換為Numpy數(shù)組
    """Output
    [[-1.97002931  2.08063244 -0.45048393 -0.14929988]
     [ 0.20280913 -2.38453931 -0.29501209 -0.41962973]
     [ 0.43664217 -0.21419501 -1.67746363  0.54578509]
     [ 0.80916191 -0.48941566  0.37982384  1.1681251 ]
     [-0.84694546  1.27742454 -1.38394127 -1.92199883]
     [-0.17471197 -0.06335029 -0.2659226  -0.23388499]]
    """
    print(df2.to_numpy()) # 由于DataFrame的每一列可能不同構(gòu),所以比較復(fù)雜時(shí),轉(zhuǎn)化為Numpy數(shù)組花的時(shí)間要長一些
    """Output
    [[1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'test' 'foo']
     [1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'train' 'foo']
     [1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'test' 'foo']
     [1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'train' 'foo']]
    """
    print(df.describe()) # 使用 describe() 函數(shù)可以把數(shù)據(jù)的統(tǒng)計(jì)信息展示出來
    """Output
               A         B         C         D
    count  6.000000  6.000000  6.000000  6.000000
    mean  -0.257179  0.034426 -0.615500 -0.168484
    std    1.011785  1.544615  0.769556  1.042999
    min   -1.970029 -2.384539 -1.677464 -1.921999
    25%   -0.678887 -0.420610 -1.150577 -0.373194
    50%    0.014049 -0.138773 -0.372748 -0.191592
    75%    0.378184  0.942231 -0.273195  0.372014
    max    0.809162  2.080632  0.379824  1.168125
    """
    print(df.T) # 輸出DataFrame的轉(zhuǎn)置矩陣
    """Output
       2013-01-01  2013-01-02  2013-01-03  2013-01-04  2013-01-05  2013-01-06
    A   -1.970029    0.202809    0.436642    0.809162   -0.846945   -0.174712
    B    2.080632   -2.384539   -0.214195   -0.489416    1.277425   -0.063350
    C   -0.450484   -0.295012   -1.677464    0.379824   -1.383941   -0.265923
    D   -0.149300   -0.419630    0.545785    1.168125   -1.921999   -0.233885
    """Output
    print(df.sort_index(axis=1, ascending=False)) 
    # 根據(jù)索引進(jìn)行排序,axis表示你要排序的軸,axis=0表示豎軸,axis=1表示橫軸
    # 而ascending表示是否按照升序來排序,默認(rèn)是True
    """Output
                    D         C         B         A
    2013-01-01 -0.149300 -0.450484  2.080632 -1.970029
    2013-01-02 -0.419630 -0.295012 -2.384539  0.202809
    2013-01-03  0.545785 -1.677464 -0.214195  0.436642
    2013-01-04  1.168125  0.379824 -0.489416  0.809162
    2013-01-05 -1.921999 -1.383941  1.277425 -0.846945
    2013-01-06 -0.233885 -0.265923 -0.063350 -0.174712
    """
    print(df.sort_values(by='B')) # 根據(jù)給定的列名,根據(jù)值的大小來排序,同樣有ascending采納數(shù)
    """Output
                    A         B         C         D
    2013-01-02  0.202809 -2.384539 -0.295012 -0.419630
    2013-01-04  0.809162 -0.489416  0.379824  1.168125
    2013-01-03  0.436642 -0.214195 -1.677464  0.545785
    2013-01-06 -0.174712 -0.063350 -0.265923 -0.233885
    2013-01-05 -0.846945  1.277425 -1.383941 -1.921999
    2013-01-01 -1.970029  2.080632 -0.450484 -0.149300
    """
    

  1. 選取數(shù)據(jù)、索引

    類似 NumPy,Pandas 亦提供了多種多樣的選擇數(shù)據(jù)的函數(shù)和成員變量。

    # 選擇一列中的數(shù)據(jù):
    print(df['A']) # 單獨(dú)輸出屬性名為'A'的一列數(shù)據(jù),返回一個(gè)Series對象
    """Output
    2013-01-01   -2.330696
    2013-01-02   -0.318615
    2013-01-03    0.667367
    2013-01-04    0.241847
    2013-01-05    1.304542
    2013-01-06   -0.343536
    Freq: D, Name: A, dtype: float64
    """
    # Pandas還可以通過[]來截取一部分?jǐn)?shù)據(jù),用于輸出指定范圍的行
    print(df[0:3])
    """Output
                    A         B         C         D
    2013-01-01 -2.330696 -1.421068 -1.734107  2.486537
    2013-01-02 -0.318615 -1.274842  0.030403 -0.133000
    2013-01-03  0.667367  1.288029 -0.291147 -1.978817
    """
    
    # 使用loc和iloc來訪問數(shù)據(jù)
    # loc是使用特定的標(biāo)簽來訪問數(shù)據(jù)的
    # iloc可以通過數(shù)字來定位哪行哪列的數(shù)據(jù)
    print(df.loc[:, ['A', 'B']]) # pandas.DataFrame.loc可以通過標(biāo)簽來訪問特定數(shù)據(jù)
    """Output
                    A         B
    2013-01-01 -2.330696 -1.421068
    2013-01-02 -0.318615 -1.274842
    2013-01-03  0.667367  1.288029
    2013-01-04  0.241847  0.116068
    2013-01-05  1.304542  0.757466
    2013-01-06 -0.343536  0.542275
    """
    print(df.iloc[3:5, 0:2]) # pandas.DataFrame.iloc是通過整數(shù)來訪問特定數(shù)據(jù)的
    """Output
                    A         B
    2013-01-04  0.241847  0.116068
    2013-01-05  1.304542  0.757466
    """
    
    # 使用布爾值來選取數(shù)據(jù)
    print(df[df.A > 0]) # 會(huì)輸出復(fù)合條件的記錄
    """Output
                    A         B         C         D
    2013-01-03  0.667367  1.288029 -0.291147 -1.978817
    2013-01-04  0.241847  0.116068 -1.386416  1.203264
    2013-01-05  1.304542  0.757466 -0.036668  1.030613
    """
    

  1. 處理缺失值

    類似于Numpy和關(guān)系型數(shù)據(jù)庫,數(shù)據(jù)中難免有一些空白值,而 在Pandas中,空值將會(huì)被賦值成Numpy的nan類型。 我們使用reindex函數(shù)可以方便的新增、修改、刪除索引。

    # 存儲(chǔ)為空值
    df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E']) # 為df增加一個(gè)E列,并存儲(chǔ)在df1
    df1.loc[dates[0]:dates[1], 'E'] = 1 # 只給部分?jǐn)?shù)據(jù)賦值
    print(df1) # 未賦值的值是NaN
    """Output
                    A         B         C         D    E
    2013-01-01 -2.330696 -1.421068 -1.734107  2.486537  1.0
    2013-01-02 -0.318615 -1.274842  0.030403 -0.133000  1.0
    2013-01-03  0.667367  1.288029 -0.291147 -1.978817  NaN
    2013-01-04  0.241847  0.116068 -1.386416  1.203264  NaN
    """
    
    # 丟棄所有空值
    print(df1.dropna(how='any')) # how指定了丟棄空值的方式,這里指所有
    """Output
                    A         B         C         D    E
    2013-01-01 -2.330696 -1.421068 -1.734107  2.486537  1.0
    2013-01-02 -0.318615 -1.274842  0.030403 -0.133000  1.0
    """
    
    # 利用指定值填補(bǔ)所有的空值
    print(df1.fillna(value=5)) # values為指定的值
    """Output
                    A         B         C         D    E
    2013-01-01 -2.330696 -1.421068 -1.734107  2.486537  1.0
    2013-01-02 -0.318615 -1.274842  0.030403 -0.133000  1.0
    2013-01-03  0.667367  1.288029 -0.291147 -1.978817  5.0 # NaN已經(jīng)被替代為5
    2013-01-04  0.241847  0.116068 -1.386416  1.203264  5.0
    """
    

  1. 像數(shù)據(jù)庫一樣使用DataFrame

    DataFrame對象與關(guān)系型數(shù)據(jù)庫的關(guān)系表相似不僅僅是因?yàn)樗鼈兌际嵌S表而是DataFrame可以進(jìn)行和數(shù)據(jù)庫一樣的數(shù)據(jù)操作。例如:自然連接、笛卡爾積等。

    # 等值連接
    left = pd.DataFrame({'key': ['foo', 'bar'], 'lval': [1, 2]}) # 創(chuàng)建兩個(gè)待連接的表
    right = pd.DataFrame({'key': ['foo', 'bar'], 'rval': [4, 5]})
    print(pd.merge(left, right, on='key')) # on指定根據(jù)什么值相等去連接
    """Output
       key   lval   rval
    0  foo     1     4
    1  bar     2     5
    """
    # 笛卡爾積,同樣是連接,但由于有相同的鍵,所以會(huì)進(jìn)行笛卡爾積
    left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})
    right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})
    print(pd.merge(left, right, on='key'))
    """Output
       key   lval   rval
    0  foo     1     4
    1  foo     1     5
    2  foo     2     4
    3  foo     2     5
    """
    # 分組
    # 1. 將數(shù)據(jù)根據(jù)特定的條件分為幾個(gè)不同的組
    # 2. 對每組數(shù)據(jù)做數(shù)學(xué)操作(例如 count:清點(diǎn)數(shù)量)
    # 3. 將結(jié)果輸出成一個(gè)完整的數(shù)據(jù)結(jié)構(gòu)
    df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'C': np.random.randn(8), 'D': np.random.randn(8)})
    print(df.groupby('A').sum())
    """Output
            C         D
    A
    bar  1.63216 -0.493714
    foo  1.89041 -0.111024
    """
    


  1. 導(dǎo)入導(dǎo)出數(shù)據(jù)

Pandas除了可以自己構(gòu)造數(shù)據(jù)之外,同時(shí)具有 從csv、hdf、Excel表等文件讀入數(shù)據(jù),以及將數(shù)據(jù)寫到這些文件中的功能。需要注意到的是,所有的read方法都是來自于Pandas的,而所有的to(寫數(shù)據(jù)到文件中)方法都是屬于DataFrame的。


  • 讀數(shù)據(jù):
    • Pandas.read_csv()
    • Pandas.read_hdf()
    • Pandas.read_excel()
    • 這三個(gè)函數(shù)就是Pandas分別用于從csv、hdf、Excel表三種數(shù)據(jù)文件中讀取表格數(shù)據(jù),并將其存儲(chǔ)于一個(gè)DataFrame對象的函數(shù)(點(diǎn)擊可跳到API文檔)

  • 寫數(shù)據(jù)
    • Pandas.DataFrame.to_csv()
    • Pandas.DataFrame.to_hdf()
    • Pandas.DataFrame.to_excel()
    • 這三個(gè)函數(shù)可以將DataFrame對象的數(shù)據(jù)寫入到三種文件類型中去。(點(diǎn)擊可跳到API文檔)
    • 重點(diǎn):
      1. 使用to_excel()將數(shù)據(jù)寫到excel之前需要pip安裝openpyxl庫。
      2. to_系列的函數(shù)中,有mode, index兩個(gè)參數(shù),前者表示寫數(shù)據(jù)的模式,有w、r、a(write、read、append)等,與C語言的文件讀寫模式相似;index則表示寫數(shù)據(jù)要不要把索引寫進(jìn)去,默認(rèn)是True,但我使用時(shí)一般設(shè)為False。


  1. Pandas與SQL數(shù)據(jù)庫合作

    Pandas除了可以自己初始化或者從文件中讀取數(shù)據(jù)之外還可以直接和數(shù)據(jù)庫進(jìn)行交互,運(yùn)行SQL語句,讀寫和查詢數(shù)據(jù)庫的數(shù)據(jù)。


1. pymssql的安裝
因?yàn)槲覀€(gè)人使用的數(shù)據(jù)庫是SQL Server,所以為了讓pandas進(jìn)行對mssql的操作,就要安裝pymssql庫,來進(jìn)行mssql的操作。如果使用其他的數(shù)據(jù)庫,就需要安裝其他的py庫。
python pip install pymssql


2. pymssql的使用練習(xí)
> * 連接到mssql數(shù)據(jù)庫
> * pymssql.connect(),用于設(shè)置連接數(shù)據(jù)庫的信息, server需要提供IP或者localhost,user是指用戶名(默認(rèn)是sa),database指需要連接的數(shù)據(jù)庫的名字.返回一個(gè)connection類對象

  ```python
  import pymssql
  conn = pymssql.connect(server="127.0.0.1",user="zackary",password="*****XTZBw*****",database="master")
  ```
  
  > * **讀寫數(shù)據(jù)庫數(shù)據(jù)**
  > * **pandas.read_sql** **(** **sql**, **con**,  *index_col=None, coerce_float=True, params=None, parse_dates=None, columns=None, chunksize=None*  **)**
  **其中sql表示sql查詢語句或者表名, con為connection類的對象; 返回一個(gè)DataFrame類對象,所以要用pandas庫來操作**
  > * **pandas.DataFrame.to_sql** **(** *name, con, schema=None, if_exists='fail', index=True, index_label=None, chunksize=None, dtype=None, method=None* **)**
  > *這個(gè)是DataFrame中的寫數(shù)據(jù)庫的函數(shù)*,**由于read_sql( )返回的是DataFrame類的對象,所以用pandas進(jìn)行相應(yīng)的操作之后,可以用to_sql( )函數(shù)來將數(shù)據(jù)寫入數(shù)據(jù)庫,其中name是表名.** *由于不想改變我的sql表的數(shù)據(jù),就不演示了。*
  > * **由于每個(gè)人的數(shù)據(jù)庫不一樣,所以以下的例子需要修改成你電腦上的樣子**

  ```python
  import pandas as pd
  # sql是你要執(zhí)行的查詢語句
  sql = "select * from [master].[dbo].[MSreplication options]"
  df1 = pd.read_sql(sql,conn)
  print(df1)
  ```

  ![從數(shù)據(jù)庫master中讀取數(shù)據(jù)](https://upload-images.jianshu.io/upload_images/18517645-ef2293241eca4570.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


二.利用pandas進(jìn)行數(shù)據(jù)清理實(shí)例

練習(xí)的來源是我的《Python數(shù)據(jù)分析》的任課老師丁燁的pdf,如果你有興趣,請點(diǎn)擊此處


  1. 讀取數(shù)據(jù)
  • 利用 read_csv( ) 方法將一個(gè)csv文件讀入到DataFrame對象中,利用head( )查看頭5行數(shù)據(jù)(實(shí)際有700多行)。
顯示df的前5行

  1. 數(shù)據(jù)預(yù)處理
  1. Pandas.DataFrame.rename(mapper=None, index=None, columns=None, axis=None, copy=True, inplace=False, level=None)
    可以 對參數(shù)列表內(nèi)的屬性進(jìn)行重命名修改方法是采用字典的方式.本例就是將名為"#"的列改名為"id",inplace參數(shù)表明要不要修改,還是臨時(shí)顯示修改的副本
  2. 利用 str.lower( ) 將所有列屬性的名字都改成小寫
  3. Pandas.DataFrame.duplicated(subset=None, keep='first')
    用于標(biāo)記重復(fù)數(shù)據(jù)的函數(shù)subset表示"參考為重復(fù)因素的列",等于None時(shí)表示全部列(默認(rèn));keep指不標(biāo)記的那個(gè)"例外",keep有三個(gè)取值,分別是'first', 'last', False,分別表示不標(biāo)記第一個(gè),不標(biāo)記最后一個(gè),標(biāo)記全部(默認(rèn))
df.rename(columns={'#': 'id'}, inplace=True)
df.columns = df.columns.str.lower()
df[df.duplicated('id', keep=False)].head()
數(shù)據(jù)預(yù)處理

  1. 清洗數(shù)據(jù),去除重復(fù)項(xiàng)
  1. DataFrame.drop_duplicates(subset=None, keep='first', inplace=False)
    用于刪除重復(fù)項(xiàng),這里可以看到.subset的值為'id',可知是只查找'id'列中重復(fù)的值; keep的取值為'first',指只留下重復(fù)項(xiàng)的第一個(gè);inplace代表替代原數(shù)據(jù)。
  2. df['type 2']指屬性為type 2的所有數(shù)據(jù)(那一列), fillna( )會(huì)用values(這里是用了None)填補(bǔ)原先為numpy.na(空)的數(shù)據(jù),這里使所有的空數(shù)據(jù)項(xiàng)變成None。
df.drop_duplicates('id', keep='first', inplace=True)
df['type 2'].fillna(value='None', inplace=True)

  1. 按需拆分表格
  1. pokedex拆分出df中的幾個(gè)屬性出來,成為了一張新表,存儲(chǔ)id, name等信息。
  2. pandas.merge( )將df表和pokedex表進(jìn)行外表連接(數(shù)據(jù)庫的操作), on表示它們是在'id'相同處拼接的.同時(shí),將id, hp, attack等屬性(以及數(shù)據(jù))賦值給statistics表,得到數(shù)據(jù)。
pokedex = df[['id', 'name', 'type 1', 'type 2', 'generation', 'legendary']]
statistics = pd.merge(df, pokedex, on='id').loc[:, ['id', 'hp', 'attack', 'defense', 'sp. atk', 'sp. def', 'speed', 'total']]
pokedex

statistics


  1. 使用seaborn畫圖

  1. seaborn是一個(gè)數(shù)據(jù)可視化的庫,類似于 matplotlib
  2. 在linux下安裝seaborn時(shí),可能會(huì)出現(xiàn)這樣的錯(cuò)誤
    Error
    這時(shí)候需要安裝一些東西。
sudo apt-get install at-spi2-core

  • 繪圖

    1. seaborn可以像matplotlib一樣繪圖但顯示不是用seaborn,而是用pyplot.所以在使用的時(shí)候要加上plt.show()
    2. 丁燁老師這里的pdf是有錯(cuò)誤的,用了中文的引號。由此我見識到了一個(gè)有趣的錯(cuò)誤
      SynataxError: EOL while scanning string literal當(dāng)字符串的最后一個(gè)字符是斜杠或者不是ASCII碼時(shí),報(bào)錯(cuò)。
      Error
    3. factplot( )函數(shù)已改名為catplot( )
      函數(shù)名變更
    from matplotlib import pyplot as plt
    sns.factorplot(x='generation', data=pokedex, kind='count').set_axis_labels('Generation',  '# of Pokemon')
    plt.show()
    
    seaborn繪圖

  • 繪圖實(shí)例

    1. seaborn.catplot()
      catplot()擁有著十分多的參數(shù),這里會(huì)講解例子中用到的參數(shù)。 y代表y軸是什么,data表示數(shù)據(jù)源。通過kind生成不同類別的圖, kind的取值有: strip, swarm, box, violin,boxen,point, bar, count,strip為默認(rèn)值;order指排序。
    sns.factorplot(y='type 1',data=pokedex,kind='count',order=pokedex['type 1'].value_counts().index,aspect=1.5,color='green').set_axis_labels('# of Pokemon', 'Type 1')
    sns.factorplot(y='type 2',data=pokedex,kind='count',order=pokedex['type 2'].value_counts().index,aspect=1.5,color='purple').set_axis_labels('# of Pokemon', 'Type 2')
    
    案例


  1. 統(tǒng)計(jì)出前十最強(qiáng)的寶可夢

思路:
1. 將數(shù)據(jù)的處理編寫成函數(shù)便于管理
2. 用merge( )將兩個(gè)表連接
3. 使用sort_values( )對table表進(jìn)行排序
4. 使用catplot( )畫圖

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns

def dataProcess():
    """ The function is to get, select and clean the data"""
    # To get the csv file
    df = pd.read_csv('https://dingye.me/src/pokemon-v0.5.27.csv')
    df.rename(columns={'#': 'id'}, inplace=True)
    df.columns = df.columns.str.lower()
    # Just show the first five tuple
    df[df.duplicated('id', keep=False)].head()

    df.drop_duplicates('id', keep='first', inplace=True)
    df['type 2'].fillna(value='None', inplace=True)
    pokedex = df[['id', 'name', 'type 1', 'type 2', 'generation', 'legendary']]
    statistics = pd.merge(df, pokedex, on='id')
    statistics = statistics.loc[:, ['id', 'hp', 'attack', 'defense', 'sp. atk', 'sp. def', 'speed', 'total']]
    return statistics, pokedex
    """
    return pokedex
    """

if __name__ == "__main__":
    """
    pokedex = dataProcess()
    sns.catplot(x='generation', data=pokedex, kind='count').set_axis_labels('Generation', '# of Pokemon')
    # You need to use this function to show the pictures
    plt.show()
    """

    # To get, select and clean the data
    statistics, pokedex = dataProcess()
    table = pd.merge(pokedex,statistics, on='id')
    # print(table)
    table = table.sort_values(by='total', ascending=False)
    print(table)

    # Make it virtualization
    sns.catplot(x='total', y='name', data=table[:10], kind='bar').set_axis_labels('# of Top ten Pokemon', 'The total counts')
    plt.title('Top ten pokemon')
    plt.show()

前十的寶可夢


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,807評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,769評論 2 372

推薦閱讀更多精彩內(nèi)容