为了账号安全,请及时绑定邮箱和手机立即绑定

MultiIndex 上的 Pandas set_levels:级别值必须是唯一的

MultiIndex 上的 Pandas set_levels:级别值必须是唯一的

慕神8447489 2021-07-21 17:01:03
给定一个数据帧 df                    ValueCategory Pool Class      A        1.0  1.0       1              9.0       2B        1.0  1.0       3C        1.0  1.0       4              5.0       5我想在没有(见下文)的情况下将级别Pool和Class整数转换为整数reset_index。我尝试使用get_level_values和set_levels像这样的组合for c in ['Pool', 'Class']:    df.index.set_levels(df.index.get_level_values(c).astype(int), level=c, inplace=True)然而,这引发了ValueError: Level values must be unique: [1, 1, 1, 1, 1] on level 1为了了解会发生什么,我还尝试使用verify_integrity=False. 然后df.index.set_levels(df.index.get_level_values('Class').astype(int),                    level='Class', verify_integrity=False, inplace=True)产生                    ValueCategory Pool Class      A        1.0  1         1              1         2B        1.0  1         3C        1.0  1         4              9         5而我的目标是获得                    ValueCategory Pool Class      A        1.0  1         1              9         2B        1.0  1         3C        1.0  1         4              5         5如何正确实现这一目标?是链接get_level_values和set_levels正确的方法吗?为什么pandas在用 转换后无法正确设置级别astype?我想你可以使用reset_index,set_index但是拥有这些方法有什么好处set_levels?d = {'Category': str, 'Pool': int, 'Class': int}df.reset_index(drop=False, inplace=True)for k, v in d.items():    df[k] = df[k].astype(v)df.set_index(list(d.keys()), inplace=True)
查看完整描述

2 回答

?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

您可以通过以下方式直接访问索引级别pd.MultiIndex.levels并提供给pd.MultiIndex.set_levels:


df.index = df.index.set_levels(df.index.levels[2].astype(int), level=2)


print(df)


                     Value

Category Pool Class       

A        1.0  1          1

              9          2

B        1.0  1          3

C        1.0  1          4

              5          5


查看完整回答
反对 回复 2021-07-27
?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

以下函数可用作 的补充get_level_values:


def set_level_values(midx, level, values):

    full_levels = list(zip(*midx.values))

    names = midx.names

    if isinstance(level, str):

        if level not in names:

            raise ValueError(f'No level {level} in MultiIndex')

        level = names.index(level)

    if len(full_levels[level]) != len(values):

        raise ValueError('Values must be of the same size as original level')

    full_levels[level] = values

    return pd.MultiIndex.from_arrays(full_levels, names=names)

使用此函数,原始问题的解决方案是:


for c in ['Pool', 'Class']:

    df.index = set_level_values(df.index, level=c, values=df.index.get_level_values(c).astype(int))



查看完整回答
反对 回复 2021-07-27
  • 2 回答
  • 0 关注
  • 426 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信