XML ist eine baumartige Struktur, während ein Pandas DataFrame eine 2D-Tabellenstruktur ist. Es gibt also keine automatische Möglichkeit, zwischen den beiden zu konvertieren. Sie müssen die XML-Struktur verstehen und wissen, wie Sie ihre Daten einer 2D-Tabelle zuordnen wollen. So ist jedes XML-zu-DataFrame-Problem anders.
Ihr XML verfügt über 2 DataSets, die jeweils eine Reihe von Serien enthalten. Jede Serie enthält eine Anzahl von Obs-Elementen.
Jede Serie verfügt über ein NAME-Attribut, und jede Ob-Eigenschaft hat die Attribute OBS_STATUS, TIME_PERIOD und OBS_VALUE. Vielleicht wäre es also sinnvoll, eine Tabelle mit den Spalten NAME, OBS_STATUS, TIME_PERIOD und OBS_VALUE zu erstellen.
Ich fand das Ziehen der gewünschten Daten aus dem XML ein wenig kompliziert, was mich zweifelhaft macht, dass ich den besten Weg gefunden habe, es zu tun. Aber hier ist ein Weg (PS Thomas Maloney Idee mit den 2D-tabellenartigen XLS Daten beginnen, sollten Art und Weise einfacher sein.):
import lxml.etree as ET
import pandas as pd
path = 'feds200628.xml'
def fast_iter(context, func, *args, **kwargs):
"""
http://lxml.de/parsing.html#modifying-the-tree
Based on Liza Daly's fast_iter
http://www.ibm.com/developerworks/xml/library/x-hiperfparse/
See also http://effbot.org/zone/element-iterparse.htm
http://stackoverflow.com/a/7171543/190597 (unutbu)
"""
for event, elem in context:
func(elem, *args, **kwargs)
# It's safe to call clear() here because no descendants will be
# accessed
elem.clear()
# Also eliminate now-empty references from the root node to elem
for ancestor in elem.xpath('ancestor-or-self::*'):
while ancestor.getprevious() is not None:
del ancestor.getparent()[0]
del context
data = list()
obs_keys = ['OBS_STATUS', 'TIME_PERIOD', 'OBS_VALUE']
columns = ['NAME'] + obs_keys
def process_obs(elem, name):
dct = elem.attrib
# print(dct)
data.append([name] + [dct[key] for key in obs_keys])
def process_series(elem):
dct = elem.attrib
# print(dct)
context = ET.iterwalk(
elem, events=('end',),
tag='{http://www.federalreserve.gov/structure/compact/common}Obs'
)
fast_iter(context, process_obs, dct['SERIES_NAME'])
def process_dataset(elem):
nsmap = elem.nsmap
# print(nsmap)
context = ET.iterwalk(
elem, events=('end',),
tag='{{{prefix}}}Series'.format(prefix=elem.nsmap['kf'])
)
fast_iter(context, process_series)
with open(path, 'rb') as f:
context = ET.iterparse(
f, events=('end',),
tag='{http://www.federalreserve.gov/structure/compact/common}DataSet'
)
fast_iter(context, process_dataset)
df = pd.DataFrame(data, columns=columns)
Ausbeuten
NAME OBS_STATUS TIME_PERIOD OBS_VALUE
0 SVENY01 A 1961-06-14 2.9825
1 SVENY01 A 1961-06-15 2.9941
2 SVENY01 A 1961-06-16 3.0012
3 SVENY01 A 1961-06-19 2.9949
4 SVENY01 A 1961-06-20 2.9833
5 SVENY01 A 1961-06-21 2.9993
6 SVENY01 A 1961-06-22 2.9837
...
1029410 TAU2 A 2014-09-19 3.72896779
1029411 TAU2 A 2014-09-22 3.12836171
1029412 TAU2 A 2014-09-23 3.20146575
1029413 TAU2 A 2014-09-24 3.29972110
Mögliches Duplikat von [Wie kann ich eine Excel-Datei in Python öffnen?] (Http://stackoverflow.com/questions/3239207/how-can-i-open-an-excel-file-in-python) – poolie