Как управлять диапазонами строк и столбцов с помощью двухуровневой индексации

У меня есть следующий фрейм данных, отображающий связь «один ко многим» между «курсами» и «уроками»:

   course_id       course_name  lesson_id     lesson_title
0          0          Learn C#          1              foo
1          0          Learn C#          2              bar
2          0          Learn C#          3              baz
3          1  Origami together          1        the crane
4          1  Origami together          2  crease patterns
5          2        WIP course          1        the first

Как мне отформатировать его так, чтобы:

  • каждая строка урока находится в пределах соответствующей строки курса

  • Столбцы lesson_id и lesson_title находятся под диапазоном общего столбца lessons.

как показано ниже:

                                            lessons
   course_id       course_name         id            title
0          0          Learn C#          1              foo
1                                       2              bar
2                                       3              baz
3          1  Origami together          1        the crane
4                                       2  crease patterns
5          2        WIP course          1        the first

и создаем результат, подобный этому, при экспорте в Excel:

Изучая подобные вопросы, я обнаружил, что принятые ответы включают использование мультииндекса, но в этом случае первый уровень индекса должен охватывать все столбцы, связанные с курсом.

Кроме того, стартовая таблица на самом деле генерируется динамически из соответствующих классов данных Course и Lesson, поэтому я боюсь, что этот подход не будет хорошо масштабироваться, если я добавлю атрибуты в класс Course.

В идеале я бы проиндексировал course_id и lesson_id, а затем указал, какие столбцы индексируются первым или вторым, таким образом избегая дублирования атрибутов курса для каждого урока;

Есть ли способ добиться этого?

0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если нужен MultiIndex в индексе и столбцах, можно использовать:

out = df.set_index(['course_id','course_name'])
out.columns = out.columns.str.split('_', expand=True)

Если вам нужны диапазоны строк для обоих уровней, вот трюк — вспомогательный столбец с пустыми строками:

out = df.assign(**{'':''}).set_index(['course_id','course_name', ''])
out.columns = out.columns.str.split('_', expand=True)

print (out)
                            lesson                 
                                id            title
course_id course_name                              
0         Learn C                1              foo
                                 2              bar
                                 3              baz
1         Origami together       1        the crane
                                 2  crease patterns
2         WIP course             1        the first

Если необходимо удалить третий столбец в Excel:

file = 'out.xlsx'
out.to_excel(file)

import xlwings as xw
wb = xw.Book(file)
wb.sheets['Sheet1'].range('C:C').delete()
wb.save(file)

Я применил ваш совет, и, несмотря на его включение в индекс, course_name по-прежнему повторяется для каждой строки. С другой стороны, колонка lesson получилась отличной.

Afelium 12.08.2024 13:32

@Afelium - Можешь проверить сейчас?

jezrael 12.08.2024 13:38

да, это исправило вывод при печати на консоли, хотя пустой столбец все еще виден при экспорте в Excel. Спасибо, что научили меня этому хаку, хотя, честно говоря, я надеялся на реальную поддержку панд, а не на обходные пути.

Afelium 12.08.2024 13:57

@Afelium — Не так просто, панды могут записывать данные только с помощью col/rowspan. Для удаления столбца C используется xlwings в отредактированном ответе.

jezrael 12.08.2024 14:12

Другие вопросы по теме