<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          系統(tǒng)性的學(xué)會(huì) Pandas, 看這一篇就夠了!

          共 29737字,需瀏覽 60分鐘

           ·

          2021-09-05 08:11


          作者:Ma Sizhou

          https://blog.csdn.net/weixin_45901519/article/details/112980822

          1、Pandas數(shù)據(jù)結(jié)構(gòu)c18f3f28ea610503ace4a59a2025c6b8.webp
          • 2008年WesMcKinney開(kāi)發(fā)出的庫(kù)
          • 專門用于數(shù)據(jù)挖掘的開(kāi)源python庫(kù)
          • 以Numpy為基礎(chǔ),借力Numpy模塊在計(jì)算方面性能高的優(yōu)勢(shì)
          • 基于matplotlib,能夠簡(jiǎn)便的畫圖
          • 獨(dú)特的數(shù)據(jù)結(jié)構(gòu)

          1.1 為什么使用Pandas

          Numpy已經(jīng)能夠幫助我們處理數(shù)據(jù),能夠結(jié)合matplotlib解決部分?jǐn)?shù)據(jù)展示等問(wèn)題,那么pandas學(xué)習(xí)的目的在什么地方呢?

          • (1)增強(qiáng)圖表可讀性

            • 在numpy當(dāng)中創(chuàng)建學(xué)生成績(jī)表樣式:

            • 返回結(jié)果:

          array([[92,?55,?78,?50,?50],
          ???????[71,?76,?50,?48,?96],
          ???????[45,?84,?78,?51,?68],
          ???????[81,?91,?56,?54,?76],
          ???????[86,?66,?77,?67,?95],
          ???????[46,?86,?56,?61,?99],
          ???????[46,?95,?44,?46,?56],
          ???????[80,?50,?45,?65,?57],
          ???????[41,?93,?90,?41,?97],
          ???????[65,?83,?57,?57,?40]])

          如果數(shù)據(jù)展示為這樣,可讀性就會(huì)更友好:
          f9c3b01d7def7eb4755a641c9923e935.webp

          • (2)便捷的數(shù)據(jù)處理能力
            a8ef96222e1f5fb520e69b85b8731178.webp
          • (3)讀取文件方便
          • (4)封裝了Matplotlib、Numpy的畫圖和計(jì)算

          1.2 Pandas數(shù)據(jù)結(jié)構(gòu)

          Pandas中一共有三種數(shù)據(jù)結(jié)構(gòu),分別為:Series、DataFrame和MultiIndex(老版本中叫Panel )。

          其中Series是一維數(shù)據(jù)結(jié)構(gòu),DataFrame是二維的表格型數(shù)據(jù)結(jié)構(gòu),MultiIndex是三維的數(shù)據(jù)結(jié)構(gòu)。

          1.2.1 Series

          Series是一個(gè)類似于一維數(shù)組的數(shù)據(jù)結(jié)構(gòu),它能夠保存任何類型的數(shù)據(jù),比如整數(shù)、字符串、浮點(diǎn)數(shù)等,主要由一組數(shù)據(jù)和與之相關(guān)的索引兩部分構(gòu)成。
          35db6b5da56181838ae15c57a93e28c8.webp

          (1)Series的創(chuàng)建

          #?導(dǎo)入pandas
          import?pandas?as?pd

          pd.Series(data=None,?index=None,?dtype=None)
          • 參數(shù):
            • data:傳入的數(shù)據(jù),可以是ndarray、list等
            • index:索引,必須是唯一的,且與數(shù)據(jù)的長(zhǎng)度相等。如果沒(méi)有傳入索引參數(shù),則默認(rèn)會(huì)自動(dòng)創(chuàng)建一個(gè)從0-N的整數(shù)索引。
            • dtype:數(shù)據(jù)的類型

          通過(guò)已有數(shù)據(jù)創(chuàng)建:

          • (1)指定內(nèi)容,默認(rèn)索引:
          pd.Series(np.arange(10))
          #?運(yùn)行結(jié)果
          0????0
          1????1
          2????2
          3????3
          4????4
          5????5
          6????6
          7????7
          8????8
          9????9
          dtype:?int64
          • (2)指定索引:
          pd.Series([6.7,5.6,3,10,2],?index=[1,2,3,4,5])
          #?運(yùn)行結(jié)果
          1?????6.7
          2?????5.6
          3?????3.0
          4????10.0
          5?????2.0
          dtype:?float64
          • (3)通過(guò)字典數(shù)據(jù)創(chuàng)建
          color_count?=?pd.Series({'red':100,?'blue':200,?'green':?500,?'yellow':1000})
          color_count
          #?運(yùn)行結(jié)果
          blue???????200
          green??????500
          red????????100
          yellow????1000
          dtype:?int64

          (2)Series的屬性

          為了更方便地操作Series對(duì)象中的索引和數(shù)據(jù),Series中提供了兩個(gè)屬性index和values:

          • index:
          color_count?=?pd.Series({'red':100,?'blue':200,?'green':?500,?'yellow':1000})

          color_count.index

          #?結(jié)果
          Index(['blue',?'green',?'red',?'yellow'],?dtype='object')
          • values:
          color_count.values

          #?結(jié)果
          array([?200,??500,??100,?1000])

          也可以使用索引來(lái)獲取數(shù)據(jù):

          color_count[2]

          #?結(jié)果
          100

          1.2.2 DataFrame

          DataFrame是一個(gè)類似于二維數(shù)組或表格(如excel)的對(duì)象,既有行索引,又有列索引:

          • 行索引,表明不同行,橫向索引,叫index,0軸,axis=0
          • 列索引,表名不同列,縱向索引,叫columns,1軸,axis=1
            80f42f8b06270a9d4df3c79ce7df8e88.webp

          (1)DataFrame的創(chuàng)建

          #?導(dǎo)入pandas
          import?pandas?as?pd

          pd.DataFrame(data=None,?index=None,?columns=None)
          • 參數(shù):

            • index:行標(biāo)簽。如果沒(méi)有傳入索引參數(shù),則默認(rèn)會(huì)自動(dòng)創(chuàng)建一個(gè)從0-N的整數(shù)索引。
            • columns:列標(biāo)簽。如果沒(méi)有傳入索引參數(shù),則默認(rèn)會(huì)自動(dòng)創(chuàng)建一個(gè)從0-N的整數(shù)索引。
          • 通過(guò)已有數(shù)據(jù)創(chuàng)建

          舉例一:

          pd.DataFrame(np.random.randn(2,3))

          結(jié)果:
          50d909b933cbe7ead81deab443c9f89a.webp
          舉例二:創(chuàng)建學(xué)生成績(jī)表

          使用np創(chuàng)建的數(shù)組顯示方式,比較兩者的區(qū)別。

          #?生成10名同學(xué),5門功課的數(shù)據(jù)
          score?=?np.random.randint(40,?100,?(10,?5))#均勻分布

          #?結(jié)果
          array([[92,?55,?78,?50,?50],
          ???????[71,?76,?50,?48,?96],
          ???????[45,?84,?78,?51,?68],
          ???????[81,?91,?56,?54,?76],
          ???????[86,?66,?77,?67,?95],
          ???????[46,?86,?56,?61,?99],
          ???????[46,?95,?44,?46,?56],
          ???????[80,?50,?45,?65,?57],
          ???????[41,?93,?90,?41,?97],
          ???????[65,?83,?57,?57,?40]])

          但是這樣的數(shù)據(jù)形式很難看到存儲(chǔ)的是什么的樣的數(shù)據(jù),可讀性比較差!!

          問(wèn)題:如何讓數(shù)據(jù)更有意義的顯示?

          #?使用Pandas中的數(shù)據(jù)結(jié)構(gòu)
          score_df?=?pd.DataFrame(score)

          結(jié)果:
          d017025fdc53227ebec462ec939692ba.webp
          給分?jǐn)?shù)數(shù)據(jù)增加行列索引,顯示效果更佳:

          • 增加行、列索引:
          #?構(gòu)造行索引序列
          subjects?=?["語(yǔ)文",?"數(shù)學(xué)",?"英語(yǔ)",?"政治",?"體育"]

          #?構(gòu)造列索引序列
          stu?=?['同學(xué)'?+?str(i)?for?i?in?range(score_df.shape[0])]

          #?添加行索引
          data?=?pd.DataFrame(score,?columns=subjects,?index=stu)

          結(jié)果:

          7671244c884808ade3c3332540ad07a5.webp

          (2)DataFrame的屬性

          • (1)shape
          data.shape

          #?結(jié)果
          (10,?5)
          • (2)index

          DataFrame的行索引列表

          data.index

          #?結(jié)果
          Index(['同學(xué)0',?'同學(xué)1',?'同學(xué)2',?'同學(xué)3',?'同學(xué)4',?'同學(xué)5',?'同學(xué)6',?'同學(xué)7',?'同學(xué)8',?'同學(xué)9'],?dtype='object')
          • (3)columns

          DataFrame的列索引列表

          data.columns

          #?結(jié)果
          Index(['語(yǔ)文',?'數(shù)學(xué)',?'英語(yǔ)',?'政治',?'體育'],?dtype='object')
          • (4)values

          直接獲取其中array的值

          array([[54,?82,?62,?81,?47],
          ???????[50,?58,?73,?72,?48],
          ???????[88,?89,?49,?99,?83],
          ???????[79,?81,?69,?45,?87],
          ???????[87,?64,?62,?74,?85],
          ???????[68,?56,?58,?77,?53],
          ???????[77,?49,?82,?48,?82],
          ???????[96,?49,?67,?94,?71],
          ???????[98,?77,?44,?99,?41],
          ???????[71,?52,?74,?90,?44]])
          • (5)T

          轉(zhuǎn)置

          data.T

          結(jié)果:
          85c80b73234ddbfc3795e6b8f2d2b999.webp

          • (6)head(5):顯示前5行內(nèi)容

          如果不補(bǔ)充參數(shù),默認(rèn)5行。填入?yún)?shù)N則顯示前N行

          data.head(5)

          結(jié)果:
          5e5151c9a16de2e6c54fedf215bea3a8.webp

          • (7)tail(5):顯示后5行內(nèi)容

          如果不補(bǔ)充參數(shù),默認(rèn)5行。填入?yún)?shù)N則顯示后N行

          data.tail(5)

          結(jié)果:

          cd07dd2938725ca2550d59aba9d18999.webp

          (3)DatatFrame索引的設(shè)置

          現(xiàn)在要將下圖的行索引改變,變成下下圖所示樣子,怎么做呢?
          7671244c884808ade3c3332540ad07a5.webp

          a30ccecdfb8fed3e217c00af3c0c17bd.webp
          • (1)修改行列索引值
          stu?=?["學(xué)同學(xué)_"?+?str(i)?for?i?in?range(score_df.shape[0])]

          #?必須整體全部修改
          data.index?=?stu

          注意:以下修改方式是錯(cuò)誤的,說(shuō)明不能單獨(dú)修改

          #?錯(cuò)誤修改方式,不能單個(gè)修改
          data.index[3]?=?'學(xué)生_3'
          • (2)重設(shè)索引

            • 設(shè)置新的下標(biāo)索引
            • drop:默認(rèn)為False,不刪除原來(lái)索引,如果為True,刪除原來(lái)的索引值
            • reset_index(drop=False)
          #?重置索引,drop=False
          data.reset_index()

          結(jié)果:
          ca627f6af44d04268463d0863a9276e3.webp

          #?重置索引,drop=True
          data.reset_index()

          結(jié)果:
          478e80310633a2bc3cda0ea103f960d6.webp

          • (3)以某列值設(shè)置為新的索引
          • set_index(keys, drop=True)
            • keys : 列索引名成或者列索引名稱的列表
            • drop : boolean, default True.當(dāng)做新的索引,刪除原來(lái)的列

          設(shè)置新索引案例:

          1、創(chuàng)建

          df?=?pd.DataFrame({'month':?[1,?4,?7,?10],
          ????????????????????'year':?[2012,?2014,?2013,?2014],
          ????????????????????'sale':[55,?40,?84,?31]})

          ???month??sale??year
          0??1??????55????2012
          1??4??????40????2014
          2??7??????84????2013
          3??10?????31????2014

          2、以月份設(shè)置新的索引

          df.set_index('month')
          ???????sale??year
          month
          1??????55????2012
          4??????40????2014
          7??????84????2013
          10?????31????2014

          3、設(shè)置多個(gè)索引,以年和月份

          df?=?df.set_index(['year',?'month'])
          df
          ????????????sale
          year??month
          2012??1?????55
          2014??4?????40
          2013??7?????84
          2014??10????31

          注:通過(guò)剛才的設(shè)置,這樣DataFrame就變成了一個(gè)具有MultiIndex的DataFrame。

          1.2.3 MultiIndex與Panel

          (1)MultiIndex

          MultiIndex是三維的數(shù)據(jù)結(jié)構(gòu);

          多級(jí)索引(也稱層次化索引)是pandas的重要功能,可以在Series、DataFrame對(duì)象上擁有2個(gè)以及2個(gè)以上的索引。

          • (1)multiIndex的特性

          打印剛才的df的行索引結(jié)果

          df
          ????????????sale
          year??month
          2012??1?????55
          2014??4?????40
          2013??7?????84
          2014??10????31

          df.index

          MultiIndex(levels=[[2012,?2013,?2014],?[1,?4,?7,?10]],
          ???????????labels=[[0,?2,?1,?2],?[0,?1,?2,?3]],
          ???????????names=['year',?'month'])

          多級(jí)或分層索引對(duì)象。

          • index屬性
            • names:levels的名稱
            • levels:每個(gè)level的元組值
          df.index.names
          #?FrozenList(['year',?'month'])

          df.index.levels
          #?FrozenList([[2012,?2013,?2014],?[1,?4,?7,?10]])
          • (2)multiIndex的創(chuàng)建
          arrays?=?[[1,?1,?2,?2],?['red',?'blue',?'red',?'blue']]
          pd.MultiIndex.from_arrays(arrays,?names=('number',?'color'))

          #?結(jié)果
          MultiIndex(levels=[[1,?2],?['blue',?'red']],
          ???????????codes=[[0,?0,?1,?1],?[1,?0,?1,?0]],
          ???????????names=['number',?'color'])

          (2)Panel

          • (1)panel的創(chuàng)建
            • 作用:存儲(chǔ)3維數(shù)組的Panel結(jié)構(gòu)

            • 參數(shù):

            • data : ndarray或者dataframe

            • items : 索引或類似數(shù)組的對(duì)象,axis=0

            • major_axis : 索引或類似數(shù)組的對(duì)象,axis=1

            • minor_axis : 索引或類似數(shù)組的對(duì)象,axis=2

            • class pandas.Panel(data=None, items=None, major_axis=None, minor_axis=None)

          p?=?pd.Panel(data=np.arange(24).reshape(4,3,2),
          ?????????????????items=list('ABCD'),
          ?????????????????major_axis=pd.date_range('20130101',?periods=3),
          ?????????????????minor_axis=['first',?'second'])

          #?結(jié)果
          <class?'pandas.core.panel.Panel'>
          Dimensions:
          ?4?(items)?x?3?(major_axis)?x?2?(minor_axis)
          Items?axis:?A?to?D
          Major_axis?axis:?2013-01-01?00:00:00?to?2013-01-03?00:00:00
          Minor_axis?axis:?first?to?second
          • (2)查看panel數(shù)據(jù)
          p[:,:,"first"]
          p["B",:,:]

          注:Pandas從版本0.20.0開(kāi)始棄用:推薦的用于表示3D數(shù)據(jù)的方法是通過(guò)DataFrame上的MultiIndex方法。

          2、基本數(shù)據(jù)操作

          為了更好的理解這些基本操作,我們將讀取一個(gè)真實(shí)的股票數(shù)據(jù)。關(guān)于文件操作,后面在介紹,這里只先用一下API。

          #?讀取文件
          data?=?pd.read_csv("./data/stock_day.csv")

          #?刪除一些列,讓數(shù)據(jù)更簡(jiǎn)單些,再去做后面的操作
          data?=?data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"],?axis=1)
          b7805e63ce196d802a7020aca4fd7691.webp

          2.1 索引操作

          Numpy當(dāng)中我們已經(jīng)講過(guò)使用索引選取序列和切片選擇,pandas也支持類似的操作,也可以直接使用列名、行名稱,甚至組合使用。

          2.2.1 直接使用行列索引(先列后行)

          獲取’2018-02-27’這天的’open’的結(jié)果:

          #?直接使用行列索引名字的方式(先列后行)
          data['open']['2018-02-27']
          23.53

          #?不支持的操作
          #?錯(cuò)誤
          data['2018-02-27']['open']
          #?錯(cuò)誤
          data[:1,?:2]

          2.2.2 結(jié)合loc或者iloc使用索引

          獲取從’2018-02-27’到’2018-02-22’,'open’的結(jié)果:

          #?使用loc:只能指定行列索引的名字
          data.loc['2018-02-27':'2018-02-22',?'open']

          2018-02-27????23.53
          2018-02-26????22.80
          2018-02-23????22.88
          Name:?open,?dtype:?float64

          #?使用iloc可以通過(guò)索引的下標(biāo)去獲取
          #?獲取前3天數(shù)據(jù),前5列的結(jié)果
          data.iloc[:3,?:5]

          ????????????open????high????close????low
          2018-02-27????23.53????25.88????24.16????23.53
          2018-02-26????22.80????23.78????23.53????22.80
          2018-02-23????22.88????23.37????22.82????22.71

          2.2.3 使用ix組合索引(混合索引:下標(biāo)和名稱)

          獲取行第1天到第4天,[‘open’, ‘close’, ‘high’, ‘low’]這個(gè)四個(gè)指標(biāo)的結(jié)果:

          #?使用ix進(jìn)行下表和名稱組合做引
          data.ix[0:4,?['open',?'close',?'high',?'low']]

          #?推薦使用loc和iloc來(lái)獲取的方式
          data.loc[data.index[0:4],?['open',?'close',?'high',?'low']]
          data.iloc[0:4,?data.columns.get_indexer(['open',?'close',?'high',?'low'])]

          ????????????open????close????high????low
          2018-02-27????23.53????24.16????25.88????23.53
          2018-02-26????22.80????23.53????23.78????22.80
          2018-02-23????22.88????22.82????23.37????22.71
          2018-02-22????22.25????22.28????22.76????22.02

          2.2 賦值操作

          對(duì)DataFrame當(dāng)中的close列進(jìn)行重新賦值為1。

          #?直接修改原來(lái)的值
          data['close']?=?1?#?這一列都變成1
          #?或者
          data.close?=?1

          2.3 排序

          排序有兩種形式,一種對(duì)于索引進(jìn)行排序,一種對(duì)于內(nèi)容進(jìn)行排序:

          2.3.1 DataFrame排序

          • (1)使用df.sort_values(by=, ascending=)
            • by:指定排序參考的鍵
            • ascending:默認(rèn)升序
            • ascending=False:降序
            • ascending=True:升序
            • 單個(gè)鍵或者多個(gè)鍵進(jìn)行排序,
            • 參數(shù):

          如下:

          例一:

          #?按照開(kāi)盤價(jià)大小進(jìn)行排序?,?使用ascending指定按照大小排序
          data.sort_values(by="open",?ascending=True).head()

          結(jié)果:
          35b37003765a6800d7634781cd0051d3.webp
          例二:

          #?按照多個(gè)鍵進(jìn)行排序
          data.sort_values(by=['open',?'high'])

          結(jié)果:
          e476076ce9085cce0e6835d1827d6f22.webp

          • (2)使用df.sort_index(ascending=)給索引進(jìn)行排序

          這個(gè)股票的日期索引原來(lái)是從大到小,現(xiàn)在重新排序,從小到大:

          #?對(duì)索引進(jìn)行排序
          data.sort_index()

          結(jié)果:
          6f0dddfd9a017e19bc0f35e4932ba4c2.webp

          2.3.2 Series排序

          • (1)使用series.sort_values(ascending=True)進(jìn)行排序

          series排序時(shí),只有一列,不需要參數(shù)

          data['p_change'].sort_values(ascending=True).head()

          2015-09-01???-10.03
          2015-09-14???-10.02
          2016-01-11???-10.02
          2015-07-15???-10.02
          2015-08-26???-10.01
          Name:?p_change,?dtype:?float64
          • (2)使用series.sort_index()進(jìn)行排序

          與df一致

          #?對(duì)索引進(jìn)行排序
          data['p_change'].sort_index().head()

          2015-03-02????2.62
          2015-03-03????1.44
          2015-03-04????1.57
          2015-03-05????2.02
          2015-03-06????8.51
          Name:?p_change,?dtype:?float64

          2.4 總結(jié)

          496ad69cb86187513b293663a31d3b42.webp3、DataFrame運(yùn)算

          3.1 算術(shù)運(yùn)算

          • (1)add(other)

          比如進(jìn)行數(shù)學(xué)運(yùn)算加上具體的一個(gè)數(shù)字

          data['open'].head().add(1)

          2018-02-27????24.53
          2018-02-26????23.80
          2018-02-23????23.88
          2018-02-22????23.25
          2018-02-14????22.49
          Name:?open,?dtype:?float64
          • (2)sub(other)

          整個(gè)列減一個(gè)數(shù)

          data.open.head().sub(2)

          2018-02-27????21.53
          2018-02-26????20.80
          2018-02-23????20.88
          2018-02-22????20.25
          2018-02-14????19.49
          Name:?open,?dtype:?float64

          3.2 邏輯運(yùn)算

          3.2.1 邏輯運(yùn)算符號(hào)

          • 例如篩選data[“open”] > 23的日期數(shù)據(jù)
            • data[“open”] > 23返回邏輯結(jié)果
          data["open"]?>?23

          2018-02-27?????True
          2018-02-26????False
          2018-02-23????False
          2018-02-22????False
          2018-02-14????False
          #?邏輯判斷的結(jié)果可以作為篩選的依據(jù)
          data[data["open"]?>?23].head()

          結(jié)果:
          0f659330adea92b85a8d875fecd02e00.webp

          • 完成多個(gè)邏輯判斷:
          data[(data["open"]?>?23)?&?(data["open"]?<?24)].head()
          3101c40f27ba3ec0035b02b612b58541.webp

          3.2.2 邏輯運(yùn)算函數(shù)

          • (1)query(expr)
            • expr:查詢字符串

          通過(guò)query使得剛才的過(guò)程更加方便簡(jiǎn)單,下面是使用的例子:

          data.query("open<24?&?open>23").head()

          結(jié)果:
          83773007ae4e4f25b8cd1ebd6965a950.webp

          • (2)isin(values)

          例如判斷’open’是否為23.53和23.85:

          #?可以指定值進(jìn)行一個(gè)判斷,從而進(jìn)行篩選操作
          data[data["open"].isin([23.53,?23.85])]
          7e9fb7080ce7231f698b2a8e5126c0bc.webp

          3.2.3 統(tǒng)計(jì)運(yùn)算

          (1)describe

          綜合分析: 能夠直接得出很多統(tǒng)計(jì)結(jié)果,count, mean, std, min, max 等

          #?計(jì)算平均值、標(biāo)準(zhǔn)差、最大值、最小值
          data.describe()
          2339606ed91d4a27628b785671bcd83a.webp

          (2)統(tǒng)計(jì)函數(shù)

          看一下min(最小值), max(最大值), mean(平均值), median(中位數(shù)), var(方差), std(標(biāo)準(zhǔn)差),mode(眾數(shù))是怎么操作的:

          0a13771b00669d4ebc5f064f2bda4510.webp

          對(duì)于單個(gè)函數(shù)去進(jìn)行統(tǒng)計(jì)的時(shí)候,坐標(biāo)軸還是按照默認(rèn)列“columns” (axis=0, default),如果要對(duì)行“index” 需要指定(axis=1)。

          • (1)max()、min()
          #?使用統(tǒng)計(jì)函數(shù):0?代表列求結(jié)果, 1 代表行求統(tǒng)計(jì)結(jié)果
          data.max(axis=0)?#?最大值

          open???????????????????34.99
          high???????????????????36.35
          close??????????????????35.21
          low????????????????????34.01
          volume?????????????501915.41
          price_change????????????3.03
          p_change???????????????10.03
          turnover???????????????12.56
          my_price_change?????????3.41
          dtype:?float64
          • (2)std()、var()
          #?方差
          data.var(axis=0)

          open???????????????1.545255e+01
          high???????????????1.662665e+01
          close??????????????1.554572e+01
          low????????????????1.437902e+01
          volume?????????????5.458124e+09
          price_change???????8.072595e-01
          p_change???????????1.664394e+01
          turnover???????????4.323800e+00
          my_price_change????6.409037e-01
          dtype:?float64

          #?標(biāo)準(zhǔn)差
          data.std(axis=0)

          open???????????????????3.930973
          high???????????????????4.077578
          close??????????????????3.942806
          low????????????????????3.791968
          volume?????????????73879.119354
          price_change???????????0.898476
          p_change???????????????4.079698
          turnover???????????????2.079375
          my_price_change????????0.800565
          dtype:?float64
          • (3)median():中位數(shù)

          中位數(shù)為將數(shù)據(jù)從小到大排列,在最中間的那個(gè)數(shù)為中位數(shù)。如果沒(méi)有中間數(shù),取中間兩個(gè)數(shù)的平均值。

          data.median(axis=0)

          open???????????????21.44
          high???????????????21.97
          close??????????????10.00
          low????????????????20.98
          volume??????????83175.93
          price_change????????0.05
          p_change????????????0.26
          turnover????????????2.50
          dtype:?float64
          • (4)idxmax()、idxmin()
          #?求出最大值的位置
          data.idxmax(axis=0)

          open???????????????2015-06-15
          high???????????????2015-06-10
          close??????????????2015-06-12
          low????????????????2015-06-12
          volume?????????????2017-10-26
          price_change???????2015-06-09
          p_change???????????2015-08-28
          turnover???????????2017-10-26
          my_price_change????2015-07-10
          dtype:?object


          #?求出最小值的位置
          data.idxmin(axis=0)

          open???????????????2015-03-02
          high???????????????2015-03-02
          close??????????????2015-09-02
          low????????????????2015-03-02
          volume?????????????2016-07-06
          price_change???????2015-06-15
          p_change???????????2015-09-01
          turnover???????????2016-07-06
          my_price_change????2015-06-15
          dtype:?object

          (3)累計(jì)統(tǒng)計(jì)函數(shù)

          72053d0c002f138c1f36d7e78820a3f9.webp

          那么這些累計(jì)統(tǒng)計(jì)函數(shù)怎么用?
          46f2d154fe4ea8cae26b220ba9d73f08.webp
          以上這些函數(shù)可以對(duì)series和dataframe操作,這里我們按照時(shí)間的從前往后來(lái)進(jìn)行累計(jì)

          • 排序
          #?排序之后,進(jìn)行累計(jì)求和
          data?=?data.sort_index()
          • 對(duì)p_change進(jìn)行求和
          stock_rise?=?data['p_change']

          stock_rise.cumsum()

          2015-03-02??????2.62
          2015-03-03??????4.06
          2015-03-04??????5.63
          2015-03-05??????7.65
          2015-03-06?????16.16
          2015-03-09?????16.37
          2015-03-10?????18.75
          2015-03-11?????16.36
          2015-03-12?????15.03
          2015-03-13?????17.58
          2015-03-16?????20.34
          2015-03-17?????22.42
          2015-03-18?????23.28
          2015-03-19?????23.74
          2015-03-20?????23.48
          2015-03-23?????23.74

          那么如何讓這個(gè)連續(xù)求和的結(jié)果更好的顯示呢?

          如果要使用plot函數(shù),需要導(dǎo)入matplotlib.下面是繪圖代碼:

          import?matplotlib.pyplot?as?plt
          #?plot顯示圖形,?plot方法集成了直方圖、條形圖、餅圖、折線圖
          stock_rise.cumsum().plot()
          #?需要調(diào)用show,才能顯示出結(jié)果
          plt.show()

          結(jié)果:
          c41adda65404017d695cc60b2feef3e7.webp

          關(guān)于plot,稍后會(huì)介紹API的選擇。

          (4)自定義運(yùn)算

          • apply(func, axis=0)
            • func:自定義函數(shù)
            • axis=0:默認(rèn)是列,axis=1為行進(jìn)行運(yùn)算
          • 定義一個(gè)對(duì)列,最大值-最小值的函數(shù)

          下面看個(gè)例子:

          data[['open',?'close']].apply(lambda?x:?x.max()?-?x.min(),?axis=0)

          open?????22.74
          close????22.85
          dtype:?float64

          特定需求需要用這個(gè)。

          4、Pandas畫圖

          4.1 pandas.DataFrame.plot

          • DataFrame.plot(kind='line')

            • ‘line’ : 折線圖
            • ‘bar’ : 條形圖
            • ‘barh’ : 橫放的條形圖
            • ‘hist’ : 直方圖
            • ‘pie’ : 餅圖
            • ‘scatter’ : 散點(diǎn)圖
            • kind : str,需要繪制圖形的種類

          關(guān)于“barh”的解釋:
          http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.barh.html

          更多細(xì)節(jié):https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.plot.html?highlight=plot#pandas.DataFrame.plot

          看個(gè)例子:

          import?matplotlib.pyplot?as?plt
          #?plot顯示圖形,?plot方法集成了直方圖、條形圖、餅圖、折線圖
          stock_rise.cumsum().plot(kind="line")
          #?需要調(diào)用show,才能顯示出結(jié)果
          plt.show()

          結(jié)果:
          c41adda65404017d695cc60b2feef3e7.webp

          4.2 pandas.Series.plot

          更多細(xì)節(jié):https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.plot.html?highlight=plot#pandas.Series.plot

          注:使用的時(shí)候查看。

          5、文件讀取與存儲(chǔ)

          我們的數(shù)據(jù)大部分存在于文件當(dāng)中,所以pandas會(huì)支持復(fù)雜的IO操作,pandas的API支持眾多的文件格式,如CSV、SQL、XLS、JSON、HDF5。

          注:最常用的HDF5和CSV文件

          5a8c3e21dc98a0dd7fc6ae729d7b3885.webp
          接下來(lái)重點(diǎn)看一下,應(yīng)用CSV方式、HDF方式和json方式實(shí)現(xiàn)文件的讀取和存儲(chǔ)。

          5.1 CSV

          5.1.1 read_csv

          • pandas.read_csv(filepath_or_buffer, sep =',', usecols )

            • filepath_or_buffer:文件路徑
            • sep :分隔符,默認(rèn)用","隔開(kāi)
            • usecols:指定讀取的列名,列表形式

          舉例:讀取之前的股票的數(shù)據(jù):

          #?讀取文件,并且指定只獲取'open',?'close'指標(biāo)
          data?=?pd.read_csv("./data/stock_day.csv",?usecols=['open',?'close'])

          ????????????open????close
          2018-02-27????23.53????24.16
          2018-02-26????22.80????23.53
          2018-02-23????22.88????22.82
          2018-02-22????22.25????22.28
          2018-02-14????21.49????21.92

          5.1.2 to_csv

          • DataFrame.to_csv(path_or_buf=None, sep=', ’, columns=None, header=True, index=True, mode='w', encoding=None)

            • path_or_buf :文件路徑
            • sep :分隔符,默認(rèn)用","隔開(kāi)
            • columns :選擇需要的列索引
            • header :boolean or list of string, default True,是否寫進(jìn)列索引值
            • index:是否寫進(jìn)行索引
            • mode:‘w’:重寫, ‘a(chǎn)’ 追加

          舉例:保存讀取出來(lái)的股票數(shù)據(jù)
          保存’open’列的數(shù)據(jù),然后讀取查看結(jié)果:

          #?選取10行數(shù)據(jù)保存,便于觀察數(shù)據(jù)
          data[:10].to_csv("./data/test.csv",?columns=['open'])

          #?讀取,查看結(jié)果
          pd.read_csv("./data/test.csv")

          ?????Unnamed:?0????open
          0????2018-02-27????23.53
          1????2018-02-26????22.80
          2????2018-02-23????22.88
          3????2018-02-22????22.25
          4????2018-02-14????21.49
          5????2018-02-13????21.40
          6????2018-02-12????20.70
          7????2018-02-09????21.20
          8????2018-02-08????21.79
          9????2018-02-07????22.69

          會(huì)發(fā)現(xiàn)將索引存入到文件當(dāng)中,變成單獨(dú)的一列數(shù)據(jù)。如果需要?jiǎng)h除,可以指定index參數(shù),刪除原來(lái)的文件,重新保存一次。

          下面例子把index指定為False,那么保存的時(shí)候就不會(huì)保存行索引了:

          #?index:存儲(chǔ)不會(huì)將索引值變成一列數(shù)據(jù)
          data[:10].to_csv("./data/test.csv",?columns=['open'],?index=False)

          當(dāng)然我們也可以這么做,就是把索引保存到文件中,讀取的時(shí)候變成了一列,那么可以把這個(gè)列再變成索引,如下:

          #?把Unnamed:?0這一列,變成行索引
          open.set_index(["Unnamed:?0"])

          #?把索引名字變成index
          open.index.name?=?"index"

          5.2 HDF5

          5.2.1 read_hdf與to_hdf

          HDF5文件的讀取和存儲(chǔ)需要指定一個(gè)鍵,值為要存儲(chǔ)的DataFrame

          • (1)pandas.read_hdf(path_or_buf,key =None,** kwargs)

            • path_or_buffer:文件路徑
            • key:讀取的鍵
            • return:Theselected object
          • (2)DataFrame.to_hdf(path_or_buf, key, **kwargs)

          5.2.2 案例

          • 讀取文件
          day_close?=?pd.read_hdf("./data/day_close.h5")

          如果讀取的時(shí)候出現(xiàn)以下錯(cuò)誤
          2b9c8a07286674cd40110bec8389353c.webp
          需要安裝安裝tables模塊避免不能讀取HDF5文件

          pip?install?tables
          715ec45bcacc0e226819bfa397809c4b.webp
          • 存儲(chǔ)文件
          day_close.to_hdf("./data/test.h5",?key="day_close")

          再次讀取的時(shí)候, 需要指定鍵的名字

          new_close?=?pd.read_hdf("./data/test.h5",?key="day_close")

          注意:優(yōu)先選擇使用HDF5文件存儲(chǔ)

          • HDF5在存儲(chǔ)的時(shí)候支持壓縮,使用的方式是blosc,這個(gè)是速度最快的也是pandas默認(rèn)支持的
          • 使用壓縮可以提磁盤利用率,節(jié)省空間
          • HDF5還是跨平臺(tái)的,可以輕松遷移到hadoop 上面

          5.3 JSON

          JSON是我們常用的一種數(shù)據(jù)交換格式,在前后端的交互經(jīng)常用到,也會(huì)在存儲(chǔ)的時(shí)候選擇這種格式。所以我們需要知道Pandas如何進(jìn)行讀取和存儲(chǔ)JSON格式。

          5.3.1 read_json

          • pandas.read_json(path_or_buf=None, orient=None, typ='frame', lines=False)

            • 按照每行讀取json對(duì)象
            • (1)‘split’ : dict like {index -> [index], columns -> [columns], data -> [values]}
            • (2)‘records’ : list like [{column -> value}, … , {column -> value}]
            • (3)‘index’ : dict like {index -> {column -> value}}
            • (4)‘columns’ : dict like {column -> {index -> value}},默認(rèn)該格式
            • (5)‘values’ : just the values array
            • split 將索引總結(jié)到索引,列名到列名,數(shù)據(jù)到數(shù)據(jù)。將三部分都分開(kāi)了
            • records 以columns:values的形式輸出
            • index 以index:{columns:values}…的形式輸出
            • colums 以columns:{index:values}的形式輸出
            • values 直接輸出值
            • path_or_buf : 路徑
            • orient : string,以什么樣的格式顯示.下面是5種格式:
            • lines : boolean, default False
            • typ : default ‘frame’, 指定轉(zhuǎn)換成的對(duì)象類型series或者dataframe

          案例:

          • 數(shù)據(jù)介紹:

          這里使用一個(gè)新聞標(biāo)題諷刺數(shù)據(jù)集,格式為json。is_sarcastic:1諷刺的,否則為0;headline:新聞報(bào)道的標(biāo)題;article_link:鏈接到原始新聞文章。存儲(chǔ)格式為:

          {"article_link":?"https://www.huffingtonpost.com/entry/versace-black-code_us_5861fbefe4b0de3a08f600d5",?"headline":?"former?versace?store?clerk?sues?over?secret?'black?code'?for?minority?shoppers",?"is_sarcastic":?0}
          {"article_link":?"https://www.huffingtonpost.com/entry/roseanne-revival-review_us_5ab3a497e4b054d118e04365",?"headline":?"the?'roseanne'?revival?catches?up?to?our?thorny?political?mood,?for?better?and?worse",?"is_sarcastic":?0}
          • 讀取

          orient指定存儲(chǔ)的json格式,lines指定按照行去變成一個(gè)樣本:

          json_read?=?pd.read_json("./data/Sarcasm_Headlines_Dataset.json",?orient="records",?lines=True)

          結(jié)果為:

          5.3.2 to_json

          • DataFrame.to_json(path_or_buf=None, orient=None, lines=False)
            • 將Pandas 對(duì)象存儲(chǔ)為json格式
            • path_or_buf=None:文件地址
            • orient:存儲(chǔ)的json形式,{‘split’,’records’,’index’,’columns’,’values’}
            • lines:一個(gè)對(duì)象存儲(chǔ)為一行

          案例:

          • 存儲(chǔ)文件
          #?不指定lines=Treu,則保存成一行
          json_read.to_json("./data/test.json",?orient='records')

          結(jié)果:

          [{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/versace-black-code_us_5861fbefe4b0de3a08f600d5","headline":"former?versace?store?clerk?sues?over?secret?'black?code'?for?minority?shoppers","is_sarcastic":0},{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/roseanne-revival-review_us_5ab3a497e4b054d118e04365","headline":"the?'roseanne'?revival?catches?up?to?our?thorny?political?mood,?for?better?and?worse","is_sarcastic":0},{"article_link":"https:\/\/local.theonion.com\/mom-starting-to-fear-son-s-web-series-closest-thing-she-1819576697","headline":"mom?starting?to?fear?son's?web?series?closest?thing?she?will?have?to?grandchild","is_sarcastic":1},{"article_link":"https:\/\/politics.theonion.com\/boehner-just-wants-wife-to-listen-not-come-up-with-alt-1819574302","headline":"boehner?just?wants?wife?to?listen,?not?come?up?with?alternative?debt-reduction?ideas","is_sarcastic":1},{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/jk-rowling-wishes-snape-happy-birthday_us_569117c4e4b0cad15e64fdcb","headline":"j.k.?rowling?wishes?snape?happy?birthday?in?the?most?magical?way","is_sarcastic":0},{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/advancing-the-worlds-women_b_6810038.html","headline":"advancing?the?world's?women","is_sarcastic":0},....]
          • 修改lines參數(shù)為True
          #?指定lines=True,則多行存儲(chǔ)
          json_read.to_json("./data/test.json",?orient='records',?lines=True)

          結(jié)果:

          {"article_link":"https:\/\/www.huffingtonpost.com\/entry\/versace-black-code_us_5861fbefe4b0de3a08f600d5","headline":"former?versace?store?clerk?sues?over?secret?'black?code'?for?minority?shoppers","is_sarcastic":0}
          {"article_link":"https:\/\/www.huffingtonpost.com\/entry\/roseanne-revival-review_us_5ab3a497e4b054d118e04365","headline":"the?'roseanne'?revival?catches?up?to?our?thorny?political?mood,?for?better?and?worse","is_sarcastic":0}
          {"article_link":"https:\/\/local.theonion.com\/mom-starting-to-fear-son-s-web-series-closest-thing-she-1819576697","headline":"mom?starting?to?fear?son's?web?series?closest?thing?she?will?have?to?grandchild","is_sarcastic":1}
          {"article_link":"https:\/\/politics.theonion.com\/boehner-just-wants-wife-to-listen-not-come-up-with-alt-1819574302","headline":"boehner?just?wants?wife?to?listen,?not?come?up?with?alternative?debt-reduction?ideas","is_sarcastic":1}
          {"article_link":"https:\/\/www.huffingtonpost.com\/entry\/jk-rowling-wishes-snape-happy-birthday_us_569117c4e4b0cad15e64fdcb","headline":"j.k.?rowling?wishes?snape?happy?birthday?in?the?most?magical?way","is_sarcastic":0}...
          6、高級(jí)處理-缺失值處理

          在pandas中,缺失值使用NaN來(lái)標(biāo)記,如下圖所示:
          5c3c732065c66666f962ab093a9fb33d.webp

          6.1 如何處理nan

          按如下步驟進(jìn)行:

          • (1)獲取缺失值的標(biāo)記方式(NaN或者其他標(biāo)記方式)

          • (2)如果缺失值的標(biāo)記方式是NaN

            • 1、刪除存在缺失值的:dropna(axis='rows')
              注:不會(huì)修改原數(shù)據(jù),需要接受返回值

            • 2、替換缺失值:fillna(value, inplace=True)

            • value:替換成的值
            • inplace:True:會(huì)修改原數(shù)據(jù),F(xiàn)alse:不替換修改原數(shù)據(jù),生成新的對(duì)象
            • pd.isnull(df),
            • pd.notnull(df)
            • 判斷數(shù)據(jù)中是否包含NaN:

            • 存在缺失值nan:

          • (3)如果缺失值沒(méi)有使用NaN標(biāo)記,比如使用"?"

            • 先替換‘?’為np.nan,然后繼續(xù)處理

          步驟就是上面的這樣,下面通過(guò)例子來(lái)看看怎么使用pandas處理的:

          6.2 電影數(shù)據(jù)的缺失值處理

          • 電影數(shù)據(jù)文件獲取
          #?讀取電影數(shù)據(jù)
          movie?=?pd.read_csv("./data/IMDB-Movie-Data.csv")
          12796f3e32bc2ae9af19b2e6664e7c61.webp

          6.2.1 判斷缺失值是否存在

          • (1)pd.notnull()

          #?判斷是否是缺失值,是則返回False
          pd.notnull(movie)

          #?結(jié)果:
          Rank????Title????Genre????Description????Director????Actors????Year????Runtime?(Minutes)????Rating????Votes????Revenue?(Millions)????Metascore
          0????True????True????True????True????True????True????True????True????True????True????True????True
          1????True????True????True????True????True????True????True????True????True????True????True????True
          2????True????True????True????True????True????True????True????True????True????True????True????True
          3????True????True????True????True????True????True????True????True????True????True????True????True
          4????True????True????True????True????True????True????True????True????True????True????True????True
          5????True????True????True????True????True????True????True????True????True????True????True????True
          6????True????True????True????True????True????True????True????True????True????True????True????True
          7????True????True????True????True????True????True????True????True????True????True????False????True

          但是上面這樣顯然不好觀察,我們可以借助np.all()來(lái)返回是否有缺失值。np.all()只要有一個(gè)就返回False,下面看例子:

          np.all(pd.notnull(movie))

          #?返回
          False
          • (2)pd.isnull()

            這個(gè)和上面的正好相反,判斷是否是缺失值,是則返回True。

          #?判斷是否是缺失值,是則返回True
          pd.isnull(movie).head()

          #?結(jié)果:
          ?Rank?Title?Genre?Description?Director?Actors?Year?Runtime?(Minutes)?Rating?Votes?Revenue?(Millions)?Metascore
          0?False?False?False?False?False?False?False?False?False?False?False?False
          1?False?False?False?False?False?False?False?False?False?False?False?False
          2?False?False?False?False?False?False?False?False?False?False?False?False
          3?False?False?False?False?False?False?False?False?False?False?False?False
          4?False?False?False?False?False?False?False?False?False?False?False?False

          這個(gè)也不好觀察,我們利用np.any() 來(lái)判斷是否有缺失值,若有則返回True,下面看例子:

          np.any(pd.isnull(movie))
          #?返回
          True

          6.2.2 存在缺失值nan,并且是np.nan

          • 1、刪除

          pandas刪除缺失值,使用dropna的前提是,缺失值的類型必須是np.nan

          #?不修改原數(shù)據(jù)
          movie.dropna()

          #?可以定義新的變量接受或者用原來(lái)的變量名
          data?=?movie.dropna()
          • 2、替換缺失值
          #?替換存在缺失值的樣本的兩列
          #?替換填充平均值,中位數(shù)
          movie['Revenue?(Millions)'].fillna(movie['Revenue?(Millions)'].mean(),?inplace=True)

          替換所有缺失值:

          #?這個(gè)循環(huán),每次取出一列數(shù)據(jù),然后用均值來(lái)填充
          for?i?in?movie.columns:
          ????if?np.all(pd.notnull(movie[i]))?==?False:
          ????????print(i)
          ????????movie[i].fillna(movie[i].mean(),?inplace=True)

          6.2.3 不是缺失值nan,有默認(rèn)標(biāo)記的

          直接看例子:

          數(shù)據(jù)是這樣的:
          0c8e990404138c0aab8996da6735d68a.webp

          #?讀入數(shù)據(jù)
          wis?=?pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data")

          以上數(shù)據(jù)在讀取時(shí),可能會(huì)報(bào)如下錯(cuò)誤:

          URLError:?<urlopen?error?[SSL:?CERTIFICATE_VERIFY_FAILED]?certificate?verify?failed?(_ssl.c:833)>

          解決辦法:

          #?全局取消證書驗(yàn)證
          import?ssl
          ssl._create_default_https_context?=?ssl._create_unverified_context

          處理思路分析:

          • 1、先替換‘?’為np.nan
            • to_replace:替換前的值
            • value:替換后的值
            • df.replace(to_replace=, value=)
          #?把一些其它值標(biāo)記的缺失值,替換成np.nan
          wis?=?wis.replace(to_replace='?',?value=np.nan)
          • 2、再進(jìn)行缺失值的處理
          #?刪除
          wis?=?wis.dropna()
          • 3、驗(yàn)證:
          np.all(pd.notnull(wis))
          #?返回True,說(shuō)明沒(méi)有了缺失值

          #?或者

          np.any(pd.isnull(wis))
          #?返回False,說(shuō)明沒(méi)有了缺失值
          7、高級(jí)處理-數(shù)據(jù)離散化

          7.1 為什么要離散化

          連續(xù)屬性離散化的目的是為了簡(jiǎn)化數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)離散化技術(shù)可以用來(lái)減少給定連續(xù)屬性值的個(gè)數(shù)。離散化方法經(jīng)常作為數(shù)據(jù)挖掘的工具。

          7.2 什么是數(shù)據(jù)的離散化

          連續(xù)屬性的離散化就是在連續(xù)屬性的值域上,將值域劃分為若干個(gè)離散的區(qū)間,最后用不同的符號(hào)或整數(shù) 值代表落在每個(gè)子區(qū)間中的屬性值。

          離散化有很多種方法,這里使用一種最簡(jiǎn)單的方式去操作:

          • 原始人的身高數(shù)據(jù):165,174,160,180,159,163,192,184
          • 假設(shè)按照身高分幾個(gè)區(qū)間段:150~165, 165~180,180~195

          這樣我們將數(shù)據(jù)分到了三個(gè)區(qū)間段,對(duì)應(yīng)的標(biāo)記為矮、中、高三個(gè)類別,最終要處理成一個(gè)"啞變量"矩陣。

          下面通過(guò)股票數(shù)據(jù)的例子來(lái)看看,具體是怎么操作的。

          7.3 股票的漲跌幅離散化

          我們對(duì)股票每日的"p_change"這一列進(jìn)行離散化,下圖便是離散化后的結(jié)果,當(dāng)前數(shù)據(jù)存在哪個(gè)區(qū)間,則這個(gè)區(qū)間標(biāo)記為1,否則為0。

          5ab14ece936ca8835fd7bdce12faa489.webp
          那具體怎么做的呢?接著看:

          7.3.1 讀取股票的數(shù)據(jù)

          先讀取股票的數(shù)據(jù),篩選出p_change數(shù)據(jù)。

          data?=?pd.read_csv("./data/stock_day.csv")
          p_change=?data['p_change']

          7.3.2 將股票漲跌幅數(shù)據(jù)進(jìn)行分組

          下面是所在區(qū)間的個(gè)數(shù)。
          301c3b77dadecccc7b063305081bf922.webp

          使用的工具:

          • pd.qcut(data, q)
            • 對(duì)數(shù)據(jù)進(jìn)行分組,將數(shù)據(jù)分成q組,一般會(huì)與value_counts搭配使用,統(tǒng)計(jì)每組的個(gè)數(shù)
          • series.value_counts():統(tǒng)計(jì)每個(gè)分組中有多少數(shù)據(jù)。
          #?自行分組
          qcut?=?pd.qcut(p_change,?10)
          #?計(jì)算分到每個(gè)組數(shù)據(jù)個(gè)數(shù)
          qcut.value_counts()

          #?運(yùn)行結(jié)果:
          (5.27,?10.03]????????????????????65
          (0.26,?0.94]?????????????????????65
          (-0.462,?0.26]???????????????????65
          (-10.030999999999999,?-4.836]????65
          (2.938,?5.27]????????????????????64
          (1.738,?2.938]???????????????????64
          (-1.352,?-0.462]?????????????????64
          (-2.444,?-1.352]?????????????????64
          (-4.836,?-2.444]?????????????????64
          (0.94,?1.738]????????????????????63
          Name:?p_change,?dtype:?int64

          自定義區(qū)間分組:

          • pd.cut(data, bins)
          #?自己指定分組區(qū)間
          bins?=?[-100,?-7,?-5,?-3,?0,?3,?5,?7,?100]
          p_counts?=?pd.cut(p_change,?bins)
          p_counts.value_counts()

          #?運(yùn)行結(jié)果:
          (0,?3]????????215
          (-3,?0]???????188
          (3,?5]?????????57
          (-5,?-3]???????51
          (7,?100]???????35
          (5,?7]?????????35
          (-100,?-7]?????34
          (-7,?-5]???????28
          Name:?p_change,?dtype:?int64

          7.3.3 股票漲跌幅分組數(shù)據(jù)變成one-hot編碼

          • 什么是one-hot編碼
            把每個(gè)類別生成一個(gè)布爾列,這些列中只有一列可以為這個(gè)樣本取值為1.其又被稱為熱編碼。

          把下圖中左邊的表格轉(zhuǎn)化為使用右邊形式進(jìn)行表示:

          8954cdb14e70f7c2fd66ff317101879b.webp
          下面看看pandas中是怎么實(shí)現(xiàn)的:

          • pandas.get_dummies(data, prefix=None)
            • data:array-like, Series, or DataFrame

            • prefix:分組名字

          下面是例子:

          #?得出one-hot編碼矩陣
          dummies?=?pd.get_dummies(p_counts,?prefix="rise")

          運(yùn)行結(jié)果:
          5ab14ece936ca8835fd7bdce12faa489.webp

          8、高級(jí)處理-合并

          如果你的數(shù)據(jù)由多張表組成,那么有時(shí)候需要將不同的內(nèi)容合并在一起分析

          8.1 pd.concat實(shí)現(xiàn)數(shù)據(jù)合并

          • pd.concat([data1, data2], axis=1)

            • 按照行或列進(jìn)行合并,axis=0為列索引,axis=1為行索引

          比如我們將剛才處理好的one-hot編碼與原數(shù)據(jù)合并:

          #?按照行索引進(jìn)行
          pd.concat([data,?dummies],?axis=1)

          結(jié)果:
          66c120f215121bddfafff28bee08f6d9.webp

          8.2 pd.merge

          • pd.merge(left, right, how='inner', on=None)

            • 可以指定按照兩組數(shù)據(jù)的共同鍵值對(duì)合并或者左右各自
            • left: DataFrame
            • right: 另一個(gè)DataFrame
            • on: 指定的共同鍵
            • how:按照什么方式連接,下面的表格是說(shuō)明

          15fba4d656c8d25b32c20b56de57fe61.webp

          例子:

          left?=?pd.DataFrame({'key1':?['K0',?'K0',?'K1',?'K2'],
          ????????????????????????'key2':?['K0',?'K1',?'K0',?'K1'],
          ????????????????????????'A':?['A0',?'A1',?'A2',?'A3'],
          ????????????????????????'B':?['B0',?'B1',?'B2',?'B3']})

          right?=?pd.DataFrame({'key1':?['K0',?'K1',?'K1',?'K2'],
          ????????????????????????'key2':?['K0',?'K0',?'K0',?'K0'],
          ????????????????????????'C':?['C0',?'C1',?'C2',?'C3'],
          ????????????????????????'D':?['D0',?'D1',?'D2',?'D3']})
          • 內(nèi)連接:健相同的取上,不同的刪掉
          #?默認(rèn)內(nèi)連接
          result?=?pd.merge(left,?right,?on=['key1',?'key2'])

          結(jié)果:
          6ec544896dc6ac578ab810a2eb266b32.webp

          • 左連接:按左邊的數(shù)據(jù)進(jìn)行合并
          result?=?pd.merge(left,?right,?how='left',?on=['key1',?'key2'])

          結(jié)果:
          69099796a8aa9fd2ac7d4ad268a914c8.webp

          • 右連接:按右邊的數(shù)據(jù)進(jìn)行合并
          result?=?pd.merge(left,?right,?how='right',?on=['key1',?'key2'])
          768037e1a2811de72fe561971d00455e.webp
          • 鏈接:無(wú)論健是否相同都取上,對(duì)應(yīng)不上的使用NaN填充。
          result?=?pd.merge(left,?right,?how='outer',?on=['key1',?'key2'])

          結(jié)果:
          4d231f606f72e71a0db18fe8b0c03d36.webp

          9、高級(jí)處理-交叉表與透視表

          9.1 交叉表與透視表什么作用

          探究股票的漲跌與星期幾有關(guān)?

          以下圖當(dāng)中表示,week代表星期幾,1,0代表這一天股票的漲跌幅是好還是壞,里面的數(shù)據(jù)代表比例

          可以理解為所有時(shí)間為星期一等等的數(shù)據(jù)當(dāng)中漲跌幅好壞的比例
          e87eda7a8c1f0d5a4d0180b93b6d86b4.webp
          e211559264c0609217182486c5fd7525.webp

          • 交叉表:交叉表用于計(jì)算一列數(shù)據(jù)對(duì)于另外一列數(shù)據(jù)的分組個(gè)數(shù)(用于統(tǒng)計(jì)分組頻率的特殊透視表)
            • pd.crosstab(value1, value2)
          • 透視表:透視表是將原有的DataFrame的列分別作為行索引和列索引,然后對(duì)指定的列應(yīng)用聚集函數(shù)
            • data.pivot_table()
            • DataFrame.pivot_table([], index=[])

          9.2 案例分析

          9.2.1 數(shù)據(jù)準(zhǔn)備

          • 準(zhǔn)備兩列數(shù)據(jù),星期數(shù)據(jù)以及漲跌幅是好是壞數(shù)據(jù)
          • 進(jìn)行交叉表計(jì)算
          #?尋找星期幾跟股票張得的關(guān)系
          #?1、先把對(duì)應(yīng)的日期找到星期幾
          date?=?pd.to_datetime(data.index).weekday
          data['week']?=?date??#?增加一列

          #?2、假如把p_change按照大小去分個(gè)類0為界限
          data['posi_neg']?=?np.where(data['p_change']?>?0,?1,?0)

          #?通過(guò)交叉表找尋兩列數(shù)據(jù)的關(guān)系
          count?=?pd.crosstab(data['week'],?data['posi_neg'])

          結(jié)果:

          52dc251ec6a603920b4b24f04c115d3e.webp

          但是我們看到count只是每個(gè)星期日子的好壞天數(shù),并沒(méi)有得到比例,該怎么去做?

          • 對(duì)于每個(gè)星期一等的總天數(shù)求和,運(yùn)用除法運(yùn)算求出比例
          #?算數(shù)運(yùn)算,先求和
          sum?=?count.sum(axis=1).astype(np.float32)

          #?進(jìn)行相除操作,得出比例
          pro?=?count.div(sum,?axis=0)

          結(jié)果:
          b9a83cc731cd9e8fc1507c17b73fa674.webp

          9.2.2 查看效果

          使用plot畫出這個(gè)比例,使用stacked的柱狀圖

          pro.plot(kind='bar',?stacked=True)
          plt.show()
          c348cafa79eed2088ff678253a7b3f87.webp

          9.2.3 使用pivot_table(透視表)實(shí)現(xiàn)

          使用透視表,剛才的過(guò)程更加簡(jiǎn)單

          #?通過(guò)透視表,將整個(gè)過(guò)程變成更簡(jiǎn)單一些
          data.pivot_table(['posi_neg'],?index='week')

          結(jié)果:
          2f377391777bd5899404a5869ae205b5.webp

          10、高級(jí)處理-分組與聚合

          分組與聚合通常是分析數(shù)據(jù)的一種方式,通常與一些統(tǒng)計(jì)函數(shù)一起使用,查看數(shù)據(jù)的分組情況

          10.1 什么分組與聚合

          下圖展示了分組與聚合的概念:
          deb245350e764f82d0c8a85e9528fa7a.webp

          10.2 分組API

          • DataFrame.groupby(key, as_index=False)
            • key:分組的列數(shù)據(jù),可以多個(gè)

          案例:不同顏色的不同筆的價(jià)格數(shù)據(jù)

          col?=pd.DataFrame({'color':?['white','red','green','red','green'],?'object':?['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.30,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})

          #?結(jié)果:
          color????object????price1????price2
          0????white????pen????5.56????4.75
          1????red????pencil????4.20????4.12
          2????green????pencil????1.30????1.60
          3????red????ashtray????0.56????0.75
          4????green????pen????2.75????3.15
          • 進(jìn)行分組,對(duì)顏色分組,price進(jìn)行聚合:
          #?按color分組,再取出price1列求平均值
          col.groupby(['color'])['price1'].mean()
          #?和上述一個(gè)功能
          col['price1'].groupby(col['color']).mean()
          #?結(jié)果:
          color
          green????2.025
          red??????2.380
          white????5.560
          Name:?price1,?dtype:?float64

          #?分組,數(shù)據(jù)的結(jié)構(gòu)不變
          col.groupby(['color'],?as_index=False)['price1'].mean()
          #?結(jié)果:
          color????price1
          0????green????2.025
          1????red????2.380
          2????white????5.560

          10.3 星巴克零售店鋪數(shù)據(jù)

          現(xiàn)在我們有一組關(guān)于全球星巴克店鋪的統(tǒng)計(jì)數(shù)據(jù),如果我想知道美國(guó)的星巴克數(shù)量和中國(guó)的哪個(gè)多,或者我想知道中國(guó)每個(gè)省份星巴克的數(shù)量的情況,那么應(yīng)該怎么辦?

          數(shù)據(jù)來(lái)源:https://www.kaggle.com/starbucks/store-locations/data

          ca215c1bddbb277f37299b0c080ccb9e.webp

          10.3.1 數(shù)據(jù)獲取

          從文件中讀取星巴克店鋪數(shù)據(jù)

          #?導(dǎo)入星巴克店的數(shù)據(jù)
          starbucks?=?pd.read_csv("./data/starbucks/directory.csv")

          10.3.2 進(jìn)行分組聚合

          #?按照國(guó)家分組,求出每個(gè)國(guó)家的星巴克零售店數(shù)量
          count?=?starbucks.groupby(['Country']).count()

          畫圖顯示結(jié)果:

          count['Brand'].plot(kind='bar',?figsize=(20,?8))
          plt.show()

          f1ce878ed7d20497b47f0585946fee2c.webp
          假設(shè)我們加入省市一起進(jìn)行分組:

          #?設(shè)置多個(gè)索引,set_index()
          starbucks.groupby(['Country',?'State/Province']).count()

          結(jié)果:
          37133bb12fd400c8c99fefc4c4b67a10.webp

          11、電影案例分析

          11.1 需求

          現(xiàn)在我們有一組從2006年到2016年1000部最流行的電影數(shù)據(jù)

          數(shù)據(jù)來(lái)源:https://www.kaggle.com/damianpanek/sunday-eda/data

          • 問(wèn)題1:我們想知道這些電影數(shù)據(jù)中評(píng)分的平均分,導(dǎo)演的人數(shù)等信息,我們應(yīng)該怎么獲取?
          • 問(wèn)題2:對(duì)于這一組電影數(shù)據(jù),如果我們想rating,runtime的分布情況,應(yīng)該如何呈現(xiàn)數(shù)據(jù)?
          • 問(wèn)題3:對(duì)于這一組電影數(shù)據(jù),如果我們希望統(tǒng)計(jì)電影分類(genre)的情況,應(yīng)該如何處理數(shù)據(jù)?

          11.2 實(shí)現(xiàn)

          首先獲取導(dǎo)入包,獲取數(shù)據(jù):

          %matplotlib?inline
          import?pandas??as?pd?
          import?numpy?as?np
          from?matplotlib?import?pyplot?as?plt
          #文件的路徑
          path?=?"./data/IMDB-Movie-Data.csv"
          #讀取文件
          df?=?pd.read_csv(path)

          11.2.1 問(wèn)題一:

          我們想知道這些電影數(shù)據(jù)中評(píng)分的平均分,導(dǎo)演的人數(shù)等信息,我們應(yīng)該怎么獲取?

          • 得出評(píng)分的平均分

          使用mean函數(shù)

          df["Rating"].mean()

          #?結(jié)果:
          6.723200000000003
          • 得出導(dǎo)演人數(shù)信息

          求出唯一值,然后進(jìn)行形狀獲取

          ##?導(dǎo)演的人數(shù)
          #?df["Director"].unique().shape[0]?#?方法一
          np.unique(df["Director"]).shape[0]?#?方法二

          644

          11.2.2 問(wèn)題二:

          對(duì)于這一組電影數(shù)據(jù),如果我們想Rating的分布情況,應(yīng)該如何呈現(xiàn)數(shù)據(jù)?

          • 直接呈現(xiàn),以直方圖的形式

          選擇分?jǐn)?shù)列數(shù)據(jù),進(jìn)行plot

          df["Rating"].plot(kind='hist',figsize=(20,8))
          plt.show()

          效果:
          038fb384719a4b5b505ad5d471771a94.webp

          發(fā)現(xiàn)直接通過(guò)pandas的plot畫圖,顯示的下標(biāo)不合適,這個(gè)時(shí)候我們需要借助matplotlib來(lái)改變。

          • Rating進(jìn)行分布展示

          進(jìn)行繪制直方圖

          #?1.添加畫布
          plt.figure(figsize=(20,8),dpi=100)

          #?2.畫圖
          plt.hist(df["Rating"].values,bins=20)
          #?2.1?添加刻度線
          max_?=?df["Rating"].max()
          min_?=?df["Rating"].min()
          x_ticks?=?np.linspace(min_,?max_,?num=21)
          plt.xticks(x_ticks)
          #?2.2添加網(wǎng)格線
          plt.grid()

          #?3.顯示
          plt.show()
          07b28d9257b6c106d4fcf2bd7d5b0f1b.webp

          數(shù)據(jù)分析:從上圖中就可以發(fā)現(xiàn),評(píng)分主要分布在5~8分之間

          11.2.3 問(wèn)題三:

          對(duì)于這一組電影數(shù)據(jù),如果我們希望統(tǒng)計(jì)電影分類(genre)的情況,應(yīng)該如何處理數(shù)據(jù)?

          • 思路分析
            • 1、創(chuàng)建一個(gè)全為0的dataframe,列索引置為電影的分類,temp_df
            • 2、遍歷每一部電影,temp_df中把分類出現(xiàn)的列的值置為1
            • 3、求和
            • 思路

          下面接著看:

          • 1、創(chuàng)建一個(gè)全為0的dataframe,列索引置為電影的分類,temp_df
          #?進(jìn)行字符串分割
          temp_list?=?[i.split(",")?for?i?in?df["Genre"]]
          #?獲取電影的分類
          genre_list?=?np.unique([i?for?j?in?temp_list?for?i?in?j])?

          #?增加新的列,創(chuàng)建全為0的dataframe
          temp_df?=?pd.DataFrame(np.zeros([df.shape[0],genre_list.shape[0]]),columns=genre_list)
          • 2、遍歷每一部電影,temp_df中把分類出現(xiàn)的列的值置為1
          for?i?in?range(1000):
          ????#temp_list[i]?就是['Action','Adventure','Animation']等
          ????temp_df.ix[i,temp_list[i]]=1
          ????
          print(temp_df.sum().sort_values())?#?求合并排序,ascending=False為倒序
          • 3、求和,繪圖
          temp_df.sum().sort_values(ascending=False).plot(kind="bar",figsize=(20,8),fontsize=20,colormap="cool")
          plt.show()

          結(jié)果:
          8d7d5c1e912fd941dd1f51aed7788d20.webp

          - EOF -

          ? 推薦閱讀:


          點(diǎn)擊關(guān)注【python之禪】,提升Python技能??????

          瀏覽 18
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久亚洲中文字幕 | 无码坐爱网站 | 波多野结衣三区 | 囯产婷婷| 亚洲最大无|