1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        【Python】我的Pandas學習經(jīng)歷及動手實踐

        共 10023字,需瀏覽 21分鐘

         ·

        2022-03-15 15:48

        ?Datawhale干貨?
        作者:吳忠強,東北大學,Datawhale成員

        門人工智能或者數(shù)據(jù),要重視可以快速上手的學習技能:掌握一些基本概念,建立一個知識框架,然后就去實戰(zhàn),在實戰(zhàn)中學習新知識,來填充這個框架。

        我根據(jù)之前整理的一些pandas知識,總結(jié)了一個pandas的快速入門的知識框架。有了這些知識,然后去通過項目實戰(zhàn),然后再補充。希望能幫助大家快速上手。

        Pandas入門知識框架

        1. 什么是Pandas?熊貓?

        Pandas 可以說是基于 NumPy 構(gòu)建的含有更高級數(shù)據(jù)結(jié)構(gòu)和分析能力的工具包, 實現(xiàn)了類似Excel表的功能,可以對二維數(shù)據(jù)表進行很方便的操作。

        在數(shù)據(jù)分析工作中,Pandas 的使用頻率是很高的,一方面是因為 Pandas 提供的基礎數(shù)據(jù)結(jié)構(gòu) DataFrame 與 json 的契合度很高,轉(zhuǎn)換起來就很方便。另一方面,如果我們?nèi)粘5臄?shù)據(jù)清理工作不是很復雜的話,你通常用幾句 Pandas 代碼就可以對數(shù)據(jù)進行規(guī)整。

        Pandas的核心數(shù)據(jù)結(jié)構(gòu):Series 和 DataFrame 這兩個核心數(shù)據(jù)結(jié)構(gòu)。他們分別代表著一維的序列和二維的表結(jié)構(gòu)?;谶@兩種數(shù)據(jù)結(jié)構(gòu),Pandas 可以對數(shù)據(jù)進行導入、清洗、處理、統(tǒng)計和輸出。

        快速掌握Pandas,就要快速學會這兩種核心數(shù)據(jù)結(jié)構(gòu)。

        2. 兩種核心數(shù)據(jù)結(jié)構(gòu)

        2.1 Series

        Series 是個定長的字典序列。說是定長是因為在存儲的時候,相當于兩個 ndarray,這也是和字典結(jié)構(gòu)最大的不同。因為在字典的結(jié)構(gòu)里,元素的個數(shù)是不固定的。

        Series 有兩個基本屬性:index 和 values。在 Series 結(jié)構(gòu)中,index 默認是 0,1,2,……遞增的整數(shù)序列,當然我們也可以自己來指定索引,比如 index=[‘a(chǎn)’, ‘b’, ‘c’, ‘d’]。

        import?pandas?as?pd
        from?pandas?import?Series,?DataFrame
        x1?=?Series([1,2,3,4])
        x2?=?Series(data=[1,2,3,4],?index=['a',?'b',?'c',?'d'])
        print?x1
        print?x2

        上面這個例子中,x1 中的 index 采用的是默認值,x2 中 index 進行了指定。我們也可以采用字典的方式來創(chuàng)建 Series,比如:

        d?=?{'a':1,?'b':2,?'c':3,?'d':4}
        x3?=?Series(d)
        print?x3?

        Series的增刪改查

        1. 創(chuàng)建一個Series

          In?[85]:?ps?=?pd.Series(data=[-3,2,1],index=['a','f','b'],dtype=np.float32)?????

          In?[86]:?ps?????????????????????????????????????????????????????????????????????
          Out[86]:?
          a???-3.0
          f????2.0
          b????1.0
          dtype:?float32
        2. 增加元素append

          In?[112]:?ps.append(pd.Series(data=[-8.0],index=['f']))?????????????????????????
          Out[112]:?
          a????4.0
          f????2.0
          b????1.0
          f???-8.0
          dtype:?float64
        3. 刪除元素drop

          In?[119]:?ps????????????????????????????????????????????????????????????????????
          Out[119]:?
          a????4.0
          f????2.0
          b????1.0
          dtype:?float32

          In?[120]:?psd?=?ps.drop('f')????????????????????????????????????????????????????
          In?[121]:?psd??????????????????????????????????????????????????????????????????
          Out[121]:?
          a????4.0
          b????1.0
          dtype:?float32

          注意不管是 append 操作,還是 drop 操作,都是發(fā)生在原數(shù)據(jù)的副本上,不是原數(shù)據(jù)上。

        4. 修改元素
          通過標簽修改對應數(shù)據(jù),如下所示:

          In?[123]:?psn???????????????????????????????????????????????????????????????????
          Out[123]:?
          a????4.0
          f????2.0
          b????1.0
          f???-8.0
          dtype:?float64

          In?[124]:?psn['f']?=?10.0???????????????????????????????????????????????????????
          In?[125]:?psn???????????????????????????????????????????????????????????????????
          Out[125]:?
          a?????4.0
          f????10.0
          b?????1.0
          f????10.0
          dtype:?float64

          Series里面允許標簽相同, 且如果相同, 標簽都會被修改。

        5. 訪問元素
          一種通過默認的整數(shù)索引,在 Series 對象未被顯示的指定 label 時,都是通過索引訪問;另一種方式是通過標簽訪問。

          In?[126]:?ps????????????????????????????????????????????????????????????????????
          Out[126]:?
          a????4.0
          f????2.0
          b????1.0
          dtype:?float32

          In?[128]:?ps[2]?#?索引訪問??????????????????????????????
          Out[128]:?1.0

          In?[127]:?ps['b']??#?標簽訪問?????????????????????????????????????????????????????????????
          Out[127]:?1.0

        2.2 DataFrame

        DataFrame 類型數(shù)據(jù)結(jié)構(gòu)類似數(shù)據(jù)庫表。它包括了行索引和列索引,我們可以將 DataFrame 看成是由相同索引的 Series 組成的字典類型。

        import?pandas?as?pd
        from?pandas?import?Series,?DataFrame
        data?=?{'Chinese':?[66,?95,?93,?90,80],'English':?[65,?85,?92,?88,?90],'Math':?[30,?98,?96,?77,?90]}
        df1=?DataFrame(data)
        df2?=?DataFrame(data,?index=['ZhangFei',?'GuanYu',?'ZhaoYun',?'HuangZhong',?'DianWei'],?columns=['English',?'Math',?'Chinese'])
        print?df1
        print?df2

        在后面的案例中,我一般會用 df, df1, df2 這些作為 DataFrame 數(shù)據(jù)類型的變量名,我們以例子中的 df2 為例,列索引是[‘English’, ‘Math’, ‘Chinese’],行索引是[‘ZhangFei’, ‘GuanYu’, ‘ZhaoYun’, ‘HuangZhong’, ‘DianWei’],所以 df2 的輸出是:


        ????????????English??Math??Chinese
        ZhangFei?????????65????30???????66
        GuanYu???????????85????98???????95
        ZhaoYun??????????92????96???????93
        HuangZhong???????88????77???????90
        DianWei??????????90????90???????80

        2.2.1基本操作

        (1)數(shù)據(jù)的導入與輸出

        Pandas 允許直接從 xlsx,csv 等文件中導入數(shù)據(jù),也可以輸出到 xlsx, csv 等文件,非常方便。
        需要說明的是,在運行的過程可能會存在缺少 xlrd 和 openpyxl 包的情況,到時候如果缺少了,可以在命令行模式下使用“pip install”命令來進行安裝。

        import?pandas?as?pd
        from?pandas?import?Series,?DataFrame
        score?=?DataFrame(pd.read_excel('data.xlsx'))
        score.to_excel('data1.xlsx')
        print?score

        關于數(shù)據(jù)導入, pandas提供了強勁的讀取支持, 比如讀寫CSV文件, read_csv()函數(shù)有38個參數(shù)之多, 這里面有一些很有用, 主要可以分為下面幾個維度來梳理:

        • 基本參數(shù)

          • filepathorbuffer: 數(shù)據(jù)的輸入路徑, 可以是文件路徑, 也可是是URL或者實現(xiàn)read方法的任意對象
          • sep: 數(shù)據(jù)文件的分隔符, 默認為逗號
          • delim_whitespace: 表示分隔符為空白字符, 可以是一個空格, 兩個空格
          • header: 設置導入DataFrame的列名稱, 如果names沒賦值, header會選取數(shù)據(jù)文件的第一行作為列名
          • index_col: 表示哪個或者哪些列作為index
          • usecols: 選取數(shù)據(jù)文件的哪些列到DataFrame中
          • prefix: 當導入的數(shù)據(jù)沒有header時, 設置此參數(shù)會自動加一個前綴
        • 通用解析參數(shù)

          • dtype:讀取數(shù)據(jù)時修改列的類型
          • converters: 實現(xiàn)對列數(shù)據(jù)的變化操作
          • skip_rows: 過濾行
          • nrows: 設置一次性讀入的文件行數(shù),它在讀入大文件時很有用,比如 16G 內(nèi)存的PC無法容納幾百 G 的大文件。
          • skip_blank_lines: 過濾掉空行
        • 時間處理相關參數(shù)

          • parse_dates: 如果導入的某些列為時間類型,但是導入時沒有為此參數(shù)賦值,導入后就不是時間類型
          • date_parser: 定制某種時間類型
        • 分開讀入相關參數(shù):
          分塊讀入內(nèi)存,尤其單機處理大文件時會很有用。

          • iterator: iterator 取值 boolean,default False,返回一個 TextFileReader 對象,以便逐塊處理文件。
          • chunksize: 整型,默認為 None,設置文件塊的大小。
        • 格式和壓縮相關參數(shù)

          id name ?age 0 ? 1 ? gz ? 10 1 ? 2 ? lh ? 12


          -?`thousands`: str,default None,千分位分割符,如?`,`?或者?`.`。

          -?`encoding`:?指定字符集類型,通常指定為?‘utf-8’

          • compression
            compression 參數(shù)取值為 {‘infer’, ‘gzip’, ‘bz2’, ‘zip’, ‘xz’, None},默認 ‘infer’,直接使用磁盤上的壓縮文件。如果使用 infer 參數(shù),則使用 gzip、bz2、zip 或者解壓文件名中以 ‘.gz’、‘.bz2’、‘.zip’ 或 ‘xz’ 這些為后綴的文件,否則不解壓。如果使用 zip,那么 ZIP 包中必須只包含一個文件。設置為 None 則不解壓。手動壓縮本文一直使用的 test.csv 為 test.zip 文件,然后打開

            In?[73]:??df?=?pd.read_csv('test.zip',sep='\s+',compression='zip')

            In?[74]:?df
            Out[74]:

        具體這些參數(shù)怎么用, 可以看https://gitbook.cn/gitchat/column/5e37978dec8d9033cf916b5d/topic/5e3bcef3ec8d9033cf92466f

        (2)數(shù)據(jù)清洗

        數(shù)據(jù)清洗是數(shù)據(jù)準備過程中必不可少的環(huán)節(jié),Pandas 也為我們提供了數(shù)據(jù)清洗的工具,在后面數(shù)據(jù)清洗的章節(jié)中會給你做詳細的介紹,這里簡單介紹下 Pandas 在數(shù)據(jù)清洗中的使用方法。

        (2.1)刪除 DataFrame 中的不必要的列或行

        Pandas 提供了一個便捷的方法 drop() 函數(shù)來刪除我們不想要的列或行

        df2?=?df2.drop(columns=['Chinese'])

        想把“張飛”這行刪掉。

        df2?=?df2.drop(index=['ZhangFei'])

        (2.2)重命名列名 columns,讓列表名更容易識別

        如果你想對 DataFrame 中的 columns 進行重命名,可以直接使用 rename(columns=new_names, inplace=True) 函數(shù),比如我把列名 Chinese 改成 YuWen,English 改成 YingYu。

        df2.rename(columns={'Chinese':?'YuWen',?'English':?'Yingyu'},?inplace?=?True)

        (2.3)去重復的值

        數(shù)據(jù)采集可能存在重復的行,這時只要使用 drop_duplicates() 就會自動把重復的行去掉

        df?=?df.drop_duplicates()?#去除重復行

        (2.4)格式問題

        • 更改數(shù)據(jù)格式
          這是個比較常用的操作,因為很多時候數(shù)據(jù)格式不規(guī)范,我們可以使用 astype 函數(shù)來規(guī)范數(shù)據(jù)格式,比如我們把 Chinese 字段的值改成 str 類型,或者 int64 可以這么寫
        df2['Chinese'].astype('str')?
        df2['Chinese'].astype(np.int64)?
        • 數(shù)據(jù)間的空格
          有時候我們先把格式轉(zhuǎn)成了 str 類型,是為了方便對數(shù)據(jù)進行操作,這時想要刪除數(shù)據(jù)間的空格,我們就可以使用 strip 函數(shù):
        #刪除左右兩邊空格
        df2['Chinese']=df2['Chinese'].map(str.strip)
        #刪除左邊空格
        df2['Chinese']=df2['Chinese'].map(str.lstrip)
        #刪除右邊空格
        df2['Chinese']=df2['Chinese'].map(str.rstrip)

        如果數(shù)據(jù)里有某個特殊的符號,我們想要刪除怎么辦?同樣可以使用 strip 函數(shù),比如 Chinese 字段里有美元符號,我們想把這個刪掉,可以這么寫:

        df2['Chinese']=df2['Chinese'].str.strip('$')

        (2.5)大小寫轉(zhuǎn)換

        大小寫是個比較常見的操作,比如人名、城市名等的統(tǒng)一都可能用到大小寫的轉(zhuǎn)換,在 Python 里直接使用 upper(), lower(), title() 函數(shù),方法如下:

        #全部大寫
        df2.columns?=?df2.columns.str.upper()
        #全部小寫
        df2.columns?=?df2.columns.str.lower()
        #首字母大寫
        df2.columns?=?df2.columns.str.title()

        (2.6)查找空值

        數(shù)據(jù)量大的情況下,有些字段存在空值 NaN 的可能,這時就需要使用 Pandas 中的 isnull 函數(shù)進行查找。比如,我們輸入一個數(shù)據(jù)表如下:

        如果我們想看下哪個地方存在空值 NaN,可以針對數(shù)據(jù)表 df 進行 df.isnull(),結(jié)果如下:

        如果我想知道哪列存在空值,可以使用 df.isnull().any(),結(jié)果如下:

        2.2.2 使用apply函數(shù)對數(shù)據(jù)進行清洗

        apply 函數(shù)是 Pandas 中自由度非常高的函數(shù),使用頻率也非常高。比如我們想對 name 列的數(shù)值都進行大寫轉(zhuǎn)化可以用:

        df['name']?=?df['name'].apply(str.upper)

        我們也可以定義個函數(shù),在 apply 中進行使用。比如定義 double_df 函數(shù)是將原來的數(shù)值 *2 進行返回。然后對 df1 中的“語文”列的數(shù)值進行 *2 處理,可以寫成:

        def?double_df(x):
        ???????????return?2*x
        df1[u'語文']?=?df1[u'語文'].apply(double_df)

        我們也可以定義更復雜的函數(shù),比如對于 DataFrame,我們新增兩列,其中’new1’列是“語文”和“英語”成績之和的 m 倍,'new2’列是“語文”和“英語”成績之和的 n 倍,我們可以這樣寫:

        def?plus(df,n,m):
        ????df['new1']?=?(df[u'語文']+df[u'英語'])?*?m
        ????df['new2']?=?(df[u'語文']+df[u'英語'])?*?n
        ????return?df
        df1?=?df1.apply(plus,axis=1,args=(2,3,))

        2.3 數(shù)據(jù)統(tǒng)計

        在數(shù)據(jù)清洗后,我們就要對數(shù)據(jù)進行統(tǒng)計了。Pandas 和 NumPy 一樣,都有常用的統(tǒng)計函數(shù),如果遇到空值 NaN,會自動排除。常用的統(tǒng)計函數(shù)包括:

        表格中有一個 describe() 函數(shù),統(tǒng)計函數(shù)千千萬,describe() 函數(shù)最簡便。它是個統(tǒng)計大禮包,可以快速讓我們對數(shù)據(jù)有個全面的了解。下面我直接使用 df1.descirbe() 輸出結(jié)果為:

        df1?=?DataFrame({'name':['ZhangFei',?'GuanYu',?'a',?'b',?'c'],?'data1':range(5)})
        print?df1.describe()

        2.4 數(shù)據(jù)表合并

        有時候我們需要將多個渠道源的多個數(shù)據(jù)表進行合并,一個 DataFrame 相當于一個數(shù)據(jù)庫的數(shù)據(jù)表,那么多個 DataFrame 數(shù)據(jù)表的合并就相當于多個數(shù)據(jù)庫的表合并。
        比如我要創(chuàng)建兩個 DataFrame:

        df1?=?DataFrame({'name':['ZhangFei',?'GuanYu',?'a',?'b',?'c'],?'data1':range(5)})
        df2?=?DataFrame({'name':['ZhangFei',?'GuanYu',?'A',?'B',?'C'],?'data2':range(5)})

        兩個 DataFrame 數(shù)據(jù)表的合并使用的是 merge() 函數(shù),有下面 5 種形式:

        1. 基于指定列進行連接
          比如我們可以基于 name 這列進行連接。
        df3?=?pd.merge(df1,?df2,?on='name')


        2. inner內(nèi)連接
        inner 內(nèi)鏈接是 merge 合并的默認情況,inner 內(nèi)連接其實也就是鍵的交集,在這里 df1, df2 相同的鍵是 name,所以是基于 name 字段做的連接:

        df3?=?pd.merge(df1,?df2,?how='inner')


        3. left左連接
        左連接是以第一個 DataFrame 為主進行的連接,第二個 DataFrame 作為補充。

        df3?=?pd.merge(df1,?df2,?how='left')
        1. right右連接
          右連接是以第二個 DataFrame 為主進行的連接,第一個 DataFrame 作為補充。
        df3?=?pd.merge(df1,?df2,?how='right')


        5. outer外連接
        外連接相當于求兩個 DataFrame 的并集。

        df3?=?pd.merge(df1,?df2,?how='outer')

        2.5 DataFram的行級遍歷

        盡管 Pandas 已經(jīng)盡可能向量化,讓使用者盡可能避免 for 循環(huán),但是有時不得已,還得要遍歷 DataFrame。Pandas 提供 iterrows、itertuples 兩種行級遍歷。

        1. 使用 iterrows 遍歷打印所有行,在 IPython 里輸入以下行:

          def?iterrows_time(df):
          for?i,row?in?df.iterrows():
          ????print(row)

          訪問每一行某個元素的時候, 可以通過列名直接訪問:

        2. 使用 itertuples 遍歷打印每行:

          def?itertuples_time(df):
          for?nt?in?df.itertuples():
          ????print(nt)

          這個效率更高, 比上面那個節(jié)省6倍多的時間, 所在數(shù)據(jù)量非常大的時候, 推薦后者。訪問每一行某個元素的時候, 需要getattr函數(shù)

        3. 使用iteritems遍歷每一行

          這個訪問每一行元素的時候, 用的是每一列的數(shù)字索引

        3. 如何用SQL方式打開Pandas

        Pandas 的 DataFrame 數(shù)據(jù)類型可以讓我們像處理數(shù)據(jù)表一樣進行操作,比如數(shù)據(jù)表的增刪改查,都可以用 Pandas 工具來完成。不過也會有很多人記不住這些 Pandas 的命令,相比之下還是用 SQL 語句更熟練,用 SQL 對數(shù)據(jù)表進行操作是最方便的,它的語句描述形式更接近我們的自然語言。

        事實上,在 Python 里可以直接使用 SQL 語句來操作 Pandas。

        這里給你介紹個工具:pandasql。

        pandasql 中的主要函數(shù)是 sqldf,它接收兩個參數(shù):一個 SQL 查詢語句,還有一組環(huán)境變量 globals() 或 locals()。這樣我們就可以在 Python 里,直接用 SQL 語句中對 DataFrame 進行操作,舉個例子:

        import?pandas?as?pd
        from?pandas?import?DataFrame
        from?pandasql?import?sqldf,?load_meat,?load_births
        df1?=?DataFrame({'name':['ZhangFei',?'GuanYu',?'a',?'b',?'c'],?'data1':range(5)})
        pysqldf?=?lambda?sql:?sqldf(sql,?globals())
        sql?=?"select?*?from?df1?where?name?='ZhangFei'"
        print?pysqldf(sql)

        運行結(jié)果

        ???data1??????name
        0??????0??ZhangFei

        上面代碼中,定義了:

        pysqldf?=?lambda?sql:?sqldf(sql,?globals())

        在這個例子里,輸入的參數(shù)是 sql,返回的結(jié)果是 sqldf 對 sql 的運行結(jié)果,當然 sqldf 中也輸入了 globals 全局參數(shù),因為在 sql 中有對全局參數(shù) df1 的使用。

        參考

        • 極客時間《數(shù)據(jù)分析實戰(zhàn)45講》課程:https://time.geekbang.org/
        • Pandas的基本使用:http://note.youdao.com/noteshare?id=28264a6b8536e4448e0bf3de701cd230&sub=25080C078C444E6E8B0C809C88BD0C76
        • python數(shù)據(jù)分析實用小抄:https://www.cnblogs.com/nxld/p/6687253.html
        • 像Excel一樣使用python進行數(shù)據(jù)分析:https://www.cnblogs.com/nxld/p/6756492.html
        • 50道練習帶你玩轉(zhuǎn)Pandas:https://mp.weixin.qq.com/s/39yPBJ7DWSMs_aIxtlpXCw
        • AI基礎:Pandas簡易入門:https://mp.weixin.qq.com/s/uLBJc_iIize8a9B491U7VQ
        • Pandas常用用法:https://www.freesion.com/article/7330378876/

        往期精彩回顧




        瀏覽 58
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            大黑逼网| 国产精品一卡二卡三卡 | 极品美女操逼视频 | 欧洲无人区卡一卡二卡三 | 亚洲中文字幕在线午夜成人网 | 去趴好屁股翘起来h | 男女午夜久久久激情视频 | 亚洲欧美日韩另类 | 亚洲制服在线观看 | 我把护士日出水了视频90分钟 |