将xml压平成pandas数据帧,深度嵌套

时间:2017-04-29 09:29:18

标签: python xml pandas

我认为这可能很容易,我还没想到它。

目标是“平坦化”。进入熊猫DataFrame。

Here is one xml(直接下载60~MB的zip文件,提取膨胀到800~MB左右。)

我尝试了以下两种方法:

第一个来自here,已被修改了一点:

def xml2dfa(xml_data):
    tree = ET.parse(xml_data)
    root = tree.getroot()[1] # Modification here
    all_records = []
    headers = []
    for i, child in enumerate(root):
        record = []
        for subchild in child:
            record.append(subchild.text)
            if subchild.tag not in headers:
                headers.append(subchild.tag)
        all_records.append(record)
    return pd.DataFrame(all_records, columns=headers)

第3行(root)已修改为获取元素LEIRecords而不是LEIHeader

之前的结果是DataFrame的行数正确但只有4列:

array(['{http://www.leiroc.org/data/schema/leidata/2014}LEI',
   '{http://www.leiroc.org/data/schema/leidata/2014}Entity',
   '{http://www.leiroc.org/data/schema/leidata/2014}Registration',
   '{http://www.leiroc.org/data/schema/leidata/2014}Extension'], dtype=object)

从第2列到第4列,仍然存在可以提取信息的嵌套子项,但所有信息都会丢失,因为任何列的唯一值都是如下所示的数组:

array(['\n        '], dtype=object)

第二种方法我已经跑了至少16个小时,没有结果,所以有些事情是不对的。我从here那里拿走了它。

预期的输出将是一个完全平坦的DataFrame,并且不存在任何信息(因为特定的树分支没有那么远,或者没有填充,填充NaN({{3} })

1 个答案:

答案 0 :(得分:3)

我遇到了类似的问题。我从ebscohost获得了关于从搜索返回的研究文章的xml。

使用xmltodict https://github.com/martinblech/xmltodict

import xmltodict

with open(filename) as fd:
    doc = xmltodict.parse(fd.read())

这将xml转换为嵌套字典

使用堆栈溢出链接中的示例代码

def flatten_dict(dd, separator='_', prefix=''):
    return { prefix + separator + k if prefix else k : v
             for kk, vv in dd.items()
             for k, v in flatten_dict(vv, separator, kk).items()
             } if isinstance(dd, dict) else { prefix : dd }

我在个别文章的层面上压扁了这个词(在我的案例中有两个级别 - doc ['记录'] [' rec'])

flattened_doc = [flatten_dict(x) for x in doc['records']['rec']]

然后从结果列表中创建一个Dataframe

data1 = pd.DataFrame(flattened_doc)

有些专栏仍然包含dicts,但它处于我不关心的水平。压缩字典的功能只会在写入时向下平整两个级别。