python - 重新排序熊猫 from_product-MultiIndex DataFrame 中的级别,加上值?
问题描述
在我目前的工作中,目前经常出现以下情况。我有一个带有 product-MultiIndex 的 pandas DataFrame,如下所示:
cols = pd.MultiIndex.from_product([['foo1', 'foo2'], ['bar1', 'bar2']], names=['foo', 'bar'])
df = pd.DataFrame(np.arange(5*4).reshape(5, 4), index=range(5), columns=cols)
df
foo foo1 foo2
bar bar1 bar2 bar1 bar2
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
3 12 13 14 15
4 16 17 18 19
现在我想交换 DataFrame 的列级别,所以我尝试了这个:
df.reorder_levels(['bar', 'foo'], axis=1)
bar bar1 bar2 bar1 bar2
foo foo1 foo1 foo2 foo2
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
3 12 13 14 15
4 16 17 18 19
但这不是我想要的。我想根据这个很好的规范产品排序来改变列的顺序。我当前的解决方法如下所示:
cols_swapped = pd.MultiIndex.from_product([['bar1', 'bar2'], ['foo1', 'foo2']], names=['bar', 'foo'])
df.reorder_levels(cols_swapped.names, axis=1).loc[:, cols_swapped])
bar bar1 bar2
foo foo1 foo2 foo1 foo2
0 0 2 1 3
1 4 6 5 7
2 8 10 9 11
3 12 14 13 15
4 16 18 17 19
这可行,但不是很好,例如因为它更令人困惑并且必须创建一个新的 MultiIndex。我经常发生这种情况的情况是,我为所有列计算了一个新特征。但是在concat
将它添加到 my之后df
,它想将相应的新级别“排序”到一个新位置。假设新功能位于级别 0,则解决方法如下所示:
new_order = [1, 2, 0, 3, 4]
cols_swapped = pd.MultiIndex.from_product(
[df.columns.levels[i] for i in new_order],
names = [df.columns.names[i] for i in new_order]
)
df_swap = df.reorder_levels(cols_swapped.names, axis=1).loc[:, cols_swapped]
这更不好。
熊猫支持这个吗?如果是的话,有什么更优雅的方式来做到这一点?
解决方案
我相信swaplevel
需要sort_index
:
df = df.swaplevel(0,1, axis=1).sort_index(axis=1)
print (df)
bar bar1 bar2
foo foo1 foo2 foo1 foo2
0 0 2 1 3
1 4 6 5 7
2 8 10 9 11
3 12 14 13 15
4 16 18 17 19
推荐阅读
- wildfly - 清除wildfly中的所有http会话
- vestacp - 灶神星控制面板让我们加密自动更新问题
- asp.net-mvc - 新的 ASP.Net 项目,但要求登录
- apache-nifi - 使用 NIFI 将数据从 oracle 传输到 postgres
- visual-studio - Visual Studio 导航栏对象下拉菜单不起作用
- sql - 在 SQL 中将 1 行与多行进行比较
- asp.net-core - 使用 Azure Key Vault 的 ASP.NET Core 数据保护,用于将容器化应用部署到 Azure Kubernetes 服务
- regex - 保留原始消息并在正则表达式中提取捕获的字段
- sql - 从另一个 dblink 表中填充缺失的列值
- javascript - 如何使用 JavaScript 将完整的 HTML 字符串作为变量读取和更新