利用python進行資料分析-pandas入門2
1.索引物件
pandas的索引物件負責管理軸標籤和其它元資料。構建Series或DataFrame時,所用到的任何陣列或其它序列的標籤都會被轉換成一個Index
obj=Series(range(3),index=['a','b','c'])
index=obj.index
print index
print index[1:]
結果為:
Index([u'a', u'b', u'c'], dtype='object')
Index([u'b', u'c'], dtype='object')
Index物件是不可修改的,因此使用者不能對其進行修改
不可修改性非常重要,因為這樣才能使Index物件在多個數據結構之間安全共享
index=pd.Index(np.arange(3))
obj2=Series([1.5,-2.5,0],index=index)
print obj2.index is index
結果為:
True
2.基本功能
a.重新索引
pandas物件的一個重要方法是reindex,其作用是建立一個適應新索引的新物件。呼叫該Series的reindex將會根據新索引進行重排,如果某個索引不存在,就引入缺失值
obj3=Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c'])
print obj3
obj4=obj3.reindex(['a','b','c','d','e'])
print obj4
print obj3.reindex(['a','b','c','d','e'],fill_value=0)
結果為:
d 4.5
b 7.2
a -5.3
c 3.6
dtype: float64
a -5.3
b 7.2
c 3.6
d 4.5
e NaN
dtype: float64
a -5.3
b 7.2
c 3.6
d 4.5
e 0.0
對於時間序列這樣的有序資料,重新索引時有可能需要做一些插值處理。method選項即可達到此目的,例如使用ffill可以實現前向值填充
obj5=Series(['blue','purple','yellow'],index=[0,2,4])
print obj5.reindex(range(6),method='ffill')
結果為:
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
dtype: object
對於DataFrame、reindex可以修改(行)索引、列,或兩個都修改。如果僅傳入一個序列,則會重新索引行
frame=DataFrame(np.arange(9).reshape(3,3),index=['a','c','d'],
columns=['Ohio','Texas','California'])
print frame
frame2=frame.reindex(['a','b','c','d'])
print frame2
結果為:
Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8
Ohio Texas California
a 0 1 2
b NaN NaN NaN
c 3 4 5
d 6 7 8
使用columns關鍵字即可重新索引列
states=['Texas','Utah','California']
print frame.reindex(columns=states)
結果為:
Texas Utah California
a 1 NaN 2
c 4 NaN 5
d 7 NaN 8
也可以同時對行和列進行重新索引,而插值則只能按行應用(即軸0)
print frame.reindex(index=['a','b','c','d'],method='ffill',columns=states)
結果為:
Texas Utah California
a 1 NaN 2
b 1 NaN 2
c 4 NaN 5
d 7 NaN 8
利用ix的標籤索引功能,重新索引任務可以變得更簡潔
print frame.ix[['a','b','c','d'],states]
結果為:
Texas Utah California
a 1 NaN 2
b NaN NaN NaN
c 4 NaN 5
d 7 NaN 8
b.丟棄指定軸上的項
丟棄某條軸上的一個或多個項很簡單,只要有一個索引陣列或列表即可。drop方法返回的是一個在指定軸上刪除了指定值的新物件
obj6=Series(np.arange(5),index=['a','b','c','d','e'])
new_obj=obj6.drop('c')
print new_obj
print obj6.drop(['a','b'])
結果為:
a 0
b 1
d 3
e 4
dtype: int32
c 2
d 3
e 4
dtype: int32
對於DataFrame,可以刪除任意軸上的索引值
data=DataFrame(np.arange(16).reshape(4,4),index=['Ohio','Colorado','Utah','New York'],
columns=['one','two','three','four'])
print data.drop(['Colorado','Ohio'])
print data.drop(['two','four'],axis=1)
結果為:
one two three four
Utah 8 9 10 11
New York 12 13 14 15
one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14
c.索引、選取和過濾
Series索引的工作方式類似於NumPy陣列的索引,只不過Series的索引值不只是整數
obj7=Series(np.arange(4),index=['a','b','c','d'])
print obj7['b']
print obj7[1]
print obj7[2:4]
print obj7[['b','a','d']]
print obj7[[1,3]]
結果為:
1
1
c 2
d 3
dtype: int32
b 1
a 0
d 3
dtype: int32
b 1
d 3
dtype: int32
利用標籤的切片與普通的Python切片運算不同,其末端是包含的
print obj7['b':'c']
結果為:
b 1
c 2
dtype: int32
對DataFrame進行索引其實就是獲取一個或多個列
data2=DataFrame(np.arange(16).reshape(4,4),index=['Ohio','Colorado','Utah','New York'],
columns=['one','two','three','four'])
print data2
print data2['two']
print data2[['three','one']]
結果為:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
Ohio 1
Colorado 5
Utah 9
New York 13
Name: two, dtype: int32
three one
Ohio 2 0
Colorado 6 4
Utah 10 8
New York 14 12
這種索引方式有幾個特殊的情況。首先通過切片或布林型陣列選取行
print data2[:2]
print data2[data2['three']>6]
結果為:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
one two three four
Utah 8 9 10 11
New York 12 13 14 15
另一種用法是通過布林型DataFrame進行索引
print data2<5
data2[data2<5]=0
print data2
結果為:
one two three four
Ohio True True True True
Colorado True False False False
Utah False False False False
New York False False False False
one two three four
Ohio 0 0 0 0
Colorado 0 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
為了在DataFrame的行上進行標籤索引,我引入了專門的索引欄位ix
print data2.ix['Colorado',['two','three']]
print data2.ix[['Colorado','Utah'],[3,0,1]]
print data2.ix[2]
print data2.ix[:'Utah','two']
print data2.ix[data2.three>5,:3]
結果為:
two 5
three 6
Name: Colorado, dtype: int32
four one two
Colorado 7 0 5
Utah 11 8 9
one 8
two 9
three 10
four 11
Name: Utah, dtype: int32
Ohio 0
Colorado 5
Utah 9
Name: two, dtype: int32
one two three
Colorado 0 5 6
Utah 8 9 10
New York 12 13 14
d.算術運算和資料對齊
在將物件相加時,如果存在不同的索引時,則結果的索引就是該索引對的並集
s1=Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e'])
s2=Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g'])
print s1
print s2
print s1+s2
結果為:
a 7.3
c -2.5
d 3.4
e 1.5
dtype: float64
a -2.1
c 3.6
e -1.5
f 4.0
g 3.1
dtype: float64
a 5.2
c 1.1
d NaN
e 0.0
f NaN
g NaN
dtype: float64
對於DataFrame,對齊操作會同時發生在行和列上
df1=DataFrame(np.arange(9).reshape(3,3),columns=list('bcd'),index=['Ohio','Texas','Colorado'])
df2=DataFrame(np.arange(12).reshape(4,3),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])
print df1
print df2
print df1+df2
結果為:
b c d
Ohio 0 1 2
Texas 3 4 5
Colorado 6 7 8
b d e
Utah 0 1 2
Ohio 3 4 5
Texas 6 7 8
Oregon 9 10 11
b c d e
Colorado NaN NaN NaN NaN
Ohio 3 NaN 6 NaN
Oregon NaN NaN NaN NaN
Texas 9 NaN 12 NaN
Utah NaN NaN NaN NaN
e.在算術方法中填充值
在對不同索引的物件進行算術運算時,可能希望當一個物件中某個軸標籤在另一個物件中找不到時填充一個特殊值(比如0)
df3=DataFrame(np.arange(12).reshape(3,4),columns=list('abcd'))
df4=DataFrame(np.arange(20).reshape(4,5),columns=list('abcde'))
print df3
print df4
print df3+df4
結果為:
a b c d
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
a b c d e
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
3 15 16 17 18 19
a b c d e
0 0 2 4 6 NaN
1 9 11 13 15 NaN
2 18 20 22 24 NaN
3 NaN NaN NaN NaN NaN
將他們相加時,沒有重疊的位置就會產生NA值;使用df3的add方法,傳入df4以及一個fill_value引數
print df3.add(df4,fill_value=0)
結果為:
a b c d e
0 0 2 4 6 4
1 9 11 13 15 9
2 18 20 22 24 14
3 15 16 17 18 19
與此類似,在對Series或DataFrame重新索引時,也可以指定一個填充值
print df3.reindex(columns=df4.columns,fill_value=0)
結果為:
a b c d e
0 0 1 2 3 0
1 4 5 6 7 0
2 8 9 10 11 0
f.DataFrame和Series之間的運算
預設情況下,DataFrame和Series之間的算術運算會將Series的索引匹配到DataFrame的列,然後沿著行一直向下廣播
frame=DataFrame(np.arange(12).reshape(4,3),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])
series=frame.ix[0]
print frame
print series
print frame-series
結果為:
b d e
Utah 0 1 2
Ohio 3 4 5
Texas 6 7 8
Oregon 9 10 11
b 0
d 1
e 2
Name: Utah, dtype: int32
b d e
Utah 0 0 0
Ohio 3 3 3
Texas 6 6 6
Oregon 9 9 9
如果某個索引值在DataFrame的列或Series的索引中找不到,則參與運算的兩個物件就會被重新索引以形成並集
series2=Series(range(3),index=['b','e','f'])
print frame+series2
結果為:
b d e f
Utah 0 NaN 3 NaN
Ohio 3 NaN 6 NaN
Texas 6 NaN 9 NaN
Oregon 9 NaN 12 NaN
如果希望匹配行且在列上廣播,必須使用算術運算子;傳入的軸號就是希望匹配的軸
series3=frame['d']
print frame.sub(series3,axis=0)
結果為:
b d e
Utah -1 0 1
Ohio -1 0 1
Texas -1 0 1
Oregon -1 0 1