Определите следующую функцию, создав словарь предков, начиная с узла и выше:
def parNames(node, root):
names = {}
while True:
node = parentMap[node]
if node is root:
return names
names[node.tag] = node.attrib['name']
Это понадобится позже. Он использует parentMap словарь, который будет создан в ближайшее время.
Прочитайте ваш входной файл:
tree = et.parse('tree.xml')
root = tree.getroot()
Фактическая обработка должна начаться с создания parent map - словарь, который для каждого узла возвращает своего родителя:
parentMap = {}
for parent in root.iter():
for child in parent:
parentMap[child] = parent
Чтобы создать исходные данные для вашего DataFrame, выполните:
rows = []
for it in root.iter('indicator'):
row = parNames(it, root)
row[it.tag] = it.text
rows.append(row)
Этот l oop создает список словарей (данные для каждой строки). Каждая строка (словарь) содержит:
- под iterator key - текст соответствующего узла,
- под «родительскими» ключами ( level_. .. ) name атрибуты всех родителей (возвращается функцией parNames ).
Следующим шагом является создание DataFrame:
df2 = pd.DataFrame(rows).fillna('').sort_index(axis=1)
И единственный шаг, который нужно сделать, - переместить столбец индикатор в последнюю позицию:
df2 = df2.reindex(df2.columns.drop('indicator')
.append(pd.Index(['indicator'])),axis=1)