Extrahieren von XML in einen Datenrahmen mit dem übergeordneten Attribut als Spaltentitel
Ich habe Tausende von XML-Dateien, die ich verarbeiten werde, und sie haben ein ähnliches Format, aber unterschiedliche Elternnamen und eine unterschiedliche Anzahl von Eltern. Durch Bücher, Google, Tutorials und das Ausprobieren von Codes konnte ich all diese Daten herausholen. Siehe zum Beispiel:Das Parsen von XML in einen Pandadatenrahmen löst einen Speicherfehler aus undDynamische Suche durch XML-Attribute mit lxml und xpath in Python
Ich bemerkte jedoch, dass ich die Daten schlecht extrahierte und ein Kind die "Zeit" für jedes Elternteil wiederholte.
Hier ist was ich versuche zu bekommen.
Time blah abc
1200 100 2
1300 30 4
1400 70 2
Folgendes weiß ich zu bekommen. Aber meine derzeitige Methode ist klobig (ich zeige unten das XML-Beispiel)
child Time grandchild
0 blah 1200 100
1 blah 1300 30
...
n-2 abc 1200 2
n-1 abc 1300 4
n abc 1400 2
Beispiel XML-Format
<outer>
<inner>
<parent name = "blah" id = "1">
<child Time = "1200">
<grandchild>100</grandchild>
</child>
<child Time = "1300">
<grandchild>30</grandchild>
</child>
<child Time = "1400">
<grandchild>70</grandchild>
</child>
</parent>
<parent name = "abc" id = "2">
<child Time = "1200">
<grandchild>2</grandchild>
</child>
<child Time = "1300">
<grandchild>4</grandchild>
</child>
<child Time = "1400">
<grandchild>2</grandchild>
</child>
</parent>
<parent name = "1234" id = "7734">
<other> 12 </other>
</parent>
</inner>
</outer>
So kann ich meine Ausgabe erhalten:
from lxml import etree, objectify
from pandas import *
dTime=[]
dparent = []
dgrandchild=[]
for df in root.xpath('/*/*/*/parent/child'):
dparent.append(df.getparent().attrib['name'])
## Iterate over attributes of time for specific parent
for attrib in df.attrib:
dTime.append(df.attrib[attrib])
## grandchild is a child of time, and iterate
subfields = df.getchildren()
for subfield in subfields:
dgrandchild.append(subfield.text)
df=DataFrame({'Parent': dparent,'Time':dTime,'grandchild':dgrandchld})
Ich könnte diese Ausgabe einfach nehmen und neu gestalten, aber das scheint ineffizient und ein sehr klobiger Ansatz zu sein.
Ich denke, ich brauche etwas von dem Geschmack:
#this does not work
data = []
for elem in root.xpath('/*/*/*/parent/child'):
elem_data = {}
for attrib in elem.attrib:
elem_data['Time'] = elem.attrib[attrib])
for child in elem.getchildren():
elem_data[getparent().attrib['name'])] = child.text
data.append(elem_data)
ndata = DataFrame(data)