【问题标题】:convert XML to DataFrame using python script使用 python 脚本将 XML 转换为 DataFrame
【发布时间】:2023-04-02 16:16:01
【问题描述】:

我正在尝试将以下 xml 数据转换为数据框。

<?xml version="1.0" encoding="utf-8"?>
<TEST>
    <Node1L1>1</Node1L1>
    <Node2L1>FP</Node2L1>
    <SUBL1>
        <M>
            <PAR>
                <NAME>A</NAME>
                <TYPE>f</TYPE>
                <DESC />
                <VAL>1,2,3,4,5,6</VAL>
            </PAR>
            <PAR>
                <NAME>B</NAME>
                <TYPE>f</TYPE>
                <DESC />
                <VAL>10,20,30,40,50,60</VAL>
            </PAR>
            <PAR>
                <NAME>C</NAME>
                <TYPE>f</TYPE>
                <DESC />
                <VAL>11,22,33,44,55,66</VAL>
            </PAR>
            <PAR>
                <NAME>D</NAME>
                <TYPE>f</TYPE>
                <DESC />
                <VAL>a,b,c,d,e,f</VAL>
            </PAR>
            <PAR>
                <NAME>E</NAME>
                <TYPE>f</TYPE>
                <DESC />
                <VAL>aa,bb,cc,dd,ee,ff</VAL>
            </PAR>
        </M>
        <M>
            <PAR>
                <NAME>A_test</NAME>
                <VAL>0.0,0.1,0.2,0.3,0.4,0.5</VAL>
            </PAR>
        </M>            
    </SUBL1>
</TEST>

我只需要提取名称 A,C,E

的第一个 M 标记 PAR 子节点

这只是一个示例文件,但我拥有的文件很大,在 2 个 M 标签中有很多 PAR 标签。我能够使用下面的代码进行 XML 转换,但它也需要第二个 M 标签 PAR 标签。

df = pd.read_xml(path2file, xpath="//*[local-name()='PAR']")

我正在尝试寻找一种方法来改进xpath= 字符串,以便它只会将第一个 M 标记数据提取到数据框中。 另外,如果有任何替代方法,请告诉我。我也想避免节点中的空 DESC 列。

【问题讨论】:

标签: python pandas xml dataframe lxml


【解决方案1】:

pandas.read_xml() 的文档中,您可以看到lxml 被用作默认解析器。

不幸的是,lxml (以及内置的xml.etree.ElementTree 不支持XPath 2.0,因此通用解决方案.//M[1]/PAR[NAME=('A','C','E')] 不适用。但我们可以使用XPath 1.0 替代方案——.//M[1]/PAR[NAME='A' or NAME='C' or NAME='E']

下一个是最终代码:

df = pd.read_xml(
    path2file,
    xpath=".//M[1]/PAR[NAME='A' or NAME='C' or NAME='E']"
)

附:还没有测试过,如果由于某种原因它不起作用,请戳我。

【讨论】:

  • 谢谢欧文。这行得通。我试图将过滤器列表作为本身传递,因此无法获得任何结果。谢谢。
  • @ArunakiriVenkatachalam,如果对你有帮助,你可以accept我的回答。
【解决方案2】:

见下文

import xml.etree.ElementTree as ET
import pandas as pd


xml = '''<?xml version="1.0" encoding="utf-8"?>
<TEST>
    <Node1L1>1</Node1L1>
    <Node2L1>FP</Node2L1>
    <SUBL1>
        <M>
            <PAR>
                <NAME>A</NAME>
                <TYPE>f</TYPE>
                <DESC />
                <VAL>1,2,3,4,5,6</VAL>
            </PAR>
            <PAR>
                <NAME>B</NAME>
                <TYPE>f</TYPE>
                <DESC />
                <VAL>10,20,30,40,50,60</VAL>
            </PAR>
            <PAR>
                <NAME>C</NAME>
                <TYPE>f</TYPE>
                <DESC />
                <VAL>11,22,33,44,55,66</VAL>
            </PAR>
            <PAR>
                <NAME>D</NAME>
                <TYPE>f</TYPE>
                <DESC />
                <VAL>a,b,c,d,e,f</VAL>
            </PAR>
            <PAR>
                <NAME>E</NAME>
                <TYPE>f</TYPE>
                <DESC />
                <VAL>aa,bb,cc,dd,ee,ff</VAL>
            </PAR>
        </M>
        <M>
            <PAR>
                <NAME>A_test</NAME>
                <VAL>0.0,0.1,0.2,0.3,0.4,0.5</VAL>
            </PAR>
        </M>            
    </SUBL1>
</TEST>'''

root = ET.fromstring(xml)
pars = list(root.find('.//M'))
data = [[p.text for p in  list(par) if p.text] for par in pars if par.find('NAME').text in ['A','C','E']]

df = pd.DataFrame(data,columns = ['NAME','TYPE','VAL'])
print(df)

输出

  NAME TYPE                VAL
0    A    f        1,2,3,4,5,6
1    C    f  11,22,33,44,55,66
2    E    f  aa,bb,cc,dd,ee,ff

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 2021-04-15
    • 2018-03-22
    • 2019-05-19
    • 1970-01-01
    相关资源
    最近更新 更多