Extracción de XML en el marco de datos con atributo principal como título de columna
Tengo miles de archivos XML que estaré procesando, y tienen un formato similar, pero diferentes nombres de padres y diferentes números de padres. A través de libros, google, tutoriales y simplemente probando códigos, he podido extraer toda esta información. Ver, por ejemplo:El análisis de xml al marco de datos pandas genera un error de memoria yBúsqueda dinámica a través de atributos xml usando lxml y xpath en python
Sin embargo, me di cuenta de que estaba extrayendo los datos de manera deficiente, con un "Tiempo" secundario repetido para cada padre.
Esto es lo que estoy tratando de conseguir.
Time blah abc
1200 100 2
1300 30 4
1400 70 2
Esto es lo que sé conseguir. Pero mi método actual es torpe (mostraré a continuación el ejemplo 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
Ejemplo de formato 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>
Aquí es cómo puedo obtener mi salida:
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})
Podría simplemente tomar esta salida y reformularla, pero eso parece ineficiente y un enfoque muy torpe.
Creo que necesito algo del sabor:
#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)