Панды set_levels в MultiIndex: значения уровня должны быть уникальными - PullRequest
0 голосов
/ 22 октября 2018

Учитывая DataFrame df

                    Value
Category Pool Class      
A        1.0  1.0       1
              9.0       2
B        1.0  1.0       3
C        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)

производит

                    Value
Category Pool Class      
A        1.0  1         1
              1         2
B        1.0  1         3
C        1.0  1         4
              9         5

, тогда как моя цель - получить

                    Value
Category Pool Class      
A        1.0  1         1
              9         2
B        1.0  1         3
C        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)

1 Ответ

0 голосов
/ 22 октября 2018

Вы можете получить доступ к уровням индекса напрямую через 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
...