一、排序和排名
排序分两种:根据索引排序和根据元素值排序。
根据索引排序使用的是sort_index方法,它返回一个新的排好序的对象:
In [103]: s = pd.Series(range(4),index = list('dabc')) In [104]: s Out[104]: d 0 a 1 b 2 c 3 dtype: int64 In [105]: s.sort_index() # 根据索引的字母序列排序
Out[105]: a 1 b 2 c 3 d 0 dtype: int64 In [108]: df = pd.DataFrame(np.random.randint(10,size=(4,3)), columns=list('edb'),index = ['two','one','five','four']) In [109]: df Out[109]: e d b two 7 6 1 one 5 6 8 five 8 4 1 four 7 0 3 In [110]: df.sort_index() # 默认按行索引排序,并以字母顺序
Out[110]: e d b five 8 4 1 four 7 0 3 one 5 6 8 two 7 6 1 In [111]: df.sort_index(axis=1) # 指定按列排序
Out[111]: b d e two 1 6 7 one 8 6 5 five 1 4 8 four 3 0 7 In [112]: df.sort_index(axis=1,ascending=False) # 默认升序,可以指定为倒序
Out[112]: e d b two 7 6 1 one 5 6 8 five 8 4 1 four 7 0 3
如果要根据某行或某列元素的值的大小进行排序,就要使用sort_values方法:
In [113]: s= pd.Series([4, 7,-3,2]) In [114]: s.sort_values() Out[114]: 2 -3
3 2 0 4
1 7 dtype: int64 # np.nan缺失值会自动排到最后
In [115]: s2 = pd.Series([4, np.nan,7,np.nan,-3,2]) In [116]: s2 Out[116]: 0 4.0
1 NaN 2 7.0
3 NaN 4 -3.0
5 2.0 dtype: float64 In [117]: s2.sort_values() Out[117]: 4 -3.0
5 2.0 0 4.0
2 7.0
1 NaN 3 NaN dtype: float64 In [118]: df2 = pd.DataFrame({'b':[4,7,-3,2], 'a':[0,1,0,1]}) In [120]: df2 Out[120]: b a 0 4 0 1 7 1
2 -3 0 3 2 1 In [121]: df2.sort_values(by='b') # 根据某一列里的元素值进行排序
Out[121]: b a 2 -3 0 3 2 1 0 4 0 1 7 1 In [122]: df2.sort_values(by=['a','b']) # 根据某些列进行排序
Out[122]: b a 2 -3 0 0 4 0 3 2 1
1 7 1
除了排序,还有排名。Pandas的排名规则不太好理解,其规则如下:
- 以升序排名为例
- 所有数中最小的数排为1.0
- 按数大小依此类推,2.0、3.0、4.0给安排位次
- 如果有重复的数,则重复的排名相加除以重复的个数,得出一个排名
- 重复的数后面的排名,接着排
比如下面的例子:
In [123]: s = pd.Series([7,-5,7,4,2,0,4]) In [124]: s.rank() Out[124]: 0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5 dtype: float64
- -5最小,给排名1.0
- 0其次,排2.0
- 2再次,排3.0
- 有2个4,于是4.0+5.0等于9,再除个数2,最终排名4.5。4.0和5.0两个排名并未使用。
- 又有2个7,于是6.0+7.0等于13,再除2,最后排名6.5
也可以根据观察顺序进行排名位次分配,主要是重复的数,按顺序先后给排名,揣摩一下就能明白规律:
In [125]: s.rank(method='first') Out[125]: 0 6.0
1 1.0
2 7.0
3 4.0
4 3.0
5 2.0
6 5.0 dtype: float64
还可以按最大值排名,并降序排列:
In [126]: s.rank(method='max',ascending=False) Out[126]: 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 [128]: df = pd.DataFrame(np.random.randint(-10,10,(4,3)),columns=list('abc')) In [129]: df Out[129]: a b c 0 -9 -1 -8
1 -10 8 -7
2 -4 2 6
3 9 -2 -7 In [130]: df.rank(axis='columns') Out[130]: a b c 0 1.0 3.0 2.0
1 1.0 3.0 2.0
2 1.0 2.0 3.0
3 3.0 2.0 1.0
下面列出了method参数可以使用的排名方法:
- average:默认方式,计算平均排名
- min:最小排名
- max:最大排名
- first:观察顺序排名
- dense:类似min,但组间排名总是增加1
二、统计和汇总
Pandas也有一套和Numpy类似的数学、统计学方法。不过在使用中要注意的是,Numpy通常将数组看作一个整体,而Pandas通常对列进行操作。当然,这两者也能单独对行进行操作。另外,Pandas内建了处理缺失值的功能,这一点是numpy不具备的。
In [131]: df = pd.DataFrame([[1.4, np.nan],[7.1,-4.2],[np.nan,np.nan],[0.75,-1.1]],index=list('abcd'),columns=['one','two']) In [132]: df Out[132]: one two a 1.40 NaN b 7.10 -4.2 c NaN NaN d 0.75 -1.1 In [133]: df.sum() # 默认对列进行求和,并返回一个Series对象,缺失值默认被忽略
Out[133]: one 9.25 two -5.30 dtype: float64 In [134]: df.sum(axis='columns') # 指定对行进行求和
Out[134]: a 1.40 b 2.90 c 0.00 d -0.35 dtype: float64 In [135]: df.mean(axis='columns', skipna=False) # 对行求平均值,但不忽略缺失值
Out[135]: a NaN b 1.450 c NaN d -0.175 dtype: float64
下面是主要的统计和汇总方法:
方法 | 描述 |
min | 最小值 |
max | 最大值 |
idxmin | 返回某行或某列最小值的索引 |
idxmax | 最大值的索引 |
cumsum | 累加 |
cumprod | 累乘 |
count | 统计非NaN的个数 |
describe | 汇总统计集合 |
quantile | 计算样本的从0到1间的分位数 |
sum | 求和 |
mean | 平均值 |
median | 中位数(50%) |
mad | 平均值的平均绝对偏差 |
prod | 所有值的积 |
var | 方差 |
std | 标案差 |
skew | 样本偏度,第三时刻值 |
kurt | 样本峰度,第四时刻值 |
diff | 计算第一个算术差值 |
pct_change | 计算百分比 |
In [136]: df.idxmax() Out[136]: one b two d dtype: object In [137]: df.idxmin() Out[137]: one d two b dtype: object In [138]: df.cumsum() Out[138]: one two a 1.40 NaN b 8.50 -4.2 c NaN NaN d 9.25 -5.3 In [139]: df.cumprod() Out[139]: one two a 1.400 NaN b 9.940 -4.20 c NaN NaN d 7.455 4.62 In [144]: df.count() Out[144]: one 3 two 2 dtype: int64
最重要的describe方法:
In [140]: df.describe() Out[140]: one two count 3.000000 2.000000 mean 3.083333 -2.650000 std 3.493685 2.192031 min 0.750000 -4.200000
25% 1.075000 -3.425000
50% 1.400000 -2.650000
75% 4.250000 -1.875000 max 7.100000 -1.100000 In [141]: s=pd.Series(list('aabc'*4)) In [143]: s.describe() # 对于非数值型,统计类型不一样
Out[143]: count 16 unique 3 top a freq 8 dtype: object
还有几个非常重要的方法:
- unique:计算唯一值数组,并按观察顺序返回
- value_counts:计数,并按多到少排序
- isin:判断是否包含成员
In [147]: s = pd.Series(list('cadaabbcc')) In [149]: uniques = s.unique() # 获取去重后的值 In [150]: uniques # 这是一个array数组
Out[150]: array(['c', 'a', 'd', 'b'], dtype=object) In [151]: s.value_counts() # 计数,默认从多到少排序
Out[151]: a 3 c 3 b 2 d 1 dtype: int64 In [152]: pd.value_counts(s, sort=False) # 也可以这么调用,并且不排序
Out[152]: d 1 c 3 a 3 b 2 dtype: int64 In [155]: mask = s.isin(['b','c']) # 判断Series的元素在不在b和c里面 In [156]: mask # 这是一个bool类型
Out[156]: 0 True 1 False 2 False 3 False 4 False 5 True 6 True 7 True 8 True dtype: bool In [157]: s[mask] Out[157]: 0 c 5 b 6 b 7 c 8 c dtype: object