这个问题是关于使用以下结构解析不一致的XML
<items>
<item>
<propertyA>1</propertyA>
<propertyB>B</propertyB>
<propertyC>2017</propertyC>
</item>
<item>
<propertyB>BB</propertyB>
<propertyD>D-2017</propertyD>
</item>
<item>
<propertyE>E</propertyE>
<propertyF>11:25</propertyF>
</item>
</items>
我希望每个项目都是数据框中的记录。最终的数据框应该具有所有属性A,B,C,D,E,F和记录应该具有NaN或其他东西以防它们没有这些值。
我现在这样做的方式是
def load_inconsistent_xml(xml):
root = ET.fromstring(xml)
frames = []
df = pd.DataFrame()
for child in root.iter('item'):
record = []
headers = []
for subchild in child:
headers.append(subchild.tag)
record.append(subchild.text)
s2 = pd.Series(record, index=headers)
df = df.append(s2, ignore_index=true)
if not df.empty:
df.columns = df.columns.str.lower()
return df
正如您可以看到的那样,我是通过将新的pd.Series附加到数据帧来实现的。这种方法似乎是防弹的(至少对我而言:D),我的数据一致。
问题是,使用100k项目效率非常低,需要很长时间。 你会推荐什么?
感谢您抽出宝贵时间回答我的问题。我是python的新手所以我将感激你的耐心。
答案 0 :(得分:0)
考虑使用pd.concat
(快速行/列绑定方法)附加数据帧而不是系列,如果数据帧列表中的列不对齐则填充NAN。此外,下面运行一个不同的解析,其中一个字典列表迭代地转换为dataframe:
import xml.etree.ElementTree as ET
import pandas as pd
xml_str = '''
<items>
<item>
<propertyA>1</propertyA>
<propertyB>B</propertyB>
<propertyC>2017</propertyC>
</item>
<item>
<propertyB>BB</propertyB>
<propertyD>D-2017</propertyD>
</item>
<item>
<propertyE>E</propertyE>
<propertyF>11:25</propertyF>
</item>
</items>'''
dfs = []
def load_inconsistent_xml(xml):
data = []; inner = {}
root = ET.fromstring(xml)
for child in root.iterfind('item'):
for grandchild in child.iterfind('./*'):
inner[grandchild.tag] = grandchild.text
data.append(inner)
dfs.append(pd.DataFrame(data))
data = []; inner = {}
finaldf = pd.concat(dfs).reset_index(drop=True)
print(finaldf)
# propertyA propertyB propertyC propertyD propertyE propertyF
# 0 1 B 2017 NaN NaN NaN
# 1 NaN BB NaN D-2017 NaN NaN
# 2 NaN NaN NaN NaN E 11:25