Как получить элементы максимальной частоты после группировки по столбцам? - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть DataFrame с именем df, и я хочу посчитать элементы верхней частоты в столбце app_0, app_1 и app_2 для разных sex.

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

Как видите, sex для id 1 и id 2 равно 0.Для sex 0 наибольшее значение имеет b, в столбце app_0, app_1 и app_2, c - второе место.Таким образом, для id 1 и id 2 самый частотный элемент - b, а второй самый большой - c.

Expected:

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

1 Ответ

0 голосов
/ 21 сентября 2018

Используйте пользовательскую функцию с stack и value_counts:

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

Или используйте Counter со сглаженными значениями с Counter.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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...