Deze code:
df2 = (
pd.DataFrame({
'X' : ['X1', 'X1', 'X1', 'X1'],
'Y' : ['Y2', 'Y1', 'Y1', 'Y1'],
'Z' : ['Z3', 'Z1', 'Z1', 'Z2']
})
)
g = df2.groupby('X')
pd.pivot_table(g, values='X', rows='Y', cols='Z', margins=False, aggfunc='count')
retourneert de volgende fout:
Traceback (most recent call last): ...
AttributeError: 'Index' object has no attribute 'index'
Hoe krijg ik een draaitabel met aantallen van unieke waardenvan één DataFrame-kolom voor twee andere kolommen?
Is er aggfunc
voor unieke telling? Moet ik np.bincount()
gebruiken?
NB. Ik ben me bewust van pandas.Series.values_counts()
maar ik heb een draaitabel nodig.
EDIT: de uitvoer moet zijn:
Z Z1 Z2 Z3
Y
Y1 1 1 NaN
Y2 NaN NaN 1
Antwoord 1, autoriteit 100%
Bedoel je zoiets?
>>> df2.pivot_table(values='X', index='Y', columns='Z', aggfunc=lambda x: len(x.unique()))
Z Z1 Z2 Z3
Y
Y1 1 1 NaN
Y2 NaN NaN 1
Merk op dat het gebruik van len
ervan uitgaat dat je geen NA
‘s in je DataFrame hebt. Je kunt x.value_counts().count()
of len(x.dropna().unique())
anders doen.
Antwoord 2, autoriteit 46%
Dit is een goede manier om items binnen .pivot_table
te tellen:
>>> df2.pivot_table(values='X', index=['Y','Z'], columns='X', aggfunc='count')
X1 X2
Y Z
Y1 Z1 1 1
Z2 1 NaN
Y2 Z3 1 NaN
Antwoord 3, autoriteit 31%
Sinds versie 0.16 van panda’s, is de parameter “rijen” niet nodig
Vanaf 0,23 zou de oplossing zijn:
df2.pivot_table(values='X', index='Y', columns='Z', aggfunc=pd.Series.nunique)
die terugkeert:
Z Z1 Z2 Z3
Y
Y1 1.0 1.0 NaN
Y2 NaN NaN 1.0
Antwoord 4, autoriteit 6%
aggfunc=pd.Series.nunique
biedt een duidelijk aantal. Volledige code volgt:
df2.pivot_table(values='X', rows='Y', cols='Z', aggfunc=pd.Series.nunique)
Met dank aan @hume voor deze oplossing (zie opmerking onder het geaccepteerde antwoord). Hier als antwoord toevoegen voor een betere vindbaarheid.
Antwoord 5, autoriteit 3%
U kunt een draaitabel maken voor elke afzonderlijke waarde van X
. In dit geval
for xval, xgroup in g:
ptable = pd.pivot_table(xgroup, rows='Y', cols='Z',
margins=False, aggfunc=numpy.size)
maakt een draaitabel voor elke waarde van X
. Misschien wil je ptable
indexeren met de xvalue
. Met deze code krijg ik (voor X1
)
X
Z Z1 Z2 Z3
Y
Y1 2 1 NaN
Y2 NaN NaN 1
Antwoord 6, autoriteit 3%
- De parameter
aggfunc
inpandas.DataFrame.pivot_table
neemt'nunique'
als eenstring
of in eenlist
- Getest in
pandas 1.3.1
out = df2.pivot_table(values='X', index='Y', columns='Z', aggfunc=['nunique', 'count', lambda x: len(x.unique()), len])
[out]:
nunique count <lambda> len
Z Z1 Z2 Z3 Z1 Z2 Z3 Z1 Z2 Z3 Z1 Z2 Z3
Y
Y1 1.0 1.0 NaN 2.0 1.0 NaN 1.0 1.0 NaN 2.0 1.0 NaN
Y2 NaN NaN 1.0 NaN NaN 1.0 NaN NaN 1.0 NaN NaN 1.0
out = df2.pivot_table(values='X', index='Y', columns='Z', aggfunc='nunique')
[out]:
Z Z1 Z2 Z3
Y
Y1 1.0 1.0 NaN
Y2 NaN NaN 1.0
out = df2.pivot_table(values='X', index='Y', columns='Z', aggfunc=['nunique'])
[out]:
nunique
Z Z1 Z2 Z3
Y
Y1 1.0 1.0 NaN
Y2 NaN NaN 1.0
Antwoord 7
Voor de beste prestaties raad ik aan om DataFrame.drop_duplicates
te volgen aggfunc='count'
.
Anderen hebben gelijk dat aggfunc=pd.Series.nunique
zal werken. Dit kan echter traag zijn als het aantal index
-groepen dat u heeft groot is (>1000).
Dus in plaats van (om @Javier te citeren)
df2.pivot_table('X', 'Y', 'Z', aggfunc=pd.Series.nunique)
Ik stel voor
df2.drop_duplicates(['X', 'Y', 'Z']).pivot_table('X', 'Y', 'Z', aggfunc='count')
Dit werkt omdat het garandeert dat elke subgroep (elke combinatie van ('Y', 'Z')
) unieke (niet-dubbele) waarden van 'X'
.
Antwoord 8
aggfunc=pd.Series.nunique
telt alleen unieke waarden voor een reeks – in dit geval telt de unieke waarden voor een kolom. Maar dit is niet echt een alternatief voor aggfunc='count'
Voor eenvoudig tellen is het beter om aggfunc=pd.Series.count
te gebruiken
Antwoord 9
Aangezien geen van de antwoorden up-to-date is met de laatste versie van Pandas, schrijf ik een andere oplossing voor dit probleem:
import pandas as pd
# Set example
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)
die terugkeert:
Z Z1 Z2 Z3
Y
Y1 1.0 1.0 NaN
Y2 NaN NaN 1.0