pandas
是基于NumPy
构建的,含有使数据分析工作变得更快更简单的高级数据结构和操作工具。
from pandas import Series,DataFrame
import pandas as pd
pandas
的数据结构介绍
主要数据结构:Series
和DataFrame
Series:
是一种类似于一维数组的对象,它由一组数据(各种numpy
数据类型)以及一组与之相关的数据标签(即索引)组成。
仅由一组数据即可产生最简单的Series
:
In [32]: obj = Series([4, 7, -5, 3])
In [33]: obj
Out[33]:
0 4
1 7
2 -5
3 3
dtype: int64
Series
的字符串表现形式:索引在左边,值在右边;由于没有指定索引,会自动创建一个0
到N1
的整数型索引;
可以通过Series
的values
和index
属性获取其数组表示形式和索引对象:
In [34]: obj.values
Out[34]: array([ 4, 7, -5, 3])
In [35]: obj.index
Out[35]: RangeIndex(start=0, stop=4, step=1)
通常我们希望创建的Series
带有一个可以对各个数据点进行标记的索引:
In [36]: obj2 = Series([4, 7, -5, 3], index=['d','b','a','c'])
In [37]: obj2
Out[37]:
d 4
b 7
a -5
c 3
dtype: int64
In [38]: obj2.index
Out[38]: Index(['d', 'b', 'a', 'c'], dtype='object'
与普通numpy
数组相比,可以通过索引的方式选取Series
中的单个或一组值:
In [39]: obj2['a']
Out[39]: -5
In [41]: obj2[['c','a','d']]
Out[41]:
c 3
a -5
d 4
dtype: int64
numpy
数组运算都会保留索引和值之间的链接:
In [42]: obj2[obj2 > 0]
Out[42]:
d 4
b 7
c 3
dtype: int64
In [44]: np.exp(obj2)
Out[44]:
d 54.598150
b 1096.633158
a 0.006738
c 20.085537
dtype: float64
还可以将Series
看成是一个定长的有序字典,因为它是索引值到数据值的一个映射:
In [45]: 'b' in obj2 In [46]: 'a' in obj2 In [47]: 'e' in obj2
Out[45]: True Out[46]: True Out[47]: False
如果数据被存放在一个Python字典中,可直接通过字典创建Series
:
In [48]: sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah':5000}
In [49]: onj3 = Series(sdata)
In [50]: onj3
Out[50]:
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000
dtype: int64
而且,传入的字典的键就是Series
结果中的索引;
In [51]: states = ['California', 'Ohio', 'Oregon','Texas']
In [52]: obj4 = Series(sdata, index=states)
In [53]: obj4
Out[53]:
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64
sdata
中跟states
索引相匹配的值会被找出并放到相应位置,
NaN
(非数字,not a number)在pandas
中用于表示缺失(missing)或NA
值,
pandas
的isnull
和notnull
函数可用于检测缺失数据:
In [54]: pd.isnull(obj4)
Out[54]:
California True
Ohio False
Oregon False
Texas False
dtype: bool
In [55]: pd.notnull(obj4)
Out[55]:
California False
Ohio True
Oregon True
Texas True
dtype: bool
pandas
中还有类似的实例方法:
In [56]: obj4.isnull()
Out[56]:
California True
Ohio False
Oregon False
Texas False
dtype: bool
对于许多应用而言,Series
最重要的一个功能是:他在算数运算中会自动对齐不同索引的数据。
In [57]: onj3 In [58]: obj4
Out[57]: Out[58]:
Ohio 35000 California NaN
Oregon 16000 Ohio 35000.0
Texas 71000 Oregon 16000.0
Utah 5000 Texas 71000.0
dtype: int64 dtype: float64
In [59]: onj3 + obj4
Out[59]:
California NaN
Ohio 70000.0
Oregon 32000.0
Texas 142000.0
Utah NaN
dtype: float64
Series
对象本身及其索引都有一个name
属性,该属性跟pandas
其他的关键功能关系非常密切:
In [60]: obj4.name = 'population'
In [61]: obj4.index.name = 'state'
In [62]: obj4
Out[62]:
state
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
Name: population, dtype: float64
Series的索引可以通过赋值的方式就地修改:
In [63]: obj.index = ['Bob', 'Steve', 'Jeff’, 'Ryan']
In [64]: obj
Out[64]:
Bob 4
Steve 7
Jeff -5
Ryan 3
dtype: int64
DataFrame:
DataFrame
是一个表格型的数据结构,含有一组有序的列,每列可以是不同的值类型。既有行索引,也有列索引,可以被看做由Series
组成的字典。
构建DataFrame
:最常用的是直接传入一个由等长列表或NumPy
数组组成的字典:
In [3]: 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 [4]: frame = DataFrame(data)
结果DataFrame
会自动加上索引,且全部列会被有序排列:
In [5]: frame
Out[5]:
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
如果指定了列序列,则按照指定顺序排列:
In [6]: DataFrame(data, columns=['year', 'state', 'pop'])
Out[6]:
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
和Series
一样,如果传入的列在数据中找不到,就会产生NA
值:
In [9]: frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five'])
In [10]: frame2
Out[10]:
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
通过类似字典标记的方式或属性的方式,可以将DataFrame
的列获取为一个Series
(返回的Series
拥有原DataFrame
相同的索引,name
属性相应的被设置好):
In [11]: frame2['state']
Out[11]:
one Ohio
two Ohio
three Ohio
four Nevada
five Nevada
Name: state, dtype: object
列可以通过赋值的方式进行修改:
In [12]: frame2['debt'] = 18.5
In [13]: frame2
Out[13]:
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
将列表或数组赋值给某个列时,其长度必须跟DataFrame
的长度匹配;如果赋值的是一个Series
,就会精确匹配DataFrame
的索引,所有的空位都将被填上缺失值:
In [14]: val = Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
In [15]: frame2['debt'] = val
In [16]: frame2
Out[16]:
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
为不存在的列赋值会创建一个新的列;关键字del
用于删除列:
In [17]: frame2['eastern'] = frame2.state == 'Ohio'
In [18]: frame2
Out[18]:
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 [19]: del frame2['eastern']
In [20]: frame2
Out[20]:
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
!!!!:通过索引方式返回的列只是相应数据的视图而已,不是副本;因此,对返回的Series
做修改会反映到源数据上;
通过Series
的copy
方法可以显式地复制列。
如果将嵌套字典传给DataFrame
,会被解释为:外层字典的键作为列,内层键作为行索引:
内层字典的键会被合并、排序以形成最终的索引:
In [21]: pop = {'Nevada': {2001: 2.4, 2002: 2.9}, 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
In [22]: frame3 = DataFrame(pop)
In [23]: frame3
Out[23]:
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
DataFrame
构造函数能接受的数据类型:见#2109
如果设置了DataFrame
的index
和columns
的name
属性:
In [25]: frame3.index.name = 'year'; frame3.columns.name = 'state'
In [26]: frame3
Out[26]:
state Nevada Ohio
year
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
和Series
一样,values
属性也会以二维ndarray
的形式返回DataFrame
中的数据:
In [27]: frame3.values
Out[27]:
array([[ nan, 1.5],
[ 2.4, 1.7],
[ 2.9, 3.6]])
如果各列的数据类型不同,则值数组的数据类型就会选用能兼容所有列的数据类型:
In [28]: frame2.values
Out[28]:
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
的索引对象负责管理:轴标签,其他元数据(比如轴名称等);
构建Series
或DataFrame
时,所用到的任何数组或其他序列的标签都会被转换成一个Index
:
In [29]: obj = Series(range(3), index=['a', 'b', 'c'])
In [30]: index = obj.index
In [31]: index
Out[31]: Index(['a', 'b', 'c'], dtype='object')
index
对象是不可修改的(immutable):
不可修改性很重要,这样能够使Index
对象在多个数据结构之间安全共享:
In [35]: index = pd.Index(np.arange(3))
In [36]: obj2 = Series([1.5, -2.5, 0], index=index)
In [37]: obj2.index is index
Out[37]: True
Index
的功能类似一个固定大小的集合:
In [39]: frame3
Out[39]:
state Nevada Ohio
year
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
In [40]: 'Ohio' in frame3.columns
Out[40]: True
In [41]: 2003 in frame3.index
Out[41]: False
每个索引都有一些方法和属性,他们可用于设置逻辑并回答有关该索引所包含的数据的常见问题:
见#2139
基本功能:
(介绍操作Series
和DataFrame
中的数据的基本手段,常用的重要功能)
重新索引:
reindex
,创建一个适应新索引的新对象,即根据新索引进行重排;当前不存在值的索引引入缺失值:
In [42]: obj = Series([1, 2.4, 4.6, 7], index=['c', 'd', 'a', 'b'])
In [43]: obj
Out[43]:
c 1.0
d 2.4
a 4.6
b 7.0
dtype: float64
In [44]: obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
In [45]: obj2
Out[45]:
a 4.6
b 7.0
c 1.0
d 2.4
e NaN
dtype: float64
对于时间序列这样的有序数据,重新索引时可能需要做一些插值处理。
method
选项可以达到目的,例如ffill
可以实现前向值填充:
- ffill/pad:前向填充值;
- bfill/backfill:后项值填充;
In [46]: obj3 = Series(['blue', 'yellow', 'purple'], index=[0, 2, 4])
In [47]: obj3.reindex(range(6), method='ffill')
Out[47]:
0 blue
1 blue
2 yellow
3 yellow
4 purple
5 purple
dtype: object
对于DataFrame
,reindex
可以修改行索引、列或两个都修改。
如果只传入一个序列,则会重新索引行:
In [49]: frame = DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'], columns=['Ohio', 'Texas', 'California'])
In [50]: frame
Out[50]:
Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8
In [51]: frame2 = frame.reindex(['a', 'b', 'c', 'd'])
In [52]: frame2
Out[52]:
Ohio Texas California
a 0.0 1.0 2.0
b NaN NaN NaN
c 3.0 4.0 5.0
d 6.0 7.0 8.0
使用columns
关键字即可重新索引列:
In [53]: states = ['Texas', 'Utah', 'California']
In [54]: frame.reindex(columns=states)
Out[54]:
Texas Utah California
a 1 NaN 2
c 4 NaN 5
d 7 NaN 8
同时对行和列重新索引,插值只能按行应用(轴0),列不填充:
frame.reindex(index=['a', 'b', 'c', 'd'], columns=['Texas', 'Utah', 'Ca ...: lifornia'])
利用ix
的标签索引功能,重新索引任务可以变得更简洁:
In [58]: frame.ix[['a','b','c','d'], states]
Out[58]:
Texas Utah California
a 1.0 NaN 2.0
b NaN NaN NaN
c 4.0 NaN 5.0
d 7.0 NaN 8.0
reindex
函数的参数见#2176
丢弃指定轴上的项:
传入一个索引数组或列表即可,由于需要执行一些数据整理和集合逻辑,所以drop
方法返回的是一个在制定轴上删除了指定值的新对象:
In [60]: obj = Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
In [61]: new_obj = obj.drop('c')
In [62]: new_obj
Out[62]:
a 0.0
b 1.0
d 3.0
e 4.0
dtype: float64
In [63]: obj.drop(['d', 'c'])
Out[63]:
a 0.0
b 1.0
e 4.0
dtype: float64
对于DataFrame
,可以删除任意轴上的索引值:
In [64]: data = DataFrame(np.arange(16).reshape((4,4)), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['one', 'two
...: ', 'three', 'four'])
In [65]: data.drop(['Colorado', 'Ohio'])
Out[65]:
one two three four
Utah 8 9 10 11
New York 12 13 14 15
In [66]: data.drop('two', axis=1)
Out[66]:
one three four
Ohio 0 2 3
Colorado 4 6 7
Utah 8 10 11
New York 12 14 15
说明:
实际上axis = 1
,指的是沿着行求所有列的平均值,代表了横轴,那axis = 0
,就是沿着列求所有行的平均值,代表了纵轴。
那这样的话,drop
就是沿着'two'
的方向删除对应的轴标签为axis = 1
的值。
索引、选取和过滤:
Series
索引(obj[…]
)的工作方式类似于NumPy
数组的索引,只不过Series
的索引值不只是整数:
In [67]: obj = Series(np.arange(4.), index=['a', 'b', 'c', 'd'])
In [68]: obj[2:4]
Out[68]:
c 2.0
d 3.0
dtype: float64
In [69]: obj[['b', 'a', 'd']]
Out[69]:
b 1.0
a 0.0
d 3.0
dtype: float64
利用标签的切片运算与普通的Python切片运算不同,其末端是包含的(inclusive),即封闭区间:
In [70]: obj['b':'d']
Out[70]:
b 1.0
c 2.0
d 3.0
dtype: float64
设置的方式也很简单:
In [71]: obj['b':'c'] = 5
In [72]: obj
Out[72]:
a 0.0
b 5.0
c 5.0
d 3.0
dtype: float64
对DataFrame
进行索引其实就是获取一个或多个列:
In [73]: data
Out[73]:
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
In [74]: data[['one', 'three']]
Out[74]:
one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14
这种索引方式有几个特殊的情况:
- 通过切片或布尔型数组选取行:
In [76]: data[2:]
Out[76]:
one two three four
Utah 8 9 10 11
New York 12 13 14 15
n [77]: data[data['three'] > 5]
Out[77]:
one two three four
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
- 通过布尔型
DataFrame
进行索引:
In [78]: bool = data < 5
In [79]: bool
Out[79]:
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
In [80]: data[bool] = 0
In [81]: data
Out[81]:
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
索引字段ix
可以通过NumPy
式的标记法以及轴标签从DataFrame
中选取行和列的子集:
loc
获取行子集,iloc
通过行号获取,ix
综合两者:
In [84]: data.ix['Colorado', ['two', 'four']]
Out[84]:
two 5
four 7
Name: Colorado, dtype: int64
算术运算和数据对齐:
pandas
可以对不同索引的对象进行算术运算,如果存在不同的索引对,结果取并集:
自动对齐操作在不重叠的所引处引入NA
值。
In [87]: s1 = Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
In [88]: s2 = Series([-2.1, 3.6, -1.5, 4, 3.1], index=['a', 'c', 'e', 'f', 'g’])
In [89]: s1
Out[89]:
a 7.3
c -2.5
d 3.4
e 1.5
dtype: float64
In [90]: s2
Out[90]:
a -2.1
c 3.6
e -1.5
f 4.0
g 3.1
dtype: float64
In [91]: s1 + s2
Out[91]:
a 5.2
c 1.1
d NaN
e 0.0
f NaN
g NaN
dtype: float64
对于DataFrame
,对齐操作会同时发生在行和列上:
相加后会返回一个新的DataFrame
,其索引和列为原来的那两个DataFrame
的并集:
In [94]: df1 = DataFrame(np.arange(9).reshape((3,3)), columns=list('bcd'), index
...: =['Ohio', 'Texas', 'Colorado'])
In [95]: df2 = DataFrame(np.arange(12).reshape((4,3)), columns=list('bde'), inde
...: x=['Utah', 'Ohio', 'Texas', 'Oregon'])
In [96]: df1
Out[96]:
b c d
Ohio 0 1 2
Texas 3 4 5
Colorado 6 7 8
In [97]: df2
Out[97]:
b d e
Utah 0 1 2
Ohio 3 4 5
Texas 6 7 8
Oregon 9 10 11
In [98]: df1 + df2
Out[98]:
b c d e
Colorado NaN NaN NaN NaN
Ohio 3.0 NaN 6.0 NaN
Oregon NaN NaN NaN NaN
Texas 9.0 NaN 12.0 NaN
Utah NaN NaN NaN NaN
在算数方法中填充值:
在对不同索引的对象进行算术运算时,当一个对象中某个轴标签在另一个对象中找不到时填充一个特殊值:
使用df1
的add
方法(sub\div\mul
),传入df2
以及一个fill_value
参数
In [99]: df1 = DataFrame(np.arange(12.).reshape((3,4)), columns=list('abcd'))
In [100]: df2 = DataFrame(np.arange(20.).reshape((4,5)), columns=list('abcde'))
In [101]: df1
Out[101]:
a b c d
0 0.0 1.0 2.0 3.0
1 4.0 5.0 6.0 7.0
2 8.0 9.0 10.0 11.0
In [102]: df2
Out[102]:
a b c d e
0 0.0 1.0 2.0 3.0 4.0
1 5.0 6.0 7.0 8.0 9.0
2 10.0 11.0 12.0 13.0 14.0
3 15.0 16.0 17.0 18.0 19.0
In [103]: df1.add(df2, fill_value=0)
Out[103]:
a b c d e
0 0.0 2.0 4.0 6.0 4.0
1 9.0 11.0 13.0 15.0 9.0
2 18.0 20.0 22.0 24.0 14.0
3 15.0 16.0 17.0 18.0 19.0
DataFrame和Series之间的运算:
广播(broadcasting):
In [104]: arr = np.arange(12).reshape((3,4))
In [105]: arr
Out[105]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [106]: arr[0]
Out[106]: array([0, 1, 2, 3])
In [107]: arr - arr[0]
Out[107]:
array([[0, 0, 0, 0],
[4, 4, 4, 4],
[8, 8, 8, 8]])
默认情况下,DataFrame
和Series
之间的算术运算会将Series
的索引匹配到DataFrame
的列,然后沿着行一直向下广播:
In [108]: frame = DataFrame(np.arange(12).reshape((4,3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])
In [111]: series = frame.iloc[0]
In [112]: frame
Out[112]:
b d e
Utah 0 1 2
Ohio 3 4 5
Texas 6 7 8
Oregon 9 10 11
In [113]: series
Out[113]:
b 0
d 1
e 2
Name: Utah, dtype: int64
In [114]: frame - series
Out[114]:
b d e
Utah 0 0 0
Ohio 3 3 3
Texas 6 6 6
Oregon 9 9 9
如果某个索引值在DataFrame
的列或Series
的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集:
In [115]: series2 = Series(range(3), index=['b', 'e', 'f'])
In [116]: frame + series2
Out[116]:
b d e f
Utah 0.0 NaN 3.0 NaN
Ohio 3.0 NaN 6.0 NaN
Texas 6.0 NaN 9.0 NaN
Oregon 9.0 NaN 12.0 NaN
如果希望匹配行且在列上广播,则必须使用算术运算方法:
传入的轴号就是希望匹配的轴
In [117]: series3 = frame['d']
In [118]: frame
Out[118]:
b d e
Utah 0 1 2
Ohio 3 4 5
Texas 6 7 8
Oregon 9 10 11
In [119]: series3
Out[119]:
Utah 1
Ohio 4
Texas 7
Oregon 10
Name: d, dtype: int64
In [120]: frame.sub(series3, axis=0)
Out[120]:
b d e
Utah -1 0 1
Ohio -1 0 1
Texas -1 0 1
Oregon -1 0 1
函数应用和映射:
NumPy
的ufuncs
(元素级数组方法)也可用于操作pandas
对象:
In [122]: frame = DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah'
...: , 'Ohio', 'Texas', 'Oregon'])
In [123]: frame
Out[123]:
b d e
Utah 0.811566 1.357208 -0.603041
Ohio 0.149760 1.201341 -0.147990
Texas 1.040389 0.413789 1.399404
Oregon -0.553470 -0.666800 -0.463801
In [124]: np.abs(frame)
Out[124]:
b d e
Utah 0.811566 1.357208 0.603041
Ohio 0.149760 1.201341 0.147990
Texas 1.040389 0.413789 1.399404
Oregon 0.553470 0.666800 0.463801
另一个常见的操作是,将函数应用到由各列或行所形成的一维数组上;
DataFrame
的apply
方法即可实现此功能:
In [125]: f = lambda x:x.max() - x.min()
In [126]: frame.apply(f)
Out[126]:
b 1.593859
d 2.024008
e 2.002445
dtype: float64
In [128]: frame.apply(f, axis=1)
Out[128]:
Utah 1.960249
Ohio 1.349331
Texas 0.985615
Oregon 0.202998
dtype: float64
除了标量值外,传递给apply
的函数还可以返回由多个值组成的Series
:
In [129]: def f(x):
...: return Series([x.min(), x.max()], index=['min', 'max'])
...:
In [130]: frame.apply(f)
Out[130]:
b d e
min -0.553470 -0.666800 -0.603041
max 1.040389 1.357208 1.399404
此外,元素级的python函数也是可以用的。假如你想得到frame
中各个浮点值的格式化字符串,使用applymap
即可:
In [131]: format = lambda x: '%.2f' %x
In [132]: frame.applymap(format)
Out[132]:
b d e
Utah 0.81 1.36 -0.60
Ohio 0.15 1.20 -0.15
Texas 1.04 0.41 1.40
Oregon -0.55 -0.67 -0.46
之所以叫applymap
,是因为Series
有一个用于元素级函数的map
方法:
In [133]: frame['e'].map(format)
Out[133]:
Utah -0.60
Ohio -0.15
Texas 1.40
Oregon -0.46
Name: e, dtype: object
排序和排名:
根据条件对数据集排序(sorting)也是一种重要的内置运算。
对行或列索引进行排序(按字典顺序),可使用sort_index
方法,他将返回一个已排序的新对象:
In [134]: obj = Series(range(4), index=['d', 'a', 'b', 'c'])
In [135]: obj.sort_index()
Out[135]:
a 1
b 2
c 3
d 0
dtype: int64
而对于DtaFrame
,则可以根据任意一个轴上的索引进行排序:
In [136]: frame = DataFrame(np.arange(8).reshape((2, 4)), index=['three', 'one'], columns=['d', 'a', 'b', 'c'])
In [137]: frame.sort_index()
Out[137]:
d a b c
one 4 5 6 7
three 0 1 2 3
In [138]: frame.sort_index(axis=1)
Out[138]:
a b c d
three 1 2 3 0
one 5 6 7 4
数据默认是按升序排列的,也可以按降序排列:
In [140]: frame.sort_index(axis=1, ascending=False)
Out[140]:
d c b a
three 0 3 2 1
one 4 7 6 5
若要对Series
按值进行排序,sort_values
方法:
排序时任何缺失值默认都会放到末尾:
In [141]: obj = Series([4, 7, -3, 2])
In [145]: obj.sort_values()
Out[145]:
2 -3
3 2
0 4
1 7
dtype: int64
在DataFrame
上,根据一个或多个列中的值进行排序,将一个或多个列的名字传递给 by
选项:
In [146]: frame = DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
In [149]: frame.sort_values(by='b')
Out[149]:
a b
2 0 -3
3 1 2
0 0 4
1 1 7
根据多个列排序,传入名称的列表即可:
In [150]: frame.sort_values(by=['a', 'b'])
Out[150]:
a b
2 0 -3
0 0 4
3 1 2
1 1 7
排名(ranking)跟排序关系密切,且他会增设一个排名值(从1开始),它会根据某种规则破坏平级关系:
rank
方法,默认情况下rank
是通过“为各组分配一个平均排名”的方式破坏平级关系:
In [151]: obj = Series([7, -5, 7, 4, 2, 0, 4])
In [152]: obj.rank()
Out[152]:
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5
dtype: float64
也可以根据值在原数据中出现的顺序给出排名:
method = ‘average’/‘min’/‘max’/‘first’
:
In [154]: obj.rank(method='first')
Out[154]:
0 6.0
1 1.0
2 7.0
3 4.0
4 3.0
5 2.0
6 5.0
dtype: float64
In [155]: obj.rank(ascending=False, method='max')
Out[155]:
0 2.0
1 7.0
2 2.0
3 4.0
4 5.0
5 6.0
6 4.0
dtype: float64
DataFrame
可以在行或列上计算排名:
In [156]: frame = DataFrame({'b':[4.3, 7, -3, 2], 'a':[0, 1, 0, 1], 'c':[-2, 5, 8, -2.5]})
In [157]: frame
Out[157]:
a b c
0 0 4.3 -2.0
1 1 7.0 5.0
2 0 -3.0 8.0
3 1 2.0 -2.5
In [158]: frame.rank(axis=1)
Out[158]:
a b c
0 2.0 3.0 1.0
1 1.0 3.0 2.0
2 2.0 1.0 3.0
3 2.0 3.0 1.0
带有重复值的轴索引:
index
的 is_unique
属性可以告诉它的值是否唯一:
In [159]: obj = Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
In [160]: obj
Out[160]:
a 0
a 1
b 2
b 3
c 4
dtype: int64
In [161]: obj.index.is_unique
Out[161]: False
如果某个索引对应多个值,则返回一个Series;而对应单个值的,则返回一个标量值:
In [162]: obj['a']
Out[162]:
a 0
a 1
dtype: int64
In [163]: obj['c']
Out[163]: 4
对DataFrame
的行进行索引时也是如此:
In [164]: df = DataFrame(np.random.randn(4, 3), index=['a', 'a', 'b', 'b'])
In [165]: df
Out[165]:
0 1 2
a -0.418238 0.816369 -1.476190
a 0.429244 1.026073 -1.226708
b -0.545915 -0.924662 2.804594
b 0.325699 -0.584846 -1.192865
In [166]: df.loc['b']
Out[166]:
0 1 2
b -0.545915 -0.924662 2.804594
b 0.325699 -0.584846 -1.192865