如何在Python中获取每个标记最常出现的类别(模式)?
+------------------+----------+
| tag | category |
+------------------+----------+
| automotive | 8 |
| ba | 8 |
| bamboo | 8 |
| bamboo | 8 |
| bamboo | 8 |
| bamboo | 8 |
| bamboo | 8 |
| bamboo | 10 |
| bamboo | 8 |
| bamboo | 9 |
| bamboo | 8 |
| bamboo | 10 |
| bamboo | 8 |
| bamboo | 9 |
| bamboo | 8 |
| banana tree | 8 |
| banana tree | 8 |
| banana tree | 8 |
| banana tree | 8 |
| bath | 9 |
+-----------------------------+
预期输出就像
tag | category
------------+-----------
ba | 8
automotive | 8
bananatree | 8
bath | 9
bamboo | 8
由于我的数据集的机密性,我借用了Stephen J. Fuhry的表并且在MySQL SELECT most frequent by group编辑了David Fuhry的输出。
答案 0 :(得分:13)
在评论中,您注意到您正在使用pandas
。您可以执行以下操作:
>>> df
tag category
0 automotive 8
1 ba 8
2 bamboo 8
3 bamboo 8
4 bamboo 8
5 bamboo 8
6 bamboo 8
7 bamboo 10
8 bamboo 8
9 bamboo 9
10 bamboo 8
11 bamboo 10
12 bamboo 8
13 bamboo 9
14 bamboo 8
15 banana tree 8
16 banana tree 8
17 banana tree 8
18 banana tree 8
19 bath 9
在'标记'上执行groupby
对于'类别'列然后在每个组内使用mode
方法。但是,我们必须使其成为条件因素,因为如果观察数小于3,pandas
不会为mode
返回一个数字(我们可以在特殊情况下返回该组本身)一组中1或2个观察的情况)。我们可以使用带有lambda函数的aggregate/agg
方法来执行此操作:
>>> mode = lambda x: x.mode() if len(x) > 2 else np.array(x)
>>> df.groupby('tag')['category'].agg(mode)
tag
automotive 8
ba 8
bamboo 8
banana tree 8
bath 9
注意,当模式是多模式时,你会得到一个数组(numpy)。例如,假设有两个浴项(所有其他数据都相同):
tag|category
bath|9
bath|10
在这种情况下,输出将是:
>>> mode = lambda x: x.mode() if len(x) > 2 else np.array(x)
>>> df.groupby('tag')['category'].agg(mode)
tag
automotive 8
ba 8
bamboo 8
banana tree 8
bath [9, 10]
您也可以使用value_counts
方法代替mode
。再次,在groupby
上添加标记'对于'类别'列然后在每个组内使用value_counts
方法。 value_counts
按降序排列,因此您想要获取第一行的索引:
>>> df.groupby('tag')['category'].agg(lambda x: x.value_counts().index[0])
tag
automotive 8
ba 8
bamboo 8
banana tree 8
bath 9
但是,这不会在多模态情况下返回数组。它将返回第一个模式。