Pandas MultiIndex 按分类顺序自定义排序级别,而不是按字母顺序
Pandas MultiIndex custom sort levels by categorical order, not alphabetically
我是 Pandas (0.16.1) 的新手,想在多索引中进行自定义排序,所以我使用分类。
我的多索引的一部分:
Part Defect Own
Кузов 504 ИП
Кузов 504 Итого
Кузов 504 ПС
Кузов 505 ПС
Кузов 506 ПС
Кузов 507 ПС
Кузов 530 ИП
Кузов 530 Итого
Кузов 530 ПС
我创建了具有 MultiIndex 级别 [缺陷,自己] 的枢轴 table。然后我将 "Own" 分类(参见 p.s. 问题的一部分)将其排序为 [ИП, ПС, Итого]。但是当我在 "Part" 前面添加级别时,这也是基于 "Defect" 级别的分类,并使用
对索引进行排序
pvt.sortlevel(0, inplace=True)
"Own" 级别按字母顺序排序:[ИП, Итого, ПС]。我如何在多索引中自定义排序两个级别?
P. S. 我使用以下代码将 "Own" 级别转换为分类级别:创建新列,用它替换索引级别。可以吗?
def makeLevelCategorical(pdf, pname, cats):
names = pdf.index.names
namei = names.index(pname)
pdf["tmp"] = pd.Categorical(pdf.index.get_level_values(pname), categories=cats) #New temp column
pdf.set_index("tmp", append=True, inplace=True) #Append column to index
pdf = pdf.reset_index(pname, drop=True) #Remove /pname/ level
names2 = list(names)
names2[namei] = "tmp"
pdf.reorder_levels(names2) #Put "tmp" level to /pname/'s position
pdf.index.names = names #Rename "tmp" level to /pname/
return pdf
可以使用 Dataframe.sort_index 函数对多索引进行排序。
这是一个小例子:
df = pd.DataFrame(
{"i1":[1,1,1,1,2,4,4,2,3,3,3,3],
"i2":[1,3,2,2,1,1,2,2,1,1,3,2],
"d1":['a','b','c','d','e','f','g','h','i','j','k','l']}
)
df.set_index(['i1', 'i2'], inplace=True)
df.sort_index()
输出:
d1
i1 i2
1 1 a
2 c
2 d
3 b
2 1 e
2 h
3 1 i
1 j
2 l
3 k
4 1 f
2 g
如果你想改变基于列的排序顺序,Dataframe.sort_index 函数接受一个参数 ascending=
,它可以给出一个列表 [True, False]
语句对应于列订单。
Categorical 是 pandas 中一个新的闪亮数据类型,应该使用它,但本身不需要此操作。
根据评论进行编辑:
排序将始终按字母顺序或倒序排序。如果您想要自定义排序,那么您需要创建一个新列,该列可以按字母顺序排序,但它是可以确定排序的列的结果。使用 Series.map 执行此操作,就像这个例子一样,首先对数据集进行元音排序:
mappings = {'a': 0, 'b':1, 'c':1, 'd':1,
'e':0, 'f':1, 'g':1, 'h':1,
'i':0, 'j':1, 'k': 1, 'l': 1}
df['sortby'] = df['d1'].map(mappings)
df.sort('sortby')
d1 sortby
i1 i2
1 1 a 0
2 1 e 0
3 1 i 0
1 3 b 1
2 c 1
2 d 1
4 1 f 1
2 g 1
2 2 h 1
3 1 j 1
3 k 1
2 l 1
如果你不想要之后的 sortby 列,你可以简单地删除它,像这样:
del df['sortby']
我是 Pandas (0.16.1) 的新手,想在多索引中进行自定义排序,所以我使用分类。 我的多索引的一部分:
Part Defect Own
Кузов 504 ИП
Кузов 504 Итого
Кузов 504 ПС
Кузов 505 ПС
Кузов 506 ПС
Кузов 507 ПС
Кузов 530 ИП
Кузов 530 Итого
Кузов 530 ПС
我创建了具有 MultiIndex 级别 [缺陷,自己] 的枢轴 table。然后我将 "Own" 分类(参见 p.s. 问题的一部分)将其排序为 [ИП, ПС, Итого]。但是当我在 "Part" 前面添加级别时,这也是基于 "Defect" 级别的分类,并使用
对索引进行排序pvt.sortlevel(0, inplace=True)
"Own" 级别按字母顺序排序:[ИП, Итого, ПС]。我如何在多索引中自定义排序两个级别?
P. S. 我使用以下代码将 "Own" 级别转换为分类级别:创建新列,用它替换索引级别。可以吗?
def makeLevelCategorical(pdf, pname, cats):
names = pdf.index.names
namei = names.index(pname)
pdf["tmp"] = pd.Categorical(pdf.index.get_level_values(pname), categories=cats) #New temp column
pdf.set_index("tmp", append=True, inplace=True) #Append column to index
pdf = pdf.reset_index(pname, drop=True) #Remove /pname/ level
names2 = list(names)
names2[namei] = "tmp"
pdf.reorder_levels(names2) #Put "tmp" level to /pname/'s position
pdf.index.names = names #Rename "tmp" level to /pname/
return pdf
可以使用 Dataframe.sort_index 函数对多索引进行排序。
这是一个小例子:
df = pd.DataFrame(
{"i1":[1,1,1,1,2,4,4,2,3,3,3,3],
"i2":[1,3,2,2,1,1,2,2,1,1,3,2],
"d1":['a','b','c','d','e','f','g','h','i','j','k','l']}
)
df.set_index(['i1', 'i2'], inplace=True)
df.sort_index()
输出:
d1
i1 i2
1 1 a
2 c
2 d
3 b
2 1 e
2 h
3 1 i
1 j
2 l
3 k
4 1 f
2 g
如果你想改变基于列的排序顺序,Dataframe.sort_index 函数接受一个参数 ascending=
,它可以给出一个列表 [True, False]
语句对应于列订单。
Categorical 是 pandas 中一个新的闪亮数据类型,应该使用它,但本身不需要此操作。
根据评论进行编辑:
排序将始终按字母顺序或倒序排序。如果您想要自定义排序,那么您需要创建一个新列,该列可以按字母顺序排序,但它是可以确定排序的列的结果。使用 Series.map 执行此操作,就像这个例子一样,首先对数据集进行元音排序:
mappings = {'a': 0, 'b':1, 'c':1, 'd':1,
'e':0, 'f':1, 'g':1, 'h':1,
'i':0, 'j':1, 'k': 1, 'l': 1}
df['sortby'] = df['d1'].map(mappings)
df.sort('sortby')
d1 sortby
i1 i2
1 1 a 0
2 1 e 0
3 1 i 0
1 3 b 1
2 c 1
2 d 1
4 1 f 1
2 g 1
2 2 h 1
3 1 j 1
3 k 1
2 l 1
如果你不想要之后的 sortby 列,你可以简单地删除它,像这样:
del df['sortby']