Python 数据透视表-导致意外边距的有序类别

Python 数据透视表-导致意外边距的有序类别,python,pandas,dataframe,pivot-table,Python,Pandas,Dataframe,Pivot Table,使用python 3.7和pandas 0.23.4。我试图用有序的分类数据创建透视表。如果我包括了利润,小计的顺序似乎不正确 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) d

使用python 3.7和pandas 0.23.4。我试图用有序的分类数据创建透视表。如果我包括了利润,小计的顺序似乎不正确

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)
输出(不正确的边距顺序,“全部”总和不在正确的行或列中):

预期产量(正确的利润顺序):

在本例中,最好使用ordered=False创建类别。但是,我的大部分数据是自动排序的(使用pd.cut),因此我想知道这是否是预期行为,如果是,是否有方法删除使用订单创建的类别上的排序

编辑-下面是一个使用pd.cut的示例。我更改了“年龄”列的值,使其与剪切顺序相反

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','2','>2'],right=False)
pd.pivot_table(df,values='num',index='cut',columns='sex',aggfunc='count',margins=True)
将熊猫作为pd导入
m='male'
f='雌性'
数据={'num':[0,1,2,3,4,5,6,7,8,9],
“年龄”:[3,3,3,2,2,1,1,2,3],
性别:[f,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_表(df,values='num',index='cut',columns='sex',aggfunc='count',margins=True)
输出,同样具有不正确的行边距(对应于pd.cut中的已排序类别)

性别女性男性所有
削减
2        4     1    2
全部7 3 10
预期输出将是正确的行边距顺序

sex  female  male  All
cut                   
<2        1     1    2
2         2     1    3
>2        4     1    5
All       7     3   10
性别女性男性所有
削减
2        4     1    5
全部7 3 10
这是您最初问题的解决方案。从
df['age1']
df['sex1']

我的变化:

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)
输出:

sex  male   female  All
age1            
3     1     4        5
2     1     2        3
1     1     1        2
All   3     7       10
从: 该范畴是否被视为有序范畴。如果为True,则将对生成的类别进行排序有序的分类在排序时尊重其类别属性的顺序

因此,当您将ordered=True传递给pd.category时,数据透视表将不会根据类别对聚合进行排序,而是在数据帧中显示变量。如果您查看您的数据帧,女性在男性之前出现,因此排序将保持聚合的排序


因此,为了回答您的问题,这是ordered的预期行为,如果要在脚本中的其他位置对数据帧进行排序,则应小心执行此操作。

这可能是一个错误。也许您可以自己计算边距,然后将它们附加到数据透视框架中?我认为使用pd.cut进行排序不会影响数据透视表聚合。但是,我认为当您传递ordered=True时,该特定参数将导致您看到的错误。@Edeki我已编辑了我的问题,以包含一个带有pd.cut的示例,该示例显示了该问题。@coldspeed这是一个选项。如果可能的话,我想继续使用默认的透视表。如果问题出在已排序的类别上,我只希望删除排序。如果这不可行,我将不使用pd.cut并编写我自己的函数将数据分类。@EdekiOkoh我更新了编辑,使其更清晰。pd.cut中的已排序类别仍导致数据透视表边距无序。
sex  female  male  All
cut                   
<2        1     1    2
2         2     1    3
>2        4     1    5
All       7     3   10
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)
sex  male   female  All
age1            
3     1     4        5
2     1     2        3
1     1     1        2
All   3     7       10