将不一致的XML有效地解析为pandas数据帧

时间:2017-08-21 19:11:56

标签: python xml pandas xml-parsing

这个问题是关于使用以下结构解析不一致的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的新手所以我将感激你的耐心。

1 个答案:

答案 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