在多索引框架上调用df.sort_index()时,如何将func_2用于级别two

func_1 = lambda s: s.str.lower()
func_2 = lambda x: np.abs(x)
m_sorted = df_multi.sort_index(level=['one', 'two'], key=func_1)

documentation是"For MultiIndex inputs, the key is applied per level",这是模糊的.


import pandas as pd
import numpy as np
np.random.seed(3)

# Create multiIndex
choice = lambda a, n: np.random.choice(a, n, replace=True)
df_multi = pd.DataFrame({
    'one': pd.Series(choice(['a', 'B', 'c'], 8)),
    'two': pd.Series(choice([1, -2, 3], 8)),
    'A': pd.Series(choice([2,6,9,7] ,8))
    })
df_multi = df_multi.set_index(['one', 'two'])

# Sort MultiIndex
func_1 = lambda s: s.str.lower()
func_2 = lambda x: np.abs(x)
m_sorted = df_multi.sort_index(level=['one'], key=func_1)

推荐答案

sort_index作为key具有独特的功能,可用于所有级别.

也就是说,您可以使用包装函数来映射每个级别名称所需的排序函数:

def sorter(level, default=lambda x: x):
    return {
      'one': lambda s: s.str.lower(),
      'two': np.abs,
    }.get(level.name, default)(level)

df_multi.sort_index(level=['one', 'two'], key=sorter)

NB. in case of no match a default function is used that returns the level unchanged.

另一个选项是numpy.lexsort而不是sort_index:

# levels, functions in desired sorting order
sorters = [('one', lambda s: s.str.lower()), ('two', np.abs)]

out = df_multi.iloc[np.lexsort([f(df_multi.index.get_level_values(lvl))
                                for lvl, f in sorters[::-1]])]

100 uses the major keys last, thus the 101

输出:

         A
one two   
a    1   6
    -2   2
     3   7
B    1   6
    -2   7
    -2   7
     3   2
     3   6

Python相关问答推荐

处理(潜在)不断增长的任务队列的并行/并行方法

如何访问所有文件,例如环境变量

Streamlit应用程序中的Plotly条形图中未正确显示Y轴刻度

形状弃用警告与组合多边形和多边形如何解决

如何使Matplotlib标题以图形为中心,而图例框则以图形为中心

删除marplotlib条形图上的底边

在不同的帧B中判断帧A中的子字符串,每个帧的大小不同

Python—转换日期:价目表到新行

具有相同图例 colored颜色 和标签的堆叠子图

OpenGL仅渲染第二个三角形,第一个三角形不可见

并行编程:同步进程

为用户输入的整数查找根/幂整数对的Python练习

仅使用预先计算的排序获取排序元素

使用SQLAlchemy从多线程Python应用程序在postgr中插入多行的最佳方法是什么?'

设置索引值每隔17行左右更改的索引

在matplotlib中重叠极 map 以创建径向龙卷风图

类型对象';敌人';没有属性';损害';

普洛特利express 发布的人口普查数据失败

Pandas:使列中的列表大小与另一列中的列表大小相同

当lambda函数作为参数传递时,pyo3执行