从 pandas pivot_table 重新排序多索引中的级别?

Reorder level in a multiindex from a pandas pivot_table?

这个问题很难说,不好意思。我有一个从我转置的 pivot_table 创建的多索引数据框,索引现在是列。我已经知道如何通过以下方式重新排序外部索引:

df[['Sunday', 'Monday', 'Tuesday', ...]] 

如您所见,外层是星期几,内层是我需要重新排序的。 我需要按照 'pre' 'day' 'twi'. 的顺序获得内部索引,并非所有日期都有所有内部级别值,例如。周日有 'pre' 和 'twi' 但没有 'day'。这是 pivot_table:

的创建
quantile_df = pd.DataFrame(quantile_list, columns=['error', 'weekday', 'sort', 'scaler'])
quantile_df = quantile_df.pivot_table(values='scaler', index='error', columns=['weekday', 'sort'])

last_week = sort_df[sort_df['volume'] > 5000].loc['2022-04-03':'2022-04-09',:].pivot_table(columns=['weekday', 'sort'])

如果需要更多上下文,请告诉我,

编辑:非常感谢 Code Different,我明白了!这是最终结果的图片:

您可以使用 CategoricalDtype。最好在数据透视之前更改列类型:

# Some sample data
import string
error = list(string.ascii_uppercase[:10])
weekday = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
sort_ = ["pre", "day", "twi"]

idx = pd.MultiIndex.from_product([error, weekday, sort_], names=["error", "weekday", "sort"])
df = pd.DataFrame({"value": np.random.randint(1, 100, len(idx))}, index=idx).reset_index()

# The code
# You can pick whatever day as first day of the week
weekdayDtype = pd.CategoricalDtype(["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], ordered=True)
sortDtype = pd.CategoricalDtype(["pre", "day", "twi"], ordered=True)

df["weekday"] = df["weekday"].astype(weekdayDtype)
df["sort"] = df["sort"].astype(sortDtype)
df.pivot(index="error", columns=["weekday", "sort"])

编辑:我的回答会按字母顺序对星期几进行排序,这可能不是您要查找的内容。我认为 Code Different 的答案更好!在 CategoricalDtype 上使用 pivot tables 的唯一问题是生成的 pivot table 将显示所有类别,而不仅仅是数据框中的类别,这对于大型数据集来说可能是个问题。 (例如,即使您的数据框只有星期六和星期日的值,它也会以一周中的所有 7 天为基准)

我过去遇到过完全相同的问题,最终在 MulitiIndex 中添加了一个辅助级别。它看起来有点乱,但它肯定会正确排列列

首先,创建一个字典,以便您可以映射所需的顺序

sort_order = {'pre':0,'day':1,'twi':2}

其次,使用from_arrays方法创建一个新的MultiIndex。

我们传入一个包含 3 个列表的列表。第一个和最后一个列表与原始数据透视 table 列没有变化。但是,第二个列表是我们使用列表理解来映射新排序顺序的地方。

new_idx = pd.MultiIndex.from_arrays(
                arrays=
                    [
                        [x[0] for x in last_week.columns], 
                        [sort_order[x[1]] for x in last_week.columns],
                        [x[1] for x in last_week.columns],
                    ],
                    names= ['weekday','sort_helper','sort']
                )

我们用新索引替换当前索引,然后在轴 1 上使用 sort_index。

last_week.columns = new_idx
last_week = last_week.sort_index(axis=1)

如果需要,我们可以删除辅助级别:

last_week.columns = last_week.columns.droplevel(1)

希望这对您有所帮助:)