Подтвердить что ты не робот

Python Pandas: сводная таблица с aggfunc = счет уникальной отдельной

df2 = pd.DataFrame({'X' : ['X1', 'X1', 'X1', 'X1'], 'Y' : ['Y2','Y1','Y1','Y1'], 'Z' : ['Z3','Z1','Z1','Z2']})

    X   Y   Z
0  X1  Y2  Z3
1  X1  Y1  Z1
2  X1  Y1  Z1
3  X1  Y1  Z2

g=df2.groupby('X')

pd.pivot_table(g, values='X', rows='Y', cols='Z', margins=False, aggfunc='count')

Traceback (последний последний вызов):... AttributeError: объект 'Index' не имеет атрибута 'index'

Как получить сводную таблицу с количеством уникальных значений одного столбца DataFrame для двух других столбцов?
Существует ли aggfunc для единственного числа? Должен ли я использовать np.bincount()?

NB. Я знаю "Series" values_counts(), но мне нужна сводная таблица.


EDIT: выход должен быть:

Z   Z1  Z2  Z3
Y             
Y1   1   1 NaN
Y2 NaN NaN   1
4b9b3361

Ответ 1

Вы имеете в виду что-то вроде этого?

In [39]: df2.pivot_table(values='X', rows='Y', cols='Z', 
                         aggfunc=lambda x: len(x.unique()))
Out[39]: 
Z   Z1  Z2  Z3
Y             
Y1   1   1 NaN
Y2 NaN NaN   1

Обратите внимание, что использование len предполагает, что у вас нет NA в вашем DataFrame. Вы можете сделать x.value_counts().count() или len(x.dropna().unique()) в противном случае.

Ответ 2

Я думаю, что это будет более совершенным:

df2.pivot_table(values='X',rows=['Y','Z'],cols='X',aggfunc='count')


                 X1 X2
Y   Z       
Y1  Z1   1   1
        Z2   1  NaN
Y2  Z3   1  NaN

Ответ 3

Поскольку по крайней мере версии 0.16 панд, он не принимает параметр "строки"

Начиная с 0.23, решение будет следующим:

df2.pivot_table(values='X', index='Y', columns='Z', aggfunc=pd.Series.nunique)

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

Z    Z1   Z2   Z3
Y                
Y1  1.0  1.0  NaN
Y2  NaN  NaN  1.0

Ответ 4

aggfunc=pd.Series.nunique дает отчетливый счет.

Благодарим @hume за это решение (см. комментарий под принятым ответом). Добавление в качестве ответа здесь для лучшей видимости.

Ответ 5

Вы можете построить сводную таблицу для каждого отдельного значения X. В этом случае

for xval, xgroup in g:
    ptable = pd.pivot_table(xgroup, rows='Y', cols='Z', 
        margins=False, aggfunc=numpy.size)

построит сводную таблицу для каждого значения X. Вы можете индексировать ptable с помощью xvalue. С помощью этого кода я получаю (для X1)

     X        
Z   Z1  Z2  Z3
Y             
Y1   2   1 NaN
Y2 NaN NaN   1

Ответ 6

Поскольку ни один из ответов не соответствует последней версии Pandas, я пишу другое решение этой проблемы:

In [1]:
import pandas as pd

# Set exemple
df2 = pd.DataFrame({'X' : ['X1', 'X1', 'X1', 'X1'], 'Y' : ['Y2','Y1','Y1','Y1'], 'Z' : ['Z3','Z1','Z1','Z2']})

# Pivot
pd.crosstab(index=df2['Y'], columns=df2['Z'], values=df2['X'], aggfunc=pd.Series.nunique)

Out [1]:
Z   Z1  Z2  Z3
Y           
Y1  1.0 1.0 NaN
Y2  NaN NaN 1.0