python - pandas 0.20:如何对具有多级索引的列进行自定义排序?
问题描述
熊猫新手。使用 pandas 0.20,所以没有 CategoricalDtype。在将一些 df 与 concat 合并后,我想对列进行自定义排序。合并的 df 将具有多级索引列。
使用分类,它不适用于自定义排序。
dfs=[table2, table3,table4]
L_list=['A', 'B', 'C']
test=pd.Categorical(L_list, categories=['B', 'C','A'], ordered=True)
merged_df = pd.concat(
dfs, axis=1,
keys=pd.MultiIndex.from_arrays([
test, # Top Level Keys
['Cat1', 'Cat2', 'Cat1'] # Second Level Keys
], names=['Importance', 'Category'])
)
output=merged_df.sort_index(axis=1, level=[0])
当前状态
**Merged_df**
Importance| A | B | C |
Category | Cat1 | Cat2 | Cat1 |
|Total Assets| AUMs | Revenue |
Firm 1 | 100 | 300 | 300 |
Firm 2 | 200 | 3400 | 200 |
Firm 3 | 300 | 800 | 400 |
Firm 4 | NaN | 800 | 350 |
期望状态
**Merged_df**
Importance| B | C | A |
Category | Cat2 | Cat1 | Cat1 |
|AUMs | Revenue | Total Assets |
Firm 1 | 300 | 300 | 100 |
Firm 2 | 3400 | 200 | 200 |
Firm 3 | 800 | 400 | 300 |
Firm 4 | 800 | 350 | NaN |
解决方案
不确定 0.20 的所有可能性,但一个想法是将多索引列转换为一个框架,将每个级别更改为分类数据(就像您在问题中对 test 所做的那样),然后对数据框进行 sort_values,保持作为列排序的索引因为您想重新排列 merge_df 列。看这个例子:
# simple example
dfs=[
pd.DataFrame({'a':[0,1]}, index=[0,1]),
pd.DataFrame({'b':[0,1]}, index=[0,1]),
pd.DataFrame({'c':[0,1]}, index=[0,1]),
]
L_list=['A', 'B', 'B'] # changed C to have 2 B with 2 Cat
merged_df = pd.concat(
dfs, axis=1,
keys=pd.MultiIndex.from_arrays([
test, # Top Level Keys
['Cat1', 'Cat1', 'Cat2'] # Second Level Keys
], names=['Importance', 'Category'])
)
print(merged_df)
# A B
# Cat1 Cat1 Cat2
# a b c
# 0 0 0 0
# 1 1 1 1
所以你可以做
# create dataframes of columns names
col_df = merged_df.columns.to_frame()
# change to catagorical each level you want
col_df[0] = pd.Categorical(col_df[0], categories=['B', 'C','A'], ordered=True)
col_df[1] = pd.Categorical(col_df[1], categories=['Cat2', 'Cat1'], ordered=True)
# sort values and get the index
print(col_df.sort_values(by=col_df.columns.tolist()).index)
# MultiIndex([('B', 'Cat2', 'c'), # B is before A and Cat2 before Cat1
# ('B', 'Cat1', 'b'),
# ('A', 'Cat1', 'a')],
# )
output = merged_df[col_df.sort_values(by=col_df.columns.tolist()).index]
print(output)
# B A
# Cat2 Cat1 Cat1
# c b a
# 0 0 0 0
# 1 1 1 1
推荐阅读
- jsf - 如何在 ap:selectCheckboxMenu 中调用监听器,其中项目作为参数传入监听器
- excel - 命令后用户窗体按钮保持按下状态
- python - Pandas 使用两个行为不同的列表创建 DataFrame
- c++ - 为什么 C++ 类名在移动到 VS Code 中的命名空间时不再突出显示语法?
- umbraco - 如何在 Umbraco 8 中上传文件并将其值设置为文件上传数据类型
- qt - txt 和 QTextEdit 的风格有什么不同
- javascript - Chrome 41 上的 Angular 7:未捕获的 SyntaxError:意外的令牌 =>
- android - android kotlin - 启动活动并从意图获取数据
- php - 如何在不添加新数组的情况下更改关联数组中的值
- php - 如何读取 json_decode 结果并转储它?