1. 问题
在做数据挖掘过程中,有时需要做一些数据聚合后的统计特征,如求最大值,均值,中位数等等,这些都可以通过将主键进行groupby,然后直接使用max(),mean(),median()等方法。但是当想要求聚合后的众数(mode),却发现出现错误,通过dir(df.groupby('a'))指令查看并没有该方法。故不能直接使用df.groupby('a').mode().reset_index()
In [1]: import pandas as pd
In [2]: df = pd.DataFrame({'a':['A','A','A','A','B','B','B','B
...: ','B'],'b':[1,1,2,3,1,2,2,3,3]})
In [3]: df
Out[3]:
a b
0 A 1
1 A 1
2 A 2
3 A 3
4 B 1
5 B 2
6 B 2
7 B 3
8 B 3
In [4]: df.groupby('a').max().reset_index()
Out[4]:
a b
0 A 3
1 B 3
In [5]: df.groupby('a').mode().reset_index()
--------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-31d971de26ea> in <module>
----> 1 df.groupby('a').mode().reset_index()
2. 解决方法
groupby没有mode()函数,只能通过自定义函数方法实现求众数的方法。搜寻尝试方法如下:
- 使用value_counts()的方法,取聚合后样本次数出现最多的那个作为众数,但是如果有多个众数,会去结果较大的那个
In [15]: df.groupby('a').agg(lambda x: x.value_counts().index[0]).reset_index() Out[15]: a b 0 A 1 1 B 3
实际结果B应该为2.5
-
直接调用Series的mode方法,当众数有多个时,改样本会返回一个list方法。
In [28]: df.groupby('a').agg(lambda x: x.mode()).reset_index() Out[28]: a b 0 A 1 1 B [2, 3]
修正的方法如下:
In [29]: import numpy as np ...: df.groupby('a').agg(lambda x: np.mean(x.mode())).reset_index() Out[29]: a b 0 A 1.0 1 B 2.5
-
如果数据量不是很大,对速度要求不是很大,个人感觉第二种方法最简单好用。如果数据量很大时,这种方法就会出现很严重的卡顿,受不了,不能等。比较快速的求众数方法
In [41]: t1 = df.groupby(['a', 'b']).size().reset_index()
...: t1.columns = ['a', 'b', 'count']
...: t2 = t1.groupby(['a'])['count'].max().reset_index()
...: t2.columns = ['a', 'max_count']
...: t1 = t1.merge(t2, on=['a'], how='left')
...: t1 = t1[t1['count']==t1['max_count']]
...: t1 = t1.groupby(['a'])['b'].mean().reset_index()
...: t1
Out[41]:
a b
0 A 1.0
1 B 2.5
继续阅读
- 我的微信小程序
- 这是我的微信小程序扫一扫
-
- 我的微信公众号
- 我的微信公众号扫一扫
-
评论