前边学习了pandas的基本数据结构Series和DataFrame,以及重要的index。本次在前期学习的基础上继续学习其基本的功能,比如重新索引(reindex)或者说索引取值、向前/后填充、。。。。
重新索引
重新索引的方法是reindex,有点像np.reshape。不同点在于np.reshape可改变数据结构本身,而reindex则是新产生一个数据结构,原始数据结构并未改变。
Series.reindex([list]/(tuple))会根据定义的索引顺序进行数据的重新排列(实际为复制),若定义的索引值在Series里找不到对象则返回NaN,若希望返回特定的值可指定fill_value=***
obj=Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c'])
obj
Out[57]:
d 4.5
b 7.2
a -5.3
c 3.6
dtype: float64
obj.reindex(['a','b','d','c','e'])
Out[58]:
a -5.3
b 7.2
d 4.5
c 3.6
e NaN
dtype: float64
obj
Out[59]:
d 4.5
b 7.2
a -5.3
c 3.6
dtype: float64
obj.reindex(['a','b','d','c','e'],fill_value=0)
Out[60]:
a -5.3
b 7.2
d 4.5
c 3.6
e 0.0
dtype: float64
针对DataFrame有index和columns,reindex可对index/columns或二者同时重新索引,若不指定index和columns,只输入一个序列则默认重索引index,即轴0,也可以指定axis=0、1来指定index和columns。使用ix方法可使得重索引变得简单,不过ix方法可能会在新版本中被弃用。
frame=DataFrame(np.arange(9).reshape(3,3),index=('a','b','c'),columns=[1,2,3])
frame
Out[64]:
1 2 3
a 0 1 2
b 3 4 5
c 6 7 8
frame.reindex(index=['a','b'],columns=[1,2])
Out[65]:
1 2
a 0 1
b 3 4
frame.reindex(['a','b'])
Out[66]:
1 2 3
a 0 1 2
b 3 4 5
frame.ix[['a','b'],[1]]
Out[68]:
1
a 0
b 3
reindex方法还可以向前或前后填充数据,用method方法指定即可(method='ffill'或'pad',即前向填充,method='bfill'或'backfill',即后向填充)----此方法的作用主要就是补充缺失数据、复制数据源。
frame
Out[75]:
1 2 3
a 0 1 2
b 3 4 5
c 6 7 8
frame.reindex(index=['a','c','e'],method='ffill')
Out[76]:
1 2 3
a 0 1 2
c 6 7 8
e 6 7 8
reindex函数的参数有:
其中的copy默认为True,即如论如何都复制,若改为False,则新旧相等就不复制。这个特点在当重索引的内容没有变化时,新创建的指针和原始数据的指针都是同一份数据对象,通过任意一个指针进行对象的修改,都会导致其他指针数据的同步修改。
frame2=frame.reindex(index=['a','b','c'],columns=[1,2,3],copy=False)
frame
Out[84]:
1 2 3
a 10 1 2
b 3 4 5
c 6 7 8
frame2
Out[85]:
1 2 3
a 10 1 2
b 3 4 5
c 6 7 8
frame[1]['a']=0
frame
Out[87]:
1 2 3
a 0 1 2
b 3 4 5
c 6 7 8
frame2
Out[88]:
1 2 3
a 0 1 2
b 3 4 5
c 6 7 8
带有重复值的轴索引
重复值的轴索引,即索引index或columns的值有重复的,那么当指定重复值的索引时,返回的对象为Sreies或DataFrame,若指定的索引值非重复的,则对于Sreies来说返回的是一个标量值,对于DataFrame来说就是一行或一列值。
丢弃轴上的项
drop方法可丢弃指定位置的数据,如指定index=[list]或者columns=[list],也可以用axis=0/1来指定是index还是columns,当然同reindex重索引一样,drop方法也会产生一个新的对象,原始对象不会被修改。
frame.drop([1],axis=1)
Out[94]:
2 3
a 1 2
b 4 5
c 7 8
frame.drop(index=['a','b'])
Out[95]:
1 2 3
c 6 7 8
frame
Out[96]:
1 2 3
a 0 1 2
b 3 4 5
c 6 7 8
索引、选取和过滤
Series的索引,通常我们可指定index的具体对象可实现想要的对象选取,也可通过布尔值进行,但Series的索引可通过index切片索引、数值索引进行数据选取,非常的神奇。需要注意的是index的切片索引左右都是闭,而不是平常所认为的左闭右开。
obj=Series([4.5,7.2,-5.3,3.6],index=['a','b','c','d'])
obj
Out[100]:
a 4.5
b 7.2
c -5.3
d 3.6
dtype: float64
obj[:2]
Out[101]:
a 4.5
b 7.2
dtype: float64
obj['a':'c']
Out[102]:
a 4.5
b 7.2
c -5.3
dtype: float64
obj[['a','c']]
Out[103]:
a 4.5
c -5.3
dtype: float64
obj[obj>4]
Out[104]:
a 4.5
b 7.2
dtype: float64
DataFrame有这index和columns两个索引属性,DataFrame[list]默认是columns的索引,而类似于DataFrame[:2]这样的切片操作却是对index进行索引,个人认为这点不是很友好。当然DataFrame也支持布尔型的索引选取和赋值。
frame
Out[111]:
1 2 3
a 0 1 2
b 3 4 5
c 6 7 8
frame[1]
Out[112]:
a 0
b 3
c 6
Name: 1, dtype: int32
frame[:2]
Out[113]:
1 2 3
a 0 1 2
b 3 4 5
frame[frame>2]
Out[114]:
1 2 3
a NaN NaN NaN
b 3.0 4.0 5.0
c 6.0 7.0 8.0
frame>2
Out[115]:
1 2 3
a False False False
b True True True
c True True True
frame[frame>2]=10
frame
Out[117]:
1 2 3
a 0 1 2
b 10 10 10
c 10 10 10
DataFrame当然也支持想多维array一样的索引取值方式DataFrame[][],需要注意第一个[]是columns对象,第二是[]index对象,且只能定位至某一个数据位置,不能实现多行多列的选取
frame[0]['a']
Out[155]: 0
DataFrame的布尔索引还有一种特殊情况,可实现类似于excel的数据筛选功能,即:
frame[frame[2]<10]
Out[119]:
1 2 3
a 0 1 2
如上,我们筛选出了在第2列里,小于10的数据。OK假设这里我们通过正则表达式,进行布尔判断筛选,那么就实现了指定列的模糊查找功能,行也同样如此,不过行的索引结果有所不同。这个功能点非常的骚气。
frame
Out[131]:
0 1 2
a 0 1 2
b 3 4 5
c 6 7 8
frame[frame[1]==4]
Out[132]:
0 1 2
b 3 4 5
frame[frame[1]>=4]
Out[133]:
0 1 2
b 3 4 5
c 6 7 8
frame[frame[1:2]==4]
Out[134]:
0 1 2
a NaN NaN NaN
b NaN 4.0 NaN
c NaN NaN NaN
frame[frame[1:2]>=4]
Out[135]:
0 1 2
a NaN NaN NaN
b NaN 4.0 5.0
c NaN NaN NaN
DataFrame的索引选取除了以上几种方式外,还有DataFrame.loc、DataFrame.iloc[]、DataFrame.ix[]、DataFrame.at[]、DataFrame.iat[]、DataFrame.getvalue[]、DataFrame.setvalue[]、DataFrame.reindex[]等方式。
其中DataFrame.loc、DataFrame.iloc[]、DataFrame.ix[]为某一块区域的选取,选取区域为一列时是Series对象,多列时是DataFrame对象。
而DataFrame.at[]、DataFrame.iat[]为某一数据位置的选取。其选取后的数据对象为numpy对象,如 numpy.int32
DataFrame.loc[]
其对象为二维对象,先行后列
行维度/列维度:标签的索引、切片、列表、布尔
DataFrame.iloc[]
其对象为二维对象,先行后列
行维度/列维度:数值的索引、切片、列表、布尔
DataFrame.ix[]
其对象为二维对象,先行后列
行维度/列维度:数值或标签的索引、切片、列表、布尔
frame.loc[['a','b'],[0,1]]
Out[173]:
0 1
a 0 1
b 3 4
frame.iloc[[0,1],[0,1]]
Out[174]:
0 1
a 0 1
b 3 4
frame.iloc[:,[0,1]]
Out[175]:
0 1
a 0 1
b 3 4
c 6 7
frame.ix[:,[0,1]]
Out[176]:
0 1
a 0 1
b 3 4
c 6 7
DataFrame.at[]
其对象为一维对象,先行后列
行维度/列维度:标签的索引
DataFrame.iat[]
其对象为一维对象,先行后列
行维度/列维度:数值的索引
frame.at['a',0]
Out[177]: 0
frame.iat[0,0]
Out[178]: 0