Почему pd.MultiIndex.from_tuples меняет порядок кортежей - PullRequest
0 голосов
/ 18 января 2019

Когда создается мультииндекс с использованием from_tuples, объект создания индекса имеет другой порядок, чем входной кортеж

Я пытаюсь добавить уровень столбца к фрейму данных, используя метод pd.MultiIndex.from_tuples, но уровни отличаются от того, что я ожидал.

df = pd.DataFrame({'x_1':[1, 2], 'x_2':[3, 4], 'x_10':[3, 4], 'y_1':[5, 6], 'y_2':[7, 8], 'y_10':[1, 2]})
df = df.reindex(columns=['x_1', 'x_2', 'x_10', 'y_1', 'y_2', 'y_10'])
index = pd.MultiIndex.from_tuples([tuple(c.split('_')) for c in df.columns])
print(index)

MultiIndex(levels=[['x', 'y'], ['1', '10', '2']],
           labels=[[0, 0, 0, 1, 1, 1], [0, 2, 1, 0, 2, 1]])

Когда я добавляю уровень в фрейм данных и выполняю наложение, порядок не тот, который я хочу.

df.columns = index
df.stack()

      x  y
0 1   1  5
  10  3  1
  2   3  7
1 1   2  6
  10  4  2
  2   4  8

Я ожидаю, что уровни индекса будут выглядеть так:

MultiIndex(levels=[['x', 'y'], ['1', '2', '10']])

и укладка будет выглядеть следующим образом:

df.stack()
      x  y
0 1   1  5
  2   3  7
  10  3  1
1 1   2  6
  2   4  8
  10  4  2

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Вы можете reindex на определенном уровне, передавая значения уровня из вашего столбца до вызова stack:

In[177]:
df.stack().reindex(df.columns.get_level_values(1).unique(), level=1)
Out[177]: 
      x  y
0 1   1  5
  2   3  7
  10  3  1
1 1   2  6
  2   4  8
  10  4  2

Обратите внимание, что это приводит к проблемам с производительностью, поскольку ожидается, что индекс будет отсортирован для быстрого поиска

0 голосов
/ 18 января 2019

Индекс, который вы построили, на самом деле упорядочен как указано. Когда вы print(index) видите, как Панды хранят индекс внутри . Использование index.values раскрывает это представление, чтобы получить массив индексов, выровненных по вашему фрейму данных.

print(index.values)
# array([('x', '1'), ('x', '2'), ('x', '10'), ('y', '1'), ('y', '2'),
#        ('y', '10')], dtype=object)

df.columns = index 
print(df)    
#    x        y      
#    1  2 10  1  2 10
# 0  1  3  3  5  7  1
# 1  2  4  4  6  8  2

Реальная проблема заключается в pd.DataFrame.stack, применяющем сортировку, и, поскольку вы определили строки, '10' предшествует '2'. Чтобы поддерживать порядок по вашему желанию после stack, убедитесь, что вы используете целые числа:

def splitter(x):
    strng, num = x.split('_')
    return strng, int(num)

index = pd.MultiIndex.from_tuples(df.columns.map(splitter))

df.columns = index 
print(df.stack())
#       x  y
# 0 1   1  5
#   2   3  7
#   10  3  1
# 1 1   2  6
#   2   4  8
#   10  4  2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...