pandas学习笔记1:核心函数。

一、重建索引(Reindex)

1
2
obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj
d    4.5
b    7.2
a   -5.3
c    3.6
dtype: float64

对Series对象应用reindex函数后,将按参数指定的新索引进行重建数据,索引对应的数据如果本来不存在,那么会引进缺失值(NaN)。

1
2
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
obj2
a   -5.3
b    7.2
c    3.6
d    4.5
e    NaN
dtype: float64

与时间序列(Time Series)的有序数据类似,Series可以在重建索引时,method选项可以指定中间数据填充的模式。举例,method选项指定为ffill,会向前填充中间原不存在的数据。

1
2
obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
obj3
0      blue
2    purple
4    yellow
dtype: object
1
obj3.reindex(range(6), method='ffill')  #重建索引后,原索引标签中间原先没有的标签对应的数据则会根据前面的数据往前填充。
0      blue
1      blue
2    purple
3    purple
4    yellow
5    yellow
dtype: object

对DataFrame来说,reindex函数可以调整行或列或者两者。若只传入一个序列,则只重建行索引。

1
2
frame = pd.DataFrame(np.arange(9).reshape((3, 3)),index=['a', 'c', 'd'],columns=['Ohio', 'Texas', 'California'])
frame































Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8

1
2
frame2 = frame.reindex(['a', 'b', 'c', 'd'])  #只重建行
frame2





































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关键字,可调整列索引。

1
2
states = ['Texas', 'Utah', 'California']
frame.reindex(columns=states)































Texas Utah California
a 1 NaN 2
c 4 NaN 5
d 7 NaN 8

同时调整行和列,使用loc方法会使语义更加明确。

1
frame.loc[['a', 'b', 'c', 'd'], states]





































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函数参数选项

参数 说明
index 指定一个序列作为调整后的序列。可以是Index对象或其他python类序列
method 间行填充方法, ‘ffill’向前填充,’bfill’向后填充.
fill_value 缺失值填充值
limit 填充时,填充间行的最大数
tolerance 填充时,不准确匹配时,填充间行的最大数
level 多重索引的层次中匹配简单索引,否则选择其子集
copy 是否拷贝原索引数据,如果新索引与老索引相等

二、使用drop函数从一条轴上删除元素

1.删除Series中的元素

1
2
3
4
import numpy as np
import pandas as pd
obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
obj
a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64
1
2
new_obj = obj.drop('c')  #删掉索引为c的元素
new_obj
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64
1
obj
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64
1
obj.drop(['d', 'c']) #删除d、c两个元素
a    0.0
b    1.0
e    4.0
dtype: float64

2.指定轴删除DataFrame的行或列

1
2
data = pd.DataFrame(np.arange(16).reshape((4, 4)),index=['Ohio', 'Colorado', 'Utah', 'New York'],columns=['one', 'two', 'three', 'four'])
data










































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

1
data.drop(['Colorado', 'Ohio']) #沿0轴(行)删除,即根据行的索引删除行




























one two three four
Utah 8 9 10 11
New York 12 13 14 15

1
data.drop('two', axis=1)  #沿1轴(列)删除,跟根据列的标签删除指定列





































one three four
Ohio 0 2 3
Colorado 4 6 7
Utah 8 10 11
New York 12 14 15

1
data.drop(['two', 'four'], axis='columns')  #axis参数可以指定为columns,与指定为1作用相同。
































one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14

1
obj
a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64
1
2
obj.drop('c', inplace=True)  #就地修改原对象,使用inplace参数需小心,因为被删掉的元素都被销毁了。
obj
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64

三、索引、选择、筛选

对Series索引操作

1
2
obj = pd.Series(np.arange(4.), index=['a', 'b', 'c', 'd'])
obj
a    0.0
b    1.0
c    2.0
d    3.0
dtype: float64
1
obj['b'] #按照索引标签定位对象
1.0
1
obj[1] #也可以按照位置进行索引
1.0
1
obj[2:4] #切片
c    2.0
d    3.0
dtype: float64
1
obj[['b', 'a', 'd']] #多个索引标签
b    1.0
a    0.0
d    3.0
dtype: float64
1
obj[[1, 3]]  #多个索引位置
b    1.0
d    3.0
dtype: float64
1
obj[obj < 2]  #使用条件表达式
a    0.0
b    1.0
dtype: float64

Series使用索引标签切片与普通Numpy切片不同之处是Series切片时最后的元素是包含在内的。

1
obj['b':'c']
b    1.0
c    2.0
dtype: float64

使用切片表达式对多个元素进行赋值

1
2
obj['b':'c'] = 5
obj
a    0.0
b    5.0
c    5.0
d    3.0
dtype: float64

对DataFrame的切片、索引操作生成一列或多列元素。

1
2
data = pd.DataFrame(np.arange(16).reshape((4, 4)),index=['Ohio', 'Colorado', 'Utah', 'New York'],columns=['one', 'two', 'three', 'four'])
data










































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

使用列标签进行索引,得到对应的列

1
data['two']
Ohio         1
Colorado     5
Utah         9
New York    13
Name: two, dtype: int32
1
data[['three', 'one']]
































three one
Ohio 2 0
Colorado 6 4
Utah 10 8
New York 14 12

行选择

1
data[:2]  #行选择的简便形式




























one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7

1
data[data['three'] > 5]  #逻辑表达式,选择行



































one two three four
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15

使用布尔DataFrame进行选择,用法与Numpy的二维数组是类似的。

1
data < 5










































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

1
2
data[data < 5] = 0  #小于5的元素赋值为0
data










































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

使用loc或iloc进行行选择

loc是用索引标签进行行选择,iloc使用整数索引进行行选择。

1
data.loc['Colorado', ['two', 'three']] #选择Colorado行的two和three这两列的对应元素
two      5
three    6
Name: Colorado, dtype: int32
1
data.iloc[2, [3, 0, 1]]   #选择第3行的four、one、two这三列的对应元素
four    11
one      8
two      9
Name: Utah, dtype: int32
1
data.iloc[2] #第三行
one       8
two       9
three    10
four     11
Name: Utah, dtype: int32
1
data.iloc[[1, 2], [3, 0, 1]] #第2、3行的第4、1、2列的对应元素

























four one two
Colorado 7 0 5
Utah 11 8 9

上面的对一个或多个标签进行的索引的方法也可应用于切片

1
data.loc[:'Utah', 'two'] #Utah行之前的行的two列元素
Ohio        0
Colorado    5
Utah        9
Name: two, dtype: int32
1
data.iloc[:, :3][data.three > 5] #先选择所有的行,前3列,再使用逻辑表达式筛选































one two three
Colorado 0 5 6
Utah 8 9 10
New York 12 13 14

DataFrame的索引类型

类型 说明
df[val] 选择单列或多列,特殊用法:布尔值数组,切片,布尔值DataFrame
df.loc[val] 根据标签选择行
df.loc[:, val] 根据标签选择列
df.loc[val1, val2] 同时选择行、列
df.iloc[where] 根据整数位置选择行
df.iloc[:, where] 根据整数位置选择列
df.iloc[where_i, where_j] 根据整数位置同时选择行、列
df.at[label_i, label_j] 根据行、列标签选择一个标量值
df.iat[i, j] 根据整数位置选择标量值
reindex 根据行、列标签选择
get_value, set_value 根据行列标签读取值或赋值

四、整数索引产生的问题

1
2
ser = pd.Series(np.arange(3.))  #不适用索引标签,索引缺省为整数序列
ser
0    0.0
1    1.0
2    2.0
dtype: float64
1
ser[2]  #因为是整数标签,使用的是pandas Series中的索引对象进行索引。2是索引对象[0,1,2]中的元素,所以能正常读取。
2.0

没有标签的情况下,使用整数位置索引,用-1取最后一个数,产生错误。因为Ser中的索引为整数0,1,2,没有-1。在python的内建索引机制中,-1是取最后一个数,而pandas是按照其索引对象来定位的,所以python内建的索引机制与pandas的索引机制在这里产生了混淆。

1
ser[-1]   # Series索引对象[0,1,2]中不包含-1,因此出错。
---------------------------------------------------------------------------

KeyError                                  Traceback (most recent call last)

<ipython-input-60-3cbe0b873a9e> in <module>()
----> 1 ser[-1]


D:\Anaconda3\lib\site-packages\pandas\core\series.py in __getitem__(self, key)
    599         key = com._apply_if_callable(key, self)
    600         try:
--> 601             result = self.index.get_value(self, key)
    602 
    603             if not is_scalar(result):


D:\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in get_value(self, series, key)
   2475         try:
   2476             return self._engine.get_value(s, k,
-> 2477                                           tz=getattr(series.dtype, 'tz', None))
   2478         except KeyError as e1:
   2479             if len(self) > 0 and self.inferred_type in ['integer', 'boolean']:


pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_value()


pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_value()


pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()


pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()


pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()


KeyError: -1
1
ser2 = pd.Series(np.arange(3.), index=['a', 'b', 'c'])

使用标签的Series,因为Series的索引对象不是整数,因此使用整数索引时不会产生混淆,只可能用python内建索引机制进行选择,选择是最后一个元素。所以,为避免索引对象的混淆,使用索引标签是推荐行为。

1
ser2[-1]   #与ser不同,这里是python内建索引机制,因此-1是读取最后一个数
2.0
1
ser[:1]  #同样,切片操作也是面向标签的。所以,因为Ser是整数索引,没有索引标签,所以这里选择的Series的整数标签行,而不是python的内建索引机制。
0    0.0
dtype: float64
1
ser.loc[:1]  #如果用pandas的loc函数,则选择对象的意义很明确,loc函数的结果包含最后的数的
0    0.0
1    1.0
dtype: float64

五、数学运算与数据对齐

pandas的一个重要特性是两个不同索引的对象进行数学运算会如何表现。如,这两个对象的索引不同,讲这两个对象相加,如果索引对不相同,那么结果对象的索引是参加运算的两个对象的索引的并集。如果你对数据库熟悉的话,则可以理解成索引标签的outer连接。

1
2
s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
s1
a    7.3
c   -2.5
d    3.4
e    1.5
dtype: float64
1
2
s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],index=['a', 'c', 'e', 'f', 'g'])
s2
a   -2.1
c    3.6
e   -1.5
f    4.0
g    3.1
dtype: float64
1
s1 + s2  #索引标签d只在s1中,f、g只在s2中,结果是两个合集
a    5.2
c    1.1
d    NaN
e    0.0
f    NaN
g    NaN
dtype: float64

对DataFrame来说,行和列两个方向都要对齐

1
2
df1 = pd.DataFrame(np.arange(9.).reshape((3, 3)), columns=list('bcd'),index=['Ohio', 'Texas', 'Colorado'])
df1































b c d
Ohio 0.0 1.0 2.0
Texas 3.0 4.0 5.0
Colorado 6.0 7.0 8.0

1
2
df2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),index=['Utah', 'Ohio', 'Texas', 'Oregon'])
df2





































b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0

1
df1 + df2   #两者之和,只在索引标签和列标签并集的位置数值相加,其他位置都是NaN

















































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

所以,如果两个DataFrame没有共同的索引标签或行标签,加(减)运算的结果将全为NaN。

1
2
3

df1 = pd.DataFrame({'A': [1, 2]})
df1



















A
0 1
1 2

1
2
df2 = pd.DataFrame({'B': [3, 4]})
df2



















B
0 3
1 4

1
df1 - df2  #两者没有共同的列,所以所有的数值都是NaN






















A B
0 NaN NaN
1 NaN NaN

以填充数值进行算数运算

对不同索引的对象进行算数运算,如果一个对象轴中的数据在另一个对象中找不到对应的标签,可以指定填充值进行填充。

1
2
df1 = pd.DataFrame(np.arange(12.).reshape((3, 4)),columns=list('abcd'))
df1



































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

1
2
3
df2 = pd.DataFrame(np.arange(20.).reshape((4, 5)),columns=list('abcde'))
df2.loc[1, 'b'] = np.nan #df2的1行b列有一个数值缺失。
df2















































a b c d e
0 0.0 1.0 2.0 3.0 4.0
1 5.0 NaN 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

1
df1 + df2   #缺失值的计算仍是缺失值















































a b c d e
0 0.0 2.0 4.0 6.0 NaN
1 9.0 NaN 13.0 15.0 NaN
2 18.0 20.0 22.0 24.0 NaN
3 NaN NaN NaN NaN NaN

1
df1.add(df2, fill_value=0) #对df1和df2中的缺失值指定为0,然后再计算。















































a b c d e
0 0.0 2.0 4.0 6.0 4.0
1 9.0 5.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

对于Series和DataFrame的Reindex函数,也可以指定缺失填充值

1
df1.reindex(columns=df2.columns, fill_value=0) #对df1使用df2的列名重新创建索引,缺失的列填充为0.







































a b c d e
0 0.0 1.0 2.0 3.0 0
1 4.0 5.0 6.0 7.0 0
2 8.0 9.0 10.0 11.0 0

灵活的算数运算函数

函数 描述
add, radd 相加,radd是把对象翻为右参数,下同
sub, rsub 相减
div, rdiv 相除
floordiv, rfloordiv 地板除(//)
mul, rmul 乘法
pow, rpow 指数
1
1 / df1



































a b c d
0 inf 1.000000 0.500000 0.333333
1 0.250000 0.200000 0.166667 0.142857
2 0.125000 0.111111 0.100000 0.090909

1
df1.rdiv(1)  #df1.rdiv(1)与1/df1等价。



































a b c d
0 inf 1.000000 0.500000 0.333333
1 0.250000 0.200000 0.166667 0.142857
2 0.125000 0.111111 0.100000 0.090909

DateFrame和Series之间的运算

与numpy支持不同维度的数组之间的运算类似,pandas也支持DataFrame和Series之间的运算。

1
2
arr = np.arange(12.).reshape((3, 4))
arr
array([[  0.,   1.,   2.,   3.],
       [  4.,   5.,   6.,   7.],
       [  8.,   9.,  10.,  11.]])
1
arr[0]
array([ 0.,  1.,  2.,  3.])
1
arr - arr[0]  #DataFrame与其第一行的差
array([[ 0.,  0.,  0.,  0.],
       [ 4.,  4.,  4.,  4.],
       [ 8.,  8.,  8.,  8.]])

上例中,Numpy数组的每一行都会减去第一行,而不是只是第一行参加运算。这就是广播(broadcasting)。在pandas中,也有类似广播模式。

1
2
frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),columns=list('bde'),index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame





































b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0

1
2
series = frame.iloc[0]
series
b    0.0
d    1.0
e    2.0
Name: Utah, dtype: float64
1
frame - series





































b d e
Utah 0.0 0.0 0.0
Ohio 3.0 3.0 3.0
Texas 6.0 6.0 6.0
Oregon 9.0 9.0 9.0

缺省状况下,DataFrame与Series的差是以Series的索引去匹配DataFrame的列,逐行广播运算。
如果一个索引的值在DataFrame列中或Series索引之一中不存在,那么结果对象会合并DataFrame列名及Series索引名以重建为新的索引。

1
2
series2 = pd.Series(range(3), index=['b', 'e', 'f'])
frame + series2










































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

如果想要改变上述缺省行为,想要DataFrame按列广播,在行上进行匹配,那么可以用算数函数,并指定轴参数加以改变。

1
2
series3 = frame['d']
series3
Utah       1.0
Ohio       4.0
Texas      7.0
Oregon    10.0
Name: d, dtype: float64
1
frame





































b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0

1
frame.sub(series3, axis='index')  #指定按列进行运算并广播运算。





































b d e
Utah -1.0 0.0 1.0
Ohio -1.0 0.0 1.0
Texas -1.0 0.0 1.0
Oregon -1.0 0.0 1.0

六、函数应用及映射

numpy通用函数同样使用于pandas。

1
2
frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'),index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame





































b d e
Utah -0.058971 0.962351 0.886096
Ohio -1.397272 -0.207003 0.198786
Texas -0.293349 0.303266 -0.037189
Oregon -1.263869 0.745421 -1.587822

1
np.abs(frame) #求绝对值





































b d e
Utah 0.058971 0.962351 0.886096
Ohio 1.397272 0.207003 0.198786
Texas 0.293349 0.303266 0.037189
Oregon 1.263869 0.745421 1.587822

另外一个常用的操作是在一维数组上应用的函数可以应用到每一行或每一列。DataFrame的apply方法的具体用法:

1
2
f = lambda x: x.max() - x.min()   
frame.apply(f) #缺省情况下,对每一列应用f函数,返回结果是以列名为索引名的Series对象。
b    1.338300
d    1.169354
e    2.473918
dtype: float64

如果指定axis=column参数,则可按行应用f函数:

1
frame.apply(f, axis='columns')
Utah      1.021322
Ohio      1.596058
Texas     0.596615
Oregon    2.333243
dtype: float64

大部分普通的数组统计函数(如sum和mean)都是DataFrame函数,因此apply函数并无使用的必要。
传递给apply的函数并非一定要返回一个标量,它也可以返回一个Series对象,即可返回一组值。

1
2
3
def f(x):
return pd.Series([x.min(), x.max()], index=['min', 'max'])
frame.apply(f)

























b d e
min -1.397272 -0.207003 -1.587822
max -0.058971 0.962351 0.886096

元素智能(element-wise)函数也可以应用在此。比如,要对DataFrame对象的每一个元素按格式字符串格式化,可以如下例这样使用applymap函数:

1
2
format = lambda x: '%.2f' % x #保留两位小数的格式化字符串
frame.applymap(format)





































b d e
Utah -0.06 0.96 0.89
Ohio -1.40 -0.21 0.20
Texas -0.29 0.30 -0.04
Oregon -1.26 0.75 -1.59

applymap函数名称的由来是因为Series有一个对应的map函数:

1
frame['e'].map(format)
Utah       0.89
Ohio       0.20
Texas     -0.04
Oregon    -1.59
Name: e, dtype: object

七、排序

按照某个标准对数据集进行排序是另一个重要的内建操作。按照行名或列名的词义进行排序使用sort_index函数,其返回结果为一个新的排好序的对象。

1
2
obj = pd.Series(range(4), index=['d', 'a', 'b', 'c'])
obj.sort_index()
a    1
b    2
c    3
d    0
dtype: int32
1
frame = pd.DataFrame(np.arange(8).reshape((2, 4)),index=['three', 'one'],columns=['d', 'a', 'b', 'c'])
1
frame.sort_index()  #缺省,按行排序




























d a b c
one 4 5 6 7
three 0 1 2 3

1
frame.sort_index(axis=1)  #也可以使用axis=1参数按列进行排序




























a b c d
three 1 2 3 0
one 5 6 7 4

1
frame.sort_index(axis=1, ascending=False) #也可以降序排序




























d c b a
three 0 3 2 1
one 4 7 6 5

对Series对象,可以使用sort_vlues对数值进行排序,而不是按照索引的顺序。

1
2
obj = pd.Series([4, 7, -3, 2])
obj.sort_values()
2   -3
3    2
0    4
1    7
dtype: int64

缺值的位置排到后面。

1
2
obj = pd.Series([4, np.nan, 7, np.nan, -3, 2])
obj.sort_values()
4   -3.0
5    2.0
0    4.0
2    7.0
1    NaN
3    NaN
dtype: float64

对DataFrame按值排序,可以指定一列或多列作为排序的关键字。

1
2
frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
frame
































a b
0 0 4
1 1 7
2 0 -3
3 1 2

1
frame.sort_values(by='b') #b列作为排序关键字
































a b
2 0 -3
3 1 2
0 0 4
1 1 7

1
frame.sort_values(by=['a', 'b']) #a列为主关键字,b列为次关键字
































a b
2 0 -3
0 0 4
3 1 2
1 1 7

Ranking排名

rank函数返回从小到大排序的下标,即给予每个数值排序后所在的位置和名次。对于平级的数,rank是通过“为各组分配一个平均排名”的方式破坏评级关系。

1
2
obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
obj.rank()
0    6.5
1    1.0
2    6.5
3    4.5
4    3.0
5    2.0
6    4.5
dtype: float64

对于平级的数,也可以不使用平均排名的办法,而是可以使用位置在前面的数的排名就靠前。
向下面的列子,对0和2这两个位置的数,虽然平级,但是给予位置0的数的评级为6.0,位置2的数的评级为7.0,而不是6.5,因为使用的首次相遇策略。

1
obj.rank(method='first')
0    6.0
1    1.0
2    7.0
3    4.0
4    3.0
5    2.0
6    5.0
dtype: float64

也可以降序排列,相同评级使用最大数。

1
obj.rank(ascending=False, method='max')
0    2.0
1    7.0
2    2.0
3    4.0
4    5.0
5    6.0
6    4.0
dtype: float64

数值相等的元素分组的评级计算方法:

方法 说明
‘average’ 缺省:对组内元素赋值平均值
‘min’ 对分组内元素都使用最小值
‘max’ 对分组内元素都是用最大值
‘first’ 使用数值在数据中出现的顺序
‘dense’ 与’min’类似,但是组间评级依次加1
1
obj.rank(method='dense')   #稠密模式,评级依次加1,中间无空值
0    5.0
1    1.0
2    5.0
3    4.0
4    3.0
5    2.0
6    4.0
dtype: float64
1
obj.rank(method='min')  #排名中间可能有空值,该例子没有5
0    6.0
1    1.0
2    6.0
3    4.0
4    3.0
5    2.0
6    4.0
dtype: float64

DataFrame的数值排名可以按行或列

1
2
frame = pd.DataFrame({'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1],'c': [-2, 5, 8, -2.5]})
frame





































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

1
frame.rank(axis='columns')





































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

八、重复标签的索引

上面的例子中,DataFrame的索引标签都是唯一的。很多pandas函数(如reindex)要求索引标签是唯一的,但这不是强制的。我们来看一个重复索引标签的Series的例子:

1
2
obj = pd.Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
obj
a    0
a    1
b    2
b    3
c    4
dtype: int32

index对象的is_unique属性可以告诉你索引标签是否是唯一的:

1
obj.index.is_unique
False

索引标签是否唯一影响数据选取的结果。如果索引标签对应多条数据,那么选取结果为Series对象,否则为一个标量。

1
obj['a']
a    0
a    1
dtype: int32
1
obj['c']
4

这样的结果会使代码变得复杂,因为根据索引标签是否唯一得到的结果可能不是一种类型。这对DataFrame也是一样的。

1
2
df = pd.DataFrame(np.random.randn(4, 3), index=['a', 'a', 'b', 'b'])
df





































0 1 2
a -0.290790 -0.402699 1.277095
a 0.785005 2.835915 -0.318999
b -0.141299 -2.397378 -0.010815
b -1.472500 1.807394 -2.828368

1
df.loc['b']

























0 1 2
b -0.141299 -2.397378 -0.010815
b -1.472500 1.807394 -2.828368