Wyodrębnianie XML do ramki danych z atrybutem rodzica jako tytuł kolumny
Mam tysiące plików XML, które będę przetwarzać, i mają podobny format, ale różne nazwy rodziców i różne liczby rodziców. Dzięki książkom, google, samouczkom i próbom kodów udało mi się wyciągnąć wszystkie te dane. Zobacz na przykład:Przetwarzanie ramki danych xml na pandas powoduje błąd pamięci iDynamiczne wyszukiwanie za pomocą atrybutów XML za pomocą lxml i xpath w python
Jednak zdałem sobie sprawę, że wyodrębniam dane słabo, z dzieckiem „Czas” powtarzanym dla każdego rodzica.
Oto, co próbuję uzyskać.
Time blah abc
1200 100 2
1300 30 4
1400 70 2
Oto, co wiem, jak zdobyć. Ale moja obecna metoda jest niezgrabna (pokażę poniżej przykładowy XML)
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
Przykładowy format XML
<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>
Oto jak mogę uzyskać moje dane wyjściowe:
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})
Mógłbym po prostu wziąć to wyjście i zmienić jego kształt, ale to wydaje się nieefektywne i bardzo przylegające.
Myślę, że potrzebuję czegoś o smaku:
#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)