2016-03-23 1 views
3

У меня есть панд данных рамки:Нахождение максимального появления значения столбца, после группы по на другой колонке

 id    city 
[email protected] Bangalore 
[email protected]  Mumbai 
[email protected]  Jamshedpur 
[email protected]  Jamshedpur 
[email protected] Bangalore 
    [email protected]  Mumbai 
    [email protected]  Vijayawada 
    [email protected]  Vijayawada 
    [email protected]  Vijayawada 

Я хочу найти ID-мудрое название города максимумом. Так что для данного идентификатора я могу сказать, что - это его любимый город:

  id    city 
[email protected] Bangalore 
[email protected]  Vijayawada 
[email protected]  Jamshedpur 

Использование GroupBy идентификатор и город дает:

  id     city  count 
0 [email protected]  Bangalore 2 
1  [email protected]  Mumbai  2 
2  [email protected]  Vijayawada 3 
3 [email protected]  Jamshedpur 2 

Как действовать дальше? Я считаю, что некоторые групповые заявки будут делать это, но не знают, что именно будет делать трюк. Поэтому, пожалуйста, предложите.

Если какой-то идентификатор имеет одинаковое количество для двух или трех городов, я в порядке с возвращением любого из этих городов.

+0

Другой вариант 'pd.crosstab (ДФ [ 'город'], [ДФ 'ид']). Idxmax (ось = 0)' 'хотя crosstab' может генерировать очень большой фрейм, если у вас много уникальных значений для id и city. –

+0

для DataFrame, о котором я упоминал, этот фрагмент кросс-таблицы дает мне только [email protected] Запись Vijayawada. я думаю, что он находит максимальное количество городов на общем наборе идентификаторов. Не указывается id id max city count. – Satya

+0

Подход [pandas recommended] (https://github.com/pandas-dev/pandas/issues/7301) - это 'groupby ('id'). Apply (your_custom_function)', за мой ответ – smci

ответ

4

Вы можете попробовать удвоить groupby с помощью size и idxmax. Выход список кортежей (потому что MultiIndex), так что используйте apply:

df = df.groupby(['id','city']).size().groupby(level=0).idxmax() 
           .apply(lambda x: x[1]).reset_index(name='city') 

Другие решения:

s = df.groupby(['id','city']).size() 
df = s.loc[s.groupby(level=0).idxmax()].reset_index().drop(0,axis=1) 

Или:

df = df.groupby(['id'])['city'].apply(lambda x: x.value_counts().index[0]).reset_index() 

print (df) 
        id  city 
0 [email protected] Bangalore 
1  [email protected] Vijayawada 
2 [email protected] Jamshedpur 
+0

Вы можете избежать ручного создания затем манипулировать MultiIndex; см. мой ответ. – smci

+0

@smci - не уверен, но 'apply' +' agg' немного сложнее;) Я добавляю еще 2 решения. – jezrael

+0

@smci - также вы не можете использовать 'head()', потому что не уверены, что первая группа макс. – jezrael

1

recommended подход является groupby('id').apply(your_custom_function), где your_custom_function объединяется по «городу» и возвращает максимальное значение (или, как вы упомянули, несколько максимальных значений). Мы даже не должны использовать .agg('city')

import pandas as pd 

def get_top_city(g): 
    return g['city'].value_counts().idxmax()  

df = pd.DataFrame.from_records(
     [('[email protected]', 'Bangalore'), ('[email protected]',  'Mumbai'), 
     ('[email protected]', 'Jamshedpur'),('[email protected]', 'Jamshedpur'), 
     ('[email protected]', 'Bangalore'), ('[email protected]',  'Mumbai'), 
     ('[email protected]',  'Vijayawada'),('[email protected]',  'Vijayawada'), 
     ('[email protected]',  'Vijayawada')], 
     columns=['id','city'], 
     index=None 
    ) 

topdf = df.groupby('id').apply(get_top_city) 

id 
[email protected]  Bangalore 
[email protected]  Vijayawada 
[email protected]  Jamshedpur 

# or topdf.items()/iteritems() if you want as list of (id,city) tuples 

[('[email protected]', 'Bangalore'), ('[email protected]', 'Vijayawada'), ('[email protected]', 'Jamshedpur')] 
+0

Нет, он не дает правильного результата, просто добавьте одну запись, как ('[email protected] ',' XYZ '), вы увидите, почему это не метод для этого. он в конечном итоге даст «xyz» для «[email protected]», а «Бангалор» должен быть ответом. – Satya

+0

он просто делает группу по id и возвращает max из всех городов, присутствующих для этой группы, которые сравниваются по алфавиту. Мне нужен счет/появление мудрый макс. – Satya

+0

Исправлено (мое решение на самом деле имело это ранее, я просто пытался свести к минимуму код) – smci

Смежные вопросы