2014-11-18 2 views
5

Рассмотрим следующий dataframe:Количество уникальных значений в столбце группой

 A  B E 
0 bar one 1 
1 bar three 1 
2 flux six 1 
3 flux three 2 
4 foo five 2 
5 foo one 1 
6 foo two 1 
7 foo two 2 

Я хотел бы найти для каждого значения A, число уникальных значений в других столбцах.

  1. Я думал, что следующее будет делать это:

    df.groupby('A').apply(lambda x: x.nunique()) 
    

    , но я получаю сообщение об ошибке:

    AttributeError: 'DataFrame' object has no attribute 'nunique' 
    
  2. Я также попытался с:

    df.groupby('A').nunique() 
    

    но я также получил ошибку:

    AttributeError: 'DataFrameGroupBy' object has no attribute 'nunique' 
    
  3. Наконец я попытался с:

    df.groupby('A').apply(lambda x: x.apply(lambda y: y.nunique())) 
    

    , который возвращает:

     A B E 
    A    
    bar 1 2 1 
    flux 1 2 2 
    foo 1 3 2 
    

    и кажется правильным. Странно, однако, он также возвращает столбец A. Зачем?

+1

FWIW, ваш метод # 3 работает для меня (я получаю '2 1 1' для' столбца é'), и это то, что я бы предложили. – DSM

ответ

5

Объект DataFrame не nunique. Вы должны выбрать, в какой колонке вы хотите применить nunique(). Вы можете сделать это с помощью простого оператора точки:

df.groupby('A').apply(lambda x: x.B.nunique()) 

напечатает:

A 
bar  2 
flux 2 
foo  3 

И делать:

df.groupby('A').apply(lambda x: x.E.nunique()) 

напечатает:

A 
bar  1 
flux 2 
foo  2 

В качестве альтернативы вы можете сделайте это с помощью одного вызова функции, используя:

df.groupby('A').aggregate({'B': lambda x: x.nunique(), 'E': lambda x: x.nunique()}) 

, который будет печатать:

 B E 
A 
bar 2 1 
flux 2 2 
foo 3 2 

Чтобы ответить на ваш вопрос о том, почему ваша рекурсивной лямбда печатает A колонок, а также, это потому, что, когда вы делаете операцию groupby/apply, вы теперь перебор через три DataFrame объектов. Каждый объект DataFrame является суб-DataFrame оригинала. Применение операции к ней будет применяться к каждому Series. Есть три Series за DataFrame, к которым вы применяете оператор nunique().

Первый Series оценивается на каждом DataFrame является ASeries, и так как вы сделали groupby на A, вы знаете, что в каждом DataFrame, есть только один уникальное значение в ASeries. Это объясняет, почему в итоге вы получили столбец результатов A со всеми 1.

+0

Спасибо. Я надеялся избежать итерации через dataframe, но другого выбора не может быть. –

1

Я столкнулся с той же проблемой. Обновление панд до последней версии решило проблему для меня.

df.groupby('A').nunique() 

Приведенный выше код не подходит для меня в версии Pandas 0.19.2. Я обновил его до версии 0.21.1 Pandas, и он сработал.

Вы можете проверить версию, используя следующий код:

print('Pandas version ' + pd.__version__)