python - 将 xml 扁平化为 pandas 数据框,深度嵌套

标签 python xml pandas

我想这可能很容易,只是我还没有弄明白。

目标是“扁平化”成 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

前面的结果产生了正确行数但只有 4 列的 DataFrame:

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 ( as in this question )

最佳答案

我遇到了类似的问题。我从 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['records']['rec'])

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

然后根据结果列表制作一个Dataframe

data1 = pd.DataFrame(flattened_doc)

一些列仍然包含字典,但它处于我不关心的级别。扁平化字典的函数只会在写入时扁平化两个级别。

关于python - 将 xml 扁平化为 pandas 数据框,深度嵌套,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43693969/

相关文章:

python - 将多个 pandas 数据帧中的所有列连接到一个包含数据和列名称的数据帧中

python比较两个包含列表的字典并仅获取差异

c++ - QXmlStreamWriter 和西里尔文

android - 单选按钮波纹切断

javascript - 何时更喜欢 JSON 而不是 XML?

python - 获取 Pandas 系列字符串的第一个元素

pandas - 过滤每个 ID 在特定变量中具有相同值的行 - Pandas

python - 让 Python 在不同时间打印行

python - DRF获取OneToOne模型的所有字段

python - 如何在Python中预分配一定大小的缓冲区?