Tabla dinámica de pandas: categorías ordenadas que causan márgenes inesperados

Utilizando python 3.7 y pandas 0.23.4. Estoy tratando de hacer tablas dinámicas con datos categóricos ordenados. Si incluyo márgenes, los subtotales no parecen estar en el orden correcto.

import pandas as pd m='male' f='female' data = {'num': [0,1,2,3,4,5,6,7,8,9], 'age': [1,2,2,3,3,3,3,1,2,3], 'sex': [f,f,f,f,f,f,f,m,m,m]} df = pd.DataFrame(data=data) df['age1'] = pd.Categorical(df['age'],categories=[3,2,1],ordered=True) df['sex1'] = pd.Categorical(df['sex'],categories=[m,f],ordered=True) pd.pivot_table(df,values='num',index='age1',columns='sex1',aggfunc='count',margins=True) 

Salida (orden de márgenes incorrecto, las sums de ‘Todos’ no están en las filas o columnas correctas):

 sex1 male female All age1 3 1 4 2 2 1 2 3 1 1 1 5 All 7 3 10 

Salida esperada (orden de márgenes correctos):

 sex1 male female All age1 3 1 4 5 2 1 2 3 1 1 1 2 All 3 7 10 

En este ejemplo, podría ser mejor crear las categorías con ordenado = Falso. Sin embargo, gran parte de mis datos se ordenan automáticamente (utilizando pd.cut), por lo que me gustaría saber si se trata de un comportamiento intencionado y, de ser así, ¿hay alguna forma de eliminar el pedido en una categoría creada con un pedido?

Editar : aquí hay un ejemplo usando pd.cut. Cambié los valores de la columna ‘edad’ para que aparezcan al revés del orden de corte.

 import pandas as pd m='male' f='female' data = {'num': [0,1,2,3,4,5,6,7,8,9], 'age': [3,3,3,3,2,2,1,1,2,3], 'sex': [f,f,f,f,f,f,f,m,m,m]} df = pd.DataFrame(data=data) df['cut'] = pd.cut(df['age'],[1,2,3,4],labels=['2'],right=False) pd.pivot_table(df,values='num',index='cut',columns='sex',aggfunc='count',margins=True) 

Salida, nuevamente con márgenes de fila incorrectos (correspondientes a la categoría ordenada de pd.cut).

 sex female male All cut 2 4 1 2 All 7 3 10 

La salida esperada sería el orden de margen de fila correcto.

 sex female male All cut 2 4 1 5 All 7 3 10 

Aquí hay una solución para su pregunta original . Elimine el argumento ordenado de df['age1'] y df['sex1']

Mis cambios:

 import pandas as pd m = 'male' f = 'female' data = {'num': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 'age': [1, 2, 2, 3, 3, 3, 3, 1, 2, 3], 'sex': [f, f, f, f, f, f, f, m, m, m]} df = pd.DataFrame(data=data) df['age1'] = pd.Categorical(df['age'], categories=[3, 2, 1]) df['sex1'] = pd.Categorical(df['sex'], categories=[m, f]) pd.pivot_table(df, values='num', index='age1', columns='sex1', aggfunc='count', margins=True) 

Salida:

 sex male female All age1 3 1 4 5 2 1 2 3 1 1 1 2 All 3 7 10 

De los documentos : Si esta categoría se trata o no como una categoría ordenada. Si es True, se ordenará la categoría resultante. Un orden categórico respeta, cuando se ordena, el orden de sus categorías de atributo

Así que parece que cuando pasa ordenado = Verdadero en pd.Categorical, la tabla dinámica no ordenará el agregado según la categoría, pero la variable aparecerá en su dataframe. Si miras tu dataframe, las mujeres vienen antes que los hombres, por lo que ordenadas mantendrán esa clasificación para el agregado.

Entonces, para responder a su pregunta, este es el comportamiento deseado de ordenado, y debe tener cuidado al hacer esto si va a ordenar su dataframe en otra parte de su script.