《利用Python進(jìn)行數(shù)據(jù)分析》第五章-pandas的數(shù)據(jù)結(jié)構(gòu)介紹

pandas的數(shù)據(jù)結(jié)構(gòu)介紹

要使用pandas昼接,你首先就得熟悉它的兩個主要數(shù)據(jù)結(jié)構(gòu):Series和DataFrame炼邀。雖然它們并不能解決所有問題斤寇,但它們?yōu)榇蠖鄶?shù)應(yīng)用提供了一種可靠的、易于使用的基礎(chǔ)。

In [1]: from pandas import Series,DataFrame

In [2]: import pandas as pd

In [3]: import numpy as np

Series

Series是一種類似于一維數(shù)組的對象曲尸,它由一組數(shù)據(jù)(各種NumPy數(shù)據(jù)類型)以及一組與之相關(guān)的數(shù)據(jù)標(biāo)簽(即索引)組成。僅由一組數(shù)據(jù)即可產(chǎn)生最簡單的Series男翰。

In [4]: obj=Series([5,8,-6,2])

In [5]: obj
Out[5]: 
0 5
1 8
2 -6
3 2
dtype: int64

Series的字符串表現(xiàn)形式為:索引在左邊另患,值在右邊。由于我們沒有為數(shù)據(jù)指定索引蛾绎,于是會自動創(chuàng)建一個0到N1(N為數(shù)據(jù)的長度)的整數(shù)型索引昆箕。你可以通過Series 的values和index屬性獲取其數(shù)組表示形式和索引對象鸦列。

In [6]: obj.values
Out[6]: array([ 5, 8, -6, 2], dtype=int64)

In [7]: obj.index
Out[7]: RangeIndex(start=0, stop=4, step=1)

希望所創(chuàng)建的Series帶有一個可以對各個數(shù)據(jù)點進(jìn)行標(biāo)記的索引

In [8]: obj2=Series([4,8,-6,3],index=['d','a','b','c'])

In [9]: obj2
Out[9]: 
d 4
a 8
b -6
c 3
dtype: int64

與普通NumPy數(shù)組相比,你可以通過索引的方式選取Series中的單個或一組值

In [10]: obj2['b']
Out[10]: -6

In [11]: obj2['d']=9

In [12]: obj2[['c','a','d']]
Out[12]: 
c 3
a 8
d 9
dtype: int64

NumPy數(shù)組運算(如根據(jù)布爾型數(shù)組進(jìn)行過濾鹏倘、標(biāo)量乘法薯嗤、應(yīng)用數(shù)學(xué)函數(shù)等)都會保留索引和值之間的鏈接

In [13]: obj2
Out[13]: 
d 9
a 8
b -6
c 3
dtype: int64

In [14]: obj2[obj2>0]
Out[14]: 
d 9
a 8
c 3
dtype: int64

In [15]: obj2*3
Out[15]: 
d 27
a 24
b -18
c 9
dtype: int64

In [16]: np.exp(obj2)
Out[16]: 
d 8103.083928
a 2980.957987
b 0.002479
c 20.085537
dtype: float64

可以將Series看成是一個定長的有序字典,因為它是索引值到數(shù)據(jù)值的一個映射纤泵。它可以用在許多原本需要字典參數(shù)的函數(shù)中骆姐。

In [17]: 'b' in obj2
Out[17]: True

In [18]: 'k' in obj2
Out[18]: False

如果數(shù)據(jù)被存放在一個Python字典中,也可以直接通過這個字典來創(chuàng)建Series

In [19]: sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}

In [20]: obj3=Series(sdata)

In [21]: obj3
Out[21]: 
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000
dtype: int64

如果只傳入一個字典捏题,則結(jié)果Series中的索引就是原字典的鍵(有序排列)

In [22]: states = ['California', 'Ohio', 'Oregon', 'Texas']

In [23]: obj4 = Series(sdata, index=states)

In [24]: obj4
Out[24]: 
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64

sdata中跟states索引相匹配的那3個值會被找出來并放到相應(yīng)的位置上玻褪,但由于"California"所對應(yīng)的sdata值找不到,所以其結(jié)果就為NaN(即“非數(shù)字”(not a number)公荧,在pandas中带射,它用于表示缺失或NA值)。我將使用缺失(missing)或NA表示缺失數(shù)據(jù)循狰。pandas的isnull和notnull函數(shù)可用于檢測缺失數(shù)據(jù)

In [25]: pd.isnull(obj4)
Out[25]: 
California True
Ohio False
Oregon False
Texas False
dtype: bool

In [26]: pd.notnull(obj4)
Out[26]: 
California False
Ohio True
Oregon True
Texas True
dtype: bool

In [27]: obj4.isnull()
Out[27]: 
California True
Ohio False
Oregon False
Texas False
dtype: bool

Series最重要的一個功能是:它在算術(shù)運算中會自動對齊不同索引的數(shù)據(jù)窟社。

In [28]: obj3
Out[28]: 
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000
dtype: int64

In [29]: obj4
Out[29]: 
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64

In [30]: obj3+obj4
Out[30]: 
California NaN
Ohio 70000.0
Oregon 32000.0
Texas 142000.0
Utah NaN
dtype: float64

Series對象本身及其索引都有一個name屬性,該屬性跟pandas其他的關(guān)鍵功能關(guān)系非常密切

In [31]: obj4.name = 'population'

In [32]: obj4.index.name = 'state'

In [33]: obj4
Out[33]: 
state
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
Name: population, dtype: float64

In [34]: obj
Out[34]: 
0 5
1 8
2 -6
3 2
dtype: int64

Series的索引可以通過賦值的方式就地修改

In [35]: obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']

In [36]: obj
Out[36]: 
Bob 5
Steve 8
Jeff -6
Ryan 2
dtype: int64

DataFrame

DataFrame是一個表格型的數(shù)據(jù)結(jié)構(gòu)绪钥,它含有一組有序的列桥爽,每列可以是不同的值類型(數(shù)值、字符串昧识、布爾值等)钠四。DataFrame既有行索引也有列索引,它可以被看做由Series組成的字典(共用同一個索引)跪楞。DataFrame中的數(shù)據(jù)是以一個或多個二維塊存放的(而不是列表缀去、字典或別的一維數(shù)據(jù)結(jié)構(gòu))。
注意: 雖然DataFrame是以二維結(jié)構(gòu)保存數(shù)據(jù)的甸祭,但你仍然可以輕松地將其表示為更高維度的數(shù)據(jù)缕碎。

構(gòu)建DataFrame的辦法有很多,最常用的一種是直接傳入一個由等長列表或NumPy數(shù)組組成的字典池户。

In [37]: data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
    ...:         'year': [2000, 2001, 2002, 2001, 2002],
    ...:         'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}

In [38]: frame=DataFrame(data)

結(jié)果DataFrame會自動加上索引(跟Series一樣)咏雌,且全部列會被有序排列

In [39]: frame
Out[39]: 
pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002

如果指定了列序列,則DataFrame的列就會按照指定順序進(jìn)行排序

In [40]: DataFrame(data, columns=['year', 'state', 'pop'])
Out[40]: 
year state pop
0 2000 Ohio 1.5
1 2001 Ohio 1.7
2 2002 Ohio 3.6
3 2001 Nevada 2.4
4 2002 Nevada 2.9

In [41]: frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
    ...:                       index=['one', 'two', 'three', 'four', 'five'])

跟Series一樣校焦,如果傳入的列在數(shù)據(jù)中找不到赊抖,就會產(chǎn)生NA值

In [42]: frame2
Out[42]: 
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 NaN
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 NaN
five 2002 Nevada 2.9 NaN

In [43]: frame2.columns
Out[43]: Index(['year', 'state', 'pop', 'debt'], dtype='object')

通過類似字典標(biāo)記的方式或?qū)傩缘姆绞剑梢詫ataFrame的列獲取為一個Series

In [44]: frame2['state']
Out[44]: 
one Ohio
two Ohio
three Ohio
four Nevada
five Nevada
Name: state, dtype: object

In [45]: frame2.year
Out[45]: 
one 2000
two 2001
three 2002
four 2001
five 2002
Name: year, dtype: int64

注意寨典,返回的Series擁有原DataFrame相同的索引氛雪,且其name屬性也已經(jīng)被相應(yīng)地設(shè)置好了。行也可以通過位置或名稱的方式進(jìn)行獲取耸成,比如用索引字段ix(被舍棄使用)报亩,可以使用loc

In [46]: frame2.ix['three']
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: DeprecationWarning: 
.ix is deprecated. Please use
.loc for label based indexing or
.iloc for positional indexing

See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate_ix
"""Entry point for launching an IPython kernel.
Out[46]: 
year 2002
state Ohio
pop 3.6
debt NaN
Name: three, dtype: object

In [47]: frame2.loc['three']
Out[47]: 
year 2002
state Ohio
pop 3.6
debt NaN
Name: three, dtype: object

列可以通過賦值的方式進(jìn)行修改浴鸿。例如,我們可以給那個空的"debt"列賦上一個標(biāo)量值或一組值

In [48]: frame2['debt'] = 18.5

In [49]: frame2
Out[49]: 
year state pop debt
one 2000 Ohio 1.5 18.5
two 2001 Ohio 1.7 18.5
three 2002 Ohio 3.6 18.5
four 2001 Nevada 2.4 18.5
five 2002 Nevada 2.9 18.5

In [50]: frame2['debt'] = np.arange(5.)

In [51]: frame2
Out[51]: 
year state pop debt
one 2000 Ohio 1.5 0.0
two 2001 Ohio 1.7 1.0
three 2002 Ohio 3.6 2.0
four 2001 Nevada 2.4 3.0
five 2002 Nevada 2.9 4.0

將列表或數(shù)組賦值給某個列時弦追,其長度必須跟DataFrame的長度相匹配岳链。如果賦值的是一個Series,就會精確匹配DataFrame的索引劲件,所有的空位都將被填上缺失值

In [52]: val = Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])

In [53]: frame2['debt']=val

In [54]: frame2
Out[54]: 
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 -1.2
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 -1.5
five 2002 Nevada 2.9 -1.7

為不存在的列賦值會創(chuàng)建出一個新列宠页。關(guān)鍵字del用于刪除列

In [55]: frame2['eastern'] = frame2.state == 'Ohio'

In [56]: frame2
Out[56]: 
year state pop debt eastern
one 2000 Ohio 1.5 NaN True
two 2001 Ohio 1.7 -1.2 True
three 2002 Ohio 3.6 NaN True
four 2001 Nevada 2.4 -1.5 False
five 2002 Nevada 2.9 -1.7 False

In [57]: del frame2['eastern']

In [58]: frame2.columns
Out[58]: Index(['year', 'state', 'pop', 'debt'], dtype='object')

警告: 通過索引方式返回的列只是相應(yīng)數(shù)據(jù)的視圖而已,并不是副本寇仓。因此究驴,對返回的Series所做的任何就地修改全都會反映到源DataFrame上磺送。通過Series的copy方法即可顯式地復(fù)制列。
另一種常見的數(shù)據(jù)形式是嵌套字典(也就是字典的字典),如果將它傳給DataFrame,它就會被解釋為:外層字典的鍵作為列地粪,內(nèi)層鍵則作為行索引家制。

In [64]: pop = {'Nevada': {2001: 2.4, 2002: 2.9},'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
In [65]: frame3=DataFrame(pop)
In [66]: frame3
Out[66]: 
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6

對該結(jié)果進(jìn)行轉(zhuǎn)置

In [67]: frame3.T
Out[67]: 
2000 2001 2002
Nevada NaN 2.4 2.9
Ohio 1.5 1.7 3.6

內(nèi)層字典的鍵會被合并饼拍、排序以形成最終的索引渣磷。如果顯式指定了索引,則不會這樣

In [68]: DataFrame(pop, index=[2001, 2002, 2003])
Out[68]: 
Nevada Ohio
2001 2.4 1.7
2002 2.9 3.6
2003 NaN NaN

由Series組成的字典差不多也是一樣的用法

In [69]: pdata = {'Ohio': frame3['Ohio'][:-1],'Nevada': frame3['Nevada'][:2]}

In [70]: DataFrame(pdata)
Out[70]: 
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7

表5-1列出了DataFrame構(gòu)造函數(shù)所能接受的各種數(shù)據(jù)



如果設(shè)置了DataFrame的index和columns的name屬性罢猪,則這些信息也會被顯示出來

In [71]: frame3.index.name = 'year'; frame3.columns.name = 'state'
In [72]: frame3
Out[72]: 
state Nevada Ohio
year 
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6

跟Series一樣近她,values屬性也會以二維ndarray的形式返回DataFrame中的數(shù)據(jù)

In [73]: frame3.values
Out[73]: 
array([[ nan, 1.5],
[ 2.4, 1.7],
[ 2.9, 3.6]])

如果DataFrame各列的數(shù)據(jù)類型不同,則值數(shù)組的數(shù)據(jù)類型就會選用能兼容所有列的數(shù)據(jù)類型

In [74]: frame2.values
Out[74]: 
array([[2000, 'Ohio', 1.5, nan],
[2001, 'Ohio', 1.7, -1.2],
[2002, 'Ohio', 3.6, nan],
[2001, 'Nevada', 2.4, -1.5],
[2002, 'Nevada', 2.9, -1.7]], dtype=object)

索引對象
pandas的索引對象負(fù)責(zé)管理軸標(biāo)簽和其他元數(shù)據(jù)(比如軸名稱等)膳帕。構(gòu)建Series或DataFrame時粘捎,所用到的任何數(shù)組或其他序列的標(biāo)簽都會被轉(zhuǎn)換成一個Index:

In [75]: obj = Series(range(3), index=['a', 'b', 'c'])

In [76]: obj
Out[76]: 
a 0
b 1
c 2
dtype: int32

In [77]: index=obj.index

In [78]: index
Out[78]: Index(['a', 'b', 'c'], dtype='object')

In [79]: index[1:]
Out[79]: Index(['b', 'c'], dtype='object')

Index對象是不可修改的(immutable),因此用戶不能對其進(jìn)行修改

In [80]: index[1]='d'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-80-d3f90986bdb1> in <module>()
----> 1 index[1]='d'

C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in __setitem__(self, key, value)
1618 
1619 def __setitem__(self, key, value):
-> 1620 raise TypeError("Index does not support mutable operations")
1621 
1622 def __getitem__(self, key):

TypeError: Index does not support mutable operations

不可修改性非常重要危彩,因為這樣才能使Index對象在多個數(shù)據(jù)結(jié)構(gòu)之間安全共享

In [81]: index = pd.index(np.arange(3))
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-81-5eb0f1ff3872> in <module>()
----> 1 index = pd.index(np.arange(3))

AttributeError: module 'pandas' has no attribute 'index'

In [82]: index = pd.Index(np.arange(3))

In [83]: index
Out[83]: Int64Index([0, 1, 2], dtype='int64')

In [84]: obj2 = Series([1.5, -3.5, 0], index=index)

In [85]: obj2
Out[85]: 
0 1.5
1 -3.5
2 0.0
dtype: float64

In [86]: obj2.index is index
Out[86]: True

表5-2列出了pandas庫中內(nèi)置的Index類



除了長得像數(shù)組攒磨,Index的功能也類似一個固定大小的集合

In [87]: frame3
Out[87]: 
state Nevada Ohio
year 
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6

In [88]: 'Ohio' in frame3.columns
Out[88]: True

In [89]: 2003 in frame3.index
Out[89]: False

每個索引都有一些方法和屬性,它們可用于設(shè)置邏輯并回答有關(guān)該索引所包含的數(shù)據(jù)的常見問題汤徽。表5-3列出了這些函數(shù)娩缰。


pandas數(shù)據(jù)結(jié)構(gòu)的按照書本上進(jìn)行練習(xí),通過練習(xí)操作谒府,可以更好的懂著這些基本的數(shù)據(jù)結(jié)構(gòu)拼坎。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市完疫,隨后出現(xiàn)的幾起案子泰鸡,更是在濱河造成了極大的恐慌,老刑警劉巖趋惨,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸟顺,死亡現(xiàn)場離奇詭異,居然都是意外死亡器虾,警方通過查閱死者的電腦和手機讯嫂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兆沙,“玉大人欧芽,你說我怎么就攤上這事「鹌裕” “怎么了千扔?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長库正。 經(jīng)常有香客問我曲楚,道長,這世上最難降的妖魔是什么褥符? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任龙誊,我火速辦了婚禮,結(jié)果婚禮上喷楣,老公的妹妹穿的比我還像新娘趟大。我一直安慰自己,他們只是感情好铣焊,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布逊朽。 她就那樣靜靜地躺著,像睡著了一般曲伊。 火紅的嫁衣襯著肌膚如雪叽讳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天坟募,我揣著相機與錄音绽榛,去河邊找鬼。 笑死婿屹,一個胖子當(dāng)著我的面吹牛灭美,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昂利,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼届腐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蜂奸?” 一聲冷哼從身側(cè)響起犁苏,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扩所,沒想到半個月后围详,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年助赞,在試婚紗的時候發(fā)現(xiàn)自己被綠了买羞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡雹食,死狀恐怖畜普,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情群叶,我是刑警寧澤吃挑,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站街立,受9級特大地震影響舶衬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赎离,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一逛犹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蟹瘾,春花似錦圾浅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至众雷,卻和暖如春灸拍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背砾省。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工鸡岗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人编兄。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓轩性,卻偏偏與公主長得像,于是被迫代替她去往敵國和親狠鸳。 傳聞我的和親對象是個殘疾皇子揣苏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

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