这是我的 previous question
的扩展:
低于df
:
In [225]: df = pd.DataFrame({'A': ['a'] * 12,
...: 'B': ['b'] * 12,
...: 'C': ['C1', 'C1', 'C2','C1', 'C3', 'C3', 'C2', 'C3', 'C3', 'C2', 'C2', 'C1'],
...: 'D': ['D1', 'D2', 'D1', 'D3', 'D3', 'D2', 'D4', 'all', 'D1', '0:1:all', 'D3', 'x:all:1'],
...: 'E': [{'value': '4', 'percentage': None}, {'value': 5, 'percentage': None}, {'value': 12, 'percentage': None}, {'value': 9, 'percentage': None}, {'value': '12', 'percentage': None}, {'value': 'N/A', 'percentage': None}, {}, {'val
...: ue': 24, 'percentage': None}, {'value': 12, 'percentage': None}, {'value': 33, 'percentage': None}, {'value': 11, 'percentage': None}, {'value': '9', 'percentage': None}]})
...:
上面 df 的透视
:
In [227]: x = df.pivot(['B', 'C', 'D'], 'A', ['E'])
In [228]: x
Out[228]:
E
A a
B C D
b C1 D1 {'value': '4', 'percentage': None}
D2 {'value': 5, 'percentage': None}
D3 {'value': 9, 'percentage': None}
x:all:1 {'value': '9', 'percentage': None}
C2 0:1:all {'value': 33, 'percentage': None}
D1 {'value': 12, 'percentage': None}
D3 {'value': 11, 'percentage': None}
D4 {}
C3 D1 {'value': 12, 'percentage': None}
D2 {'value': 'N/A', 'percentage': None}
D3 {'value': '12', 'percentage': None}
all {'value': 24, 'percentage': None}
我想根据字典中的值键,根据索引为(E,a)的多级列,按升序/降序顺序对每组外部列 B 和 C 的最内列 D 进行排序。
但是,对于每个组,都会有一行包含所有其他行的总值。 包含总计的行由子字符串中包含all
的值标识。无论排序顺序如何(升序或降序),我总是需要将该行保留在最后。
asc 情况下的预期输出:
Out[228]:
E
A a
B C D
b C1 D1 {'value': '4', 'percentage': None}
D2 {'value': 5, 'percentage': None}
D3 {'value': 9, 'percentage': None}
x:all:1 {'value': '9', 'percentage': None}
C2 D3 {'value': 11, 'percentage': None}
D1 {'value': 12, 'percentage': None}
D4 {}
0:1:all {'value': 33, 'percentage': None}
C3 D1 {'value': 12, 'percentage': None}
D3 {'value': '12', 'percentage': None}
D2 {'value': 'N/A', 'percentage': None}
all {'value': 24, 'percentage': None}
desc 情况下的预期输出:
Out[228]:
E
A a
B C D
b C1 D3 {'value': 9, 'percentage': None}
D2 {'value': 5, 'percentage': None}
D1 {'value': '4', 'percentage': None}
x:all:1 {'value': '9', 'percentage': None}
C2 D1 {'value': 12, 'percentage': None}
D3 {'value': 11, 'percentage': None}
D4 {}
0:1:all {'value': 33, 'percentage': None}
C3 D1 {'value': 12, 'percentage': None}
D3 {'value': '12', 'percentage': None}
D2 {'value': 'N/A', 'percentage': None}
all {'value': 24, 'percentage': None}
最佳答案
使用Index.get_level_values
与 str.contains
用于测试全部
:
lvls = list(x.index.names[:-1])
print (lvls)
['B', 'C']
x[('tmp', 'tmp')] = pd.to_numeric(x[('E','a')].str.get('value'), errors='coerce')
x[('max','tmp')] = x.index.get_level_values(-1).str.contains('all')
x1 = x.sort_values(lvls + [('max','tmp'), ('tmp','tmp')])
print (x1)
E tmp max
A a tmp tmp
B C D
b C1 D1 {'value': '4', 'percentage': None} 4.0 False
D2 {'value': 5, 'percentage': None} 5.0 False
D3 {'value': 9, 'percentage': None} 9.0 False
x:all:1 {'value': '9', 'percentage': None} 9.0 True
C2 D3 {'value': 11, 'percentage': None} 11.0 False
D1 {'value': 12, 'percentage': None} 12.0 False
D4 {} NaN False
0:1:all {'value': 33, 'percentage': None} 33.0 True
C3 D1 {'value': 12, 'percentage': None} 12.0 False
D3 {'value': '12', 'percentage': None} 12.0 False
D2 {'value': 'N/A', 'percentage': None} NaN False
all {'value': 24, 'percentage': None} 24.0 True
还有:
x2 = x.sort_values(lvls + [('max','tmp'), ('tmp','tmp')],
ascending=[True] * len(lvls) + [True, False])
print (x2)
E tmp max
A a tmp tmp
B C D
b C1 D3 {'value': 9, 'percentage': None} 9.0 False
D2 {'value': 5, 'percentage': None} 5.0 False
D1 {'value': '4', 'percentage': None} 4.0 False
x:all:1 {'value': '9', 'percentage': None} 9.0 True
C2 D1 {'value': 12, 'percentage': None} 12.0 False
D3 {'value': 11, 'percentage': None} 11.0 False
D4 {} NaN False
0:1:all {'value': 33, 'percentage': None} 33.0 True
C3 D1 {'value': 12, 'percentage': None} 12.0 False
D3 {'value': '12', 'percentage': None} 12.0 False
D2 {'value': 'N/A', 'percentage': None} NaN False
all {'value': 24, 'percentage': None} 24.0 True
最后删除辅助列:
x1 = x1.drop([('max','tmp'), ('tmp','tmp')], axis=1)
x2 = x2.drop([('max','tmp'), ('tmp','tmp')], axis=1)
关于python - Pandas:根据多级列对最里面的列进行分组排序,不包括与某个子字符串匹配的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65217755/