使用pandas展平嵌套XML 解决read_xml嵌套列返回NaN问题
问题原因
pd.read_xml()默认只会提取指定XPath路径下直接子节点的文本内容,你案例里的ettevotja_aadress节点本身没有直属文本,所有有效内容都存储在它的子节点中,所以默认读取时该列会全部返回NaN,不需要手动修改XML源文件,用pandas原生能力就能实现嵌套展平。
实现方案
方案1:分块读取后按索引拼接(零额外依赖,适合简单嵌套)
XML中每个<ettevotja>主节点和内部的<ettevotja_aadress>子节点是严格一一对应的,解析后的行顺序完全匹配,分别读取两个层级的数据后直接横向拼接即可:
import pandas as pd # 读取企业主表数据,删除全为NaN的嵌套地址列 df_main = pd.read_xml( "test_file.xml", xpath=".//ettevotja" ).drop(columns=["ettevotja_aadress"]) # 单独读取嵌套的地址节点数据 df_address = pd.read_xml( "test_file.xml", xpath=".//ettevotja_aadress" ) # 两表行顺序完全对应,直接拼接得到展平后的完整表 df_flat = pd.concat([df_main, df_address], axis=1)
运行后地址节点下的asukoht_ettevotja_aadressis、asukoha_ehak_kood、ads_normaliseeritud_taisaadress等7个子字段会全部展开为独立列,空值自动填充为NaN,效果和json_normalize处理嵌套JSON一致。
方案2:XSLT预转换一次性读取(适合多层复杂嵌套)
如果XML嵌套层级更多,不想分多次读取拼接,可以给read_xml传入一段极简XSLT样式表,在解析阶段就把嵌套子节点提升到主节点同级,一次性读入完整展平数据:
import pandas as pd # 定义展平嵌套地址节点的XSLT规则 flatten_xslt = """ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="no"/> <!-- 默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配到地址节点时,不输出节点本身,仅输出它的所有子节点 --> <xsl:template match="ettevotja_aadress"> <xsl:apply-templates select="@*|node()"/> </xsl:template> </xsl:stylesheet> """ # 传入样式表一次性读取展平数据 df_flat = pd.read_xml( "test_file.xml", xpath=".//ettevotja", stylesheet=flatten_xslt )
该方法不需要后续拼接操作,嵌套层级越多效率优势越明显。
不建议手动修改XML源文件删除标签的处理方式:不仅容易破坏XML结构合法性,处理大文件时效率极低,上述两种方案均为pandas原生支持的能力,无需改动源文件。
内容的提问来源于stack exchange,提问作者chitown88
相关产品推荐
相关产品推荐

