Python 使用pd.Category对多索引pd.Series进行排序? 问题:
为什么使用分类索引时使用的排序似乎不起作用?如何使用字母/数字以外的其他排序顺序对多索引pd.系列的索引进行排序 MWE 设置代码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导入
将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.5TLDR:您需要在您的
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版本中修复。