У меня есть многоуровневый Dataframe со столбцом под названием name
. Я хотел бы сохранить группировку данных на уровне родитель-потомок, но отсортировать каждый уровень A-Z по этому столбцу name
.
Другими словами, для каждой строки, если отсортирован родительский элемент, все дочерние элементы на более низком уровне также будут отсортированы в виде блока.
Вот пример моего текущего кадра данных:
df = pd.DataFrame(columns=['level', 'name'],
data=[['1','AAA'],
['1.1', 'ZZZ'],
['1.2', 'XXX'],
['1.3', 'YYY'],
['1.3.1', 'GGG'],
['1.3.1.1', 'XXX'],
['1.3.2', 'EEE'],
['1.3.3', 'FFF'],
['1.3.3.1', 'TTT'],
['1.3.3.2', 'SSS'],
['2', 'CCC'],
['3', 'BBB'],
['3.1', 'AAA']])
И как должен выглядеть отсортированный Dataframe:
sorted_df = pd.DataFrame(columns=['level', 'name'],
data=[['1','AAA'], # No Change
['1.1', 'XXX'], # Was 1.2
['1.2', 'YYY'], # Was 1.3
['1.2.1', 'EEE'], # Was 1.3.2
['1.2.2', 'FFF'], # Was 1.3.3
['1.2.3', 'GGG'], # Was 1.3.1
['1.2.3.1', 'XXX'], # Was 1.3.1.1
['1.2.3.1', 'SSS'], # Was 1.3.3.2
['1.2.3.2', 'TTT'], # was 1.3.3.1
['1.3', 'ZZZ'], # Was 1.1
['2', 'BBB'], # Was 3
['2.1', 'AAA'], # Was 3.1
['3', 'CCC']]) # Was 2
Разбиваем это на шаги:
Сортировка самого глубокого уровня (т.е. X.X.X.X) по имени. В оригинальном DF выше, 1.3.3.1 (SSS) и 1.3.3.2 (TTT) поменялись местами. 1.3.1.1 (XXX) остается прежним, поскольку в группе 1.3.1.X нет других элементов.
Посмотрите на следующий уровень вверх (т.е. X.X.X - GGG, EEE, FFF). 1.3.1 (GGG) и все, что находится ниже (т. Е. 1.3.1.1), должны двигаться ниже EEE и FFF (и их детей). EEE и FFF (и их дети) уже находятся в правильном положении.
Повторите этот процесс на следующих уровнях, сортируя родителей и всех их детей.
Я попытался разбить Dataframe на несколько индексов, разделив столбец уровня по точкам:
df = pd.concat([df['level'].str.split('.', expand=True), df], axis=1) \
.set_index([0,1,2,3])
Как только я дошел до этой точки, я как-то застрял. Я пробовал разные вещи (sort_value
, sort_index
, reset_index
и т. Д.), Но не смог разобраться (каламбур). Чтобы еще больше усложнить ситуацию, 'level'
может быть произвольной длины с моими реальными данными (например, 1.2.2.1.2.3.1 ...), а столбец имени также является произвольным (см., Как AAA повторяется на другом уровне в примере данные).
Это кажется простым делом, но я потратил пару часов на исследования и стучу головой, пытаясь понять это. Любая помощь будет принята с благодарностью !!