在一个级别和每个分区按较早级别对索引进行排序

Sort index at a level and per partitioning by earlier levels

我正在使用 pandas 来计算不同的类型或错误并纠正不同(机器学习)模型的预测,以显示混淆矩阵。

预测和基本事实标签的特定顺序是有意义的,例如将多数 class 'B' 放在第一位。

但是,当我使用 pd.DataFrame.sort_index 排序时,其他索引级别也被排列。我想根据第一个索引的唯一值对第二级进行排序。

errors = pd.DataFrame([
  {'model': model, 'ground truth': ground_truth, 'prediction': prediction,
  'count': np.random.randint(0, (10000 if prediction=='B' else 1000) if prediction==ground_truth else 100)}
  for model in ['foo', 'bar']
  for prediction in 'ABC'
  for ground_truth in 'ABC'

])

def sort_index(index):
  return index.map('BCA'.index)

errors.pivot(
  index=['model', 'ground truth'],
  columns=['prediction'],
  values='count'
).fillna(0).astype(int).sort_index(level=1, key=sort_index)[['B', 'C', 'A']]

一种解决方案是也按所有较早的索引进行排序,但它非常冗长。将一个函数应用于所有索引是愚蠢的,就好像它们在语义上都是相同的一样。此外,这还会重新排列模型的顺序,这并不是必需的。最后,它在两个方面浪费了计算:对较小的分区进行排序速度更快,因为排序超线性缩放,并且在考虑更多索引时元素比较更慢。

def sort_index(index):
  if index.name == 'ground truth':
    return index.map('BCA'.index)
  return index

errors.pivot(
  index=['model', 'ground truth'],
  columns=['prediction'],
  values='count'
).fillna(0).astype(int).sort_index(level=[0, 1], key=sort_index)[['B', 'C', 'A']]

是否有一种干净的方法来对较高的索引级别进行排序,同时将较早的级别保持在一起?

您可能想使用 reindex 方法。

代码:

import numpy as np
import pandas as pd

# Create a sample dataframe
errors = pd.DataFrame([ {'model': model, 'ground truth': ground_truth, 'prediction': prediction, 'count': np.random.randint(0, (10000 if prediction=='B' else 1000) if prediction==ground_truth else 100)} for model in ['foo', 'bar'] for prediction in 'ABC' for ground_truth in 'ABC' ])

# Pivot and reindex the dataframe
errors.pivot(
  index=['model', 'ground truth'],
  columns=['prediction'],
  values='count'
).fillna(0).astype(int).reindex(['B', 'C', 'A'], level=1)[['B', 'C', 'A']]

输出: