XML là cấu trúc giống cây, trong khi khung dữ liệu Pandas là cấu trúc giống bảng 2D. Vì vậy, không có cách tự động để chuyển đổi giữa hai. Bạn phải hiểu cấu trúc XML và biết cách bạn muốn ánh xạ dữ liệu của nó vào một bảng 2D. Vì vậy, mọi vấn đề XML-to-DataFrame là khác nhau.
XML của bạn có 2 DataSets, mỗi tệp chứa một số Series. Mỗi Series chứa một số yếu tố Obs.
Mỗi chuỗi có thuộc tính NAME và mỗi thuộc tính có thuộc tính OBS_STATUS, TIME_PERIOD và OBS_VALUE. Vì vậy, có lẽ nó sẽ là hợp lý để tạo ra một bảng với các cột NAME, OBS_STATUS, TIME_PERIOD và OBS_VALUE.
Tôi thấy việc kéo dữ liệu mong muốn ra khỏi XML phức tạp một chút, điều này khiến tôi nghi ngờ rằng tôi đã tìm ra cách tốt nhất để làm điều đó. Nhưng đây là một cách (PS ý tưởng bắt đầu với các dữ liệu XLS bảng giống như 2D Thomas Maloney nên cách đơn giản hơn.):
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)
sản lượng
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
Có thể trùng lặp [Làm cách nào để mở tệp Excel bằng Python?] (Http://stackoverflow.com/questions/3239207/how-can-i-open-an-excel-file-in-python) – poolie