Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用pd.Category对多索引pd.Series进行排序? 问题:_Python_Pandas - Fatal编程技术网

Python 使用pd.Category对多索引pd.Series进行排序? 问题:

Python 使用pd.Category对多索引pd.Series进行排序? 问题:,python,pandas,Python,Pandas,为什么使用分类索引时使用的排序似乎不起作用?如何使用字母/数字以外的其他排序顺序对多索引pd.系列的索引进行排序 MWE 设置代码 将熊猫作为pd导入 将numpy作为np导入 d={ “卡片”:[ ‘Visa’、‘Visa’、‘万事达卡’、‘万事达卡’、‘Visa’、‘万事达卡’, ‘Visa’、‘Visa’、‘万事达卡’、‘Visa’、‘万事达卡’、‘Visa’、‘Visa’、‘Visa’, ‘万事达卡’、‘万事达卡’、‘Visa’、‘万事达卡’、‘Visa’、‘Visa’、‘Visa’,

为什么使用分类索引时使用的排序似乎不起作用?如何使用字母/数字以外的其他排序顺序对多索引pd.系列的索引进行排序

MWE 设置代码
将熊猫作为pd导入
将numpy作为np导入
d={
“卡片”:[
‘Visa’、‘Visa’、‘万事达卡’、‘万事达卡’、‘Visa’、‘万事达卡’,
‘Visa’、‘Visa’、‘万事达卡’、‘Visa’、‘万事达卡’、‘Visa’、‘Visa’、‘Visa’,
‘万事达卡’、‘万事达卡’、‘Visa’、‘万事达卡’、‘Visa’、‘Visa’、‘Visa’,
‘万事达卡’、‘Visa’、‘万事达卡’、‘万事达卡’、‘万事达卡’,
“万事达卡”、“万事达卡”、“万事达卡”、“Visa卡”、“Visa卡”
],
“年”:[
‘三’、‘三’、‘七’、‘三’、‘三’、‘七’、‘七’、‘七’,
‘三’、‘七’、‘三’、‘三’、‘三’、‘七’、‘三’、‘三’,
‘七’、‘七’、‘三’、‘七’、‘三’、‘五’、‘一’,
“一”,“二”,“四”,“六”,“六”
],
“价值”:[
45, 13, 52, 321, 31, 1231, 876, 231, 4, 213, 123, 45, 321, 1, 123, 52,
736, 35, 900, 301, 374, 9, 294, 337, 4465, 321, 755, 22, 8
]
}
df=pd.数据帧(d)
grp_cols=[“卡片”,“年份”]
ser_val=df.groupby(grp_cols)['Value'].mean()
简单地使用
排序索引
,数据如下所示:

[2]中的
:序列值排序索引()
出[2]:
卡年
万事达五卡294.000000
四个755000000
一个2401000000
七个50500000
三个146.833333
两个321000000
Visa Seven 438.166667
六千五百万
三个84.50万
名称:Value,数据类型:float64
您可以看到这些列是按字母顺序排序的。现在,我想强制订购。为此,我尝试:

categories_顺序=['1'、'2'、'3'、'4'、'5'、'6'、'7']
categories=pd.Categorical(ser_val.index.levels[1]。值,
类别=类别\顺序,
顺序=真)
ser_val.index.set_levels(类别,level='Year',inplace=True)
同样,排序后的数据如下所示(同样,按字母顺序排列)

[3]中的
:序列值排序索引()
出[3]:
卡年
万事达五卡294.000000
四个755000000
一个2401000000
七个50500000
三个146.833333
两个321000000
Visa Seven 438.166667
六千五百万
三个84.50万
名称:Value,数据类型:float64
我知道,如果我将数据转换为pandas.DataFrame并在那里排序,它会工作,如下所示:

df_val=ser_val.reset_index().sort_值(grp_cols)
df_val['Year']=pd.分类(df_val['Year'].值,
按顺序分类,
顺序=真)
df_val=df_val.sort_值(grp_cols)。set_索引(grp_cols)
In[5]:df_val
出[5]:
价值
卡年
万事达卡1 2401.000000
两个321000000
三个146.833333
四个755000000
五二亿九千四百万
七个50500000
三号签证84.500000
六千五百万
七个438.166667
为什么pd.Series不使用分类数据进行排序


我正在使用Python3.7.3 64位的pandas 1.0.5

TLDR:您需要在您的
groupby
中设置
sort=False
,并且您需要将
Categorical
更改为
CategoricalIndex
。以下是完整的工作示例:

df = pd.DataFrame(d)
grp_cols = ['Card', 'Year']
ser_val = df.groupby(grp_cols, sort=False)['Value'].mean()

categories_order = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven']
categories = pd.CategoricalIndex(ser_val.index.levels[1].values,
                                 categories=categories_order,
                                 ordered=True)
ser_val.index.set_levels(categories, level='Year', inplace=True)
ser_val.sort_index(inplace=True)
ser_val
现在是:

Card         Year 
Master Card  One      2401.000000
             Two       321.000000
             Three     146.833333
             Four      755.000000
             Five      294.000000
             Seven     505.000000
Visa         Three      84.500000
             Six        15.000000
             Seven     438.166667
Name: Value, dtype: float64

长篇大论:你会问为什么你所做的不起作用,我当然无法解释(我确信这涉及到一些来源方面的问题),但下面是我如何得出解决方案的

请参见以下示例,从头开始构建玩具多索引系列:

lets = ['a','b','c']*3
ids = ['MALE']*4 + ['FEMALE']*5
s = pd.Series(range(9), index=[ids,lets])

categories_order = ['b','a','c']
categories = pd.CategoricalIndex(s.index.levels[1].values,
                                 categories=categories_order,
                                 ordered=True)
s.index.set_levels(categories, level=1,inplace=True)
s.sort_index(inplace=True)
s
按我们的要求排序:

FEMALE  b    4
        b    7
        a    6
        c    5
        c    8
MALE    b    1
        a    0
        a    3
        c    2
dtype: int64
您的示例和我的示例(我可以看出)之间唯一的显著区别是,您的示例从
groupby
开始。有一个
sort
参数:

sort:bool,默认为True
对组键进行排序。关闭此选项可获得更好的性能。注:这并不影响各组内观察的顺序。Groupby保留每个组中的行顺序

因此,
groupby
sort似乎在强制执行一些没有被新的分类顺序覆盖的顺序

但是仍然带有
sort=False
,您的原样代码不起作用。通过谷歌搜索,我发现和有单独的类,显然后者是你在这里需要的。当然,如果使用
Categorical
而不是
CategoricalIndex
,我的示例也会失败

因此,
groupby
似乎是一个更奇怪的问题;我不能告诉你这里的基本规则,但也许有人可以详细说明。

事实上,我认为你发现了一两个错误! Bug#1-使用pd.Categorical使用set#U级别更改数据类型不起作用。 输出:

object  *FAILED change type using inplace*
object  *FAILED change type using reassignment*
category  *SUCCESS change type using pd.CategoricalDtype*
CategoricalIndex(['Five', 'Four', 'One', 'Seven', 'Six', 'Three', 'Two'], categories=['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven'], ordered=True, name='Year', dtype='category')
Year   Card       
Five   Master Card     294.000000
Four   Master Card     755.000000
One    Master Card    2401.000000
Seven  Master Card     505.000000
       Visa            438.166667
Six    Visa             15.000000
Three  Master Card     146.833333
       Visa             84.500000
Two    Master Card     321.000000
Name: Value, dtype: float64
Bug#2-在多索引级别1中使用categorical对索引进行排序不起作用 这可能已经在这里找到了 成功更改索引级别1的dype后:

 ser_val.index.levels[1]
输出:

object  *FAILED change type using inplace*
object  *FAILED change type using reassignment*
category  *SUCCESS change type using pd.CategoricalDtype*
CategoricalIndex(['Five', 'Four', 'One', 'Seven', 'Six', 'Three', 'Two'], categories=['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven'], ordered=True, name='Year', dtype='category')
Year   Card       
Five   Master Card     294.000000
Four   Master Card     755.000000
One    Master Card    2401.000000
Seven  Master Card     505.000000
       Visa            438.166667
Six    Visa             15.000000
Three  Master Card     146.833333
       Visa             84.500000
Two    Master Card     321.000000
Name: Value, dtype: float64
现在,让我们使用sort_索引对数据帧进行排序:

ser_val.sort_index()
输出(失败):

现在,为了方便测试,让我们交换索引级别,然后再次尝试排序索引

ser_val.swaplevel(0,1).sort_index()
输出(成功):

但是,如果我们显式设置排序级别。。。再次失败

ser_val.swaplevel(0,1).sort_index(level=[0,1])
输出:

object  *FAILED change type using inplace*
object  *FAILED change type using reassignment*
category  *SUCCESS change type using pd.CategoricalDtype*
CategoricalIndex(['Five', 'Four', 'One', 'Seven', 'Six', 'Three', 'Two'], categories=['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven'], ordered=True, name='Year', dtype='category')
Year   Card       
Five   Master Card     294.000000
Four   Master Card     755.000000
One    Master Card    2401.000000
Seven  Master Card     505.000000
       Visa            438.166667
Six    Visa             15.000000
Three  Master Card     146.833333
       Visa             84.500000
Two    Master Card     321.000000
Name: Value, dtype: float64

我的儿子是1.0.4。它可能会在即将发布的1.1.0版本中修复。