2017-01-26 4 views
4

Предположим, я создаю следующую фреймворк данных с df.set_index ('Class', 'subclass'), имея в виду, что существует несколько классов с подклассами ... A> Z. неПодведение итогов в виде мультииндекса pandas DataFrame

Class subclass  
    A  a   
    A  b 
    A  c 
    A  d 
    B  a    
    B  b 

Как бы я рассчитывать подклассы в классе и создать отдельный столбец с именем не классов, таких, что я могу видеть класс с наибольшим количеством подклассов? Я думал о каком-то цикле, который пробегает буквы класса и подсчитывает подкласс, если это письмо класса все равно. Однако для такой проблемы это кажется немного противоречивым. Будет ли более простой подход, например, df.groupby [] count?

Нужный результат будет:

Class subclass No. of classes 
    A  a    4  
    A  b 
    A  c 
    A  d 
    B  a    2  
    B  b 

Я попытался параметр уровня, как показано на group multi-index pandas dataframe, но это не похоже на работу для меня

EDIT:

я не сделал что я хотел вернуть класс с наибольшим количеством подклассов. Я достиг этого с:

df.reset_index().groupby('Class')['subclass'].nunique().idxmax() 
+1

IIUC вы можете сделать 'ФР [ 'Нет. классов '] = df.groupby (' Class ') [' subclass ']. transform (' count ') ' – EdChum

+0

Вам нужны пустые значения в' Нет. классов?? – jezrael

+0

Мне нужен был возврат класса с наибольшим количеством подклассов. После большего поиска я написал следующее: 'df.reset_index(). Groupby (' Class ') [' subclass ']. Nunique(). Idxmax()', который работал. – Joey

ответ

3

Вы можете использовать transform, но получить значение дубликатов:

df['No. of classes'] = df.groupby(level='Class')['val'].transform('size') 

print (df) 
       val No. of classes 
Class subclass      
A  a   1    4 
     b   4    4 
     c   5    4 
     d   4    4 
B  a   1    2 
     b   2    2 

Но если нужно пустые значения:

df['No. of classes'] = df.groupby(level='Class') 
         .apply(lambda x: pd.Series([len(x)] + [np.nan] * (len(x)-1))) 
         .values 
print (df) 
       val No. of classes 
Class subclass      
A  a   1    4.0 
     b   4    NaN 
     c   5    NaN 
     d   4    NaN 
B  a   1    2.0 
     b   2    NaN 

Другим решением для получения Class с наибольшим числом является:

df = df.groupby(level=['Class']) 
     .apply(lambda x: x.index.get_level_values('subclass').nunique()) 
     .idxmax() 
print (df) 
A 
+0

Если я хочу найти сумму трех верхних валов в каждом классе и вернуть верхние 3 класса с максимальной суммой, могу ли я использовать аналогичное выражение? скажите 'df.groupby (' Class ') [' val ']. nlargest (3)', чтобы отсортировать верхние 3 vals в каждом классе, а затем применить другое выражение, чтобы суммировать верхние 3 и отсортировать? – Joey

+1

Как вы думаете, 'df.groupby ('Class') ['val']. Apply (lambda x: x.nlargest (3) .sum())'? – jezrael

+1

И тогда, если нужно, добавьте 'idxmax()' like 'df.groupby ('Class') ['val']. Apply (lambda x: x.nlargest (3) .sum()). Idxmax()' – jezrael

2

Вы можете использовать transform добавить агрегированный расчет вернуться к первоначальному ДФУ как новый столбец:

In [165]: 
df['No. of classes'] = df.groupby('Class')['subclass'].transform('count') 
df 

Out[165]: 
    Class subclass No. of classes 
0  A  a    4 
1  A  b    4 
2  A  c    4 
3  A  d    4 
4  B  a    2 
5  B  b    2 
Смежные вопросы