熊猫数据透视表-有序类别导致意外利润

时间:2019-02-07 21:04:11

标签: 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)

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)

输出(页边距顺序错误,“所有”总和不在正确的行或列中):

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

预期输出(正确的边距顺序):

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

在此示例中,最好使用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.cut中的排序类别)。

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

预期的输出将是正确的行边距顺序。

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

1 个答案:

答案 0 :(得分:1)

以下是针对您的原始问题的解决方法 。从SELECT V.Date, V.Amount, I.Number FROM Values V JOIN Items I ON V.ItemId = I.Id AND I.AssetId = V.AssetId WHERE I.Type IN (10023, 10025) AND V.AssetId = 100 --ORDER BY V.Date 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)

docs是否将此分类视为有序分类。如果为True,则将对结果分类进行排序。 排序的分类方面,在排序时,其类别属性的顺序

因此,当您将 ordered = True 传递给pd时,分类表将不会根据类别对聚合进行排序,而是将变量显示在数据框中。如果您查看自己的数据框,那么女性在男性之前要先于男性,这样才能保持合计。

因此,要回答您的问题,这是有序的预期行为,因此,如果要在脚本中的其他位置对数据框进行排序,则应格外小心。