按列分组后如何获得最高频率元素?

时间:2018-09-21 08:01:38

标签: python pandas dataframe pandas-groupby

我有一个名为df的DataFrame,我想计算不同app_0app_1app_2sex列中的最高频率元素。

import pandas as pd 
import numpy as np 
df=pd.DataFrame({'id':[1,2,3,4],'app_0':['a','b','c','d'],
'app_1':['b','c','d',np.nan],'app_2':['c','b','a','a'],'sex':[0,0,1,1]})

Input:

df
    id app_0 app_1 app_2  sex
0   1     a     b     c    0
1   2     b     c     b    0
2   3     c     d     a    1
3   4     d   NaN     a    1

如您所见,sexid 1的{​​{1}}均为id 2。对于0sex 0bapp_0app_1列中出现最多,app_2在倒数第二位。因此,对于cid 1,频率最高的元素是id 2,第二频率最高的是b

c

Expected:

1 个答案:

答案 0 :(得分:2)

stackvalue_counts使用自定义功能:

def f(x):
    s = x.stack().value_counts()
    return pd.Series([s.index[0], s.index[1]], index=['top_1','top_2'])

或将CounterCounter.most_common的取整值一起使用:

from collections import Counter

def f(x):
    c = Counter([y for x in x.values.tolist() for y in x])
    a = c.most_common(2)
    return pd.Series([a[0][0], a[1][0]], index=['top_1','top_2'])

df1 = df.groupby('sex')['app_0','app_1','app_2'].apply(f)

df = df.join(df1, on='sex')
print (df)
   id app_0 app_1 app_2  sex top_1 top_2
0   1     a     b     c    0     b     c
1   2     b     c     b    0     b     c
2   3     c     d     a    1     a     d
3   4     d   NaN     a    1     a     d

编辑:

如果next不存在第二个最高值,则可以使用更通用的解决方案:

df=pd.DataFrame({'id':[1,2,3,4],'app_0':['a','a','a','a'],
'app_1':['a','a','a',np.nan],'app_2':['a','a','a','a'],'sex':[0,0,1,1]})
print (df)
   id app_0 app_1 app_2  sex
0   1     a     a     a    0
1   2     a     a     a    0
2   3     a     a     a    1
3   4     a   NaN     a    1

def f(x):
    c = Counter([y for x in x.values.tolist() for y in x])
    a = iter(c.most_common(2))

    return pd.Series([next(a, ['no top1'])[0],
                      next(a, ['no top2'])[0]], index=['top_1','top_2'])

df1 = df.groupby('sex')['app_0','app_1','app_2'].apply(f)

df = df.join(df1, on='sex')
print (df)
   id app_0 app_1 app_2  sex top_1    top_2
0   1     a     a     a    0     a  no top2
1   2     a     a     a    0     a  no top2
2   3     a     a     a    1     a      NaN
3   4     a   NaN     a    1     a      NaN