【问题标题】:Flatten a nested xml with pandas用 pandas 展平嵌套的 xml
【发布时间】:2022-06-11 03:04:47
【问题描述】:

我有以下格式的xml:

<?xml version='1.0' encoding='UTF-8'?>
<ettevotjad>
  <ettevotja>
    <nimi>000 Holdings OÜ</nimi>
    <ariregistri_kood>16372442</ariregistri_kood>
    <ettevotja_oiguslik_vorm>Osaühing</ettevotja_oiguslik_vorm>
    <ettevotja_oigusliku_vormi_alaliik/>
    <kmkr_nr/>
    <ettevotja_staatus>R</ettevotja_staatus>
    <ettevotja_staatus_tekstina>Registrisse kantud</ettevotja_staatus_tekstina>
    <ettevotja_esmakande_kpv>23.11.2021</ettevotja_esmakande_kpv>
    <ettevotja_aadress>
      <asukoht_ettevotja_aadressis/>
      <asukoha_ehak_kood/>
      <asukoha_ehak_tekstina></asukoha_ehak_tekstina>
      <indeks_ettevotja_aadressis/>
      <ads_adr_id></ads_adr_id>
      <ads_ads_oid></ads_ads_oid>
      <ads_normaliseeritud_taisaadress/>
    </ettevotja_aadress>
    <teabesysteemi_link>https://ariregister.rik.ee/est/company/16372442</teabesysteemi_link>
  </ettevotja>
  <ettevotja>
    <nimi>001 group OÜ</nimi>
    <ariregistri_kood>12754230</ariregistri_kood>
    <ettevotja_oiguslik_vorm>Osaühing</ettevotja_oiguslik_vorm>
    <ettevotja_oigusliku_vormi_alaliik/>
    <kmkr_nr/>
    <ettevotja_staatus>R</ettevotja_staatus>
    <ettevotja_staatus_tekstina>Registrisse kantud</ettevotja_staatus_tekstina>
    <ettevotja_esmakande_kpv>17.11.2014</ettevotja_esmakande_kpv>
    <ettevotja_aadress>
      <asukoht_ettevotja_aadressis>Õismäe tee 78-9</asukoht_ettevotja_aadressis>
      <asukoha_ehak_kood>0176</asukoha_ehak_kood>
      <asukoha_ehak_tekstina>Haabersti linnaosa, Tallinn, Harju maakond</asukoha_ehak_tekstina>
      <indeks_ettevotja_aadressis>13513</indeks_ettevotja_aadressis>
      <ads_adr_id>2182337</ads_adr_id>
      <ads_ads_oid></ads_ads_oid>
      <ads_normaliseeritud_taisaadress>Harju maakond, Tallinn, Haabersti linnaosa, Õismäe tee 78-9</ads_normaliseeritud_taisaadress>
    </ettevotja_aadress>
    <teabesysteemi_link>https://ariregister.rik.ee/est/company/12754230</teabesysteemi_link>
  </ettevotja>
</ettevotjad>

使用pandas'.read_xml() 产生:

 import pandas as pd

 data = pd.read_xml('test_file.xml')

 print(data.head(2).to_string())
              nimi  ariregistri_kood ettevotja_oiguslik_vorm  ettevotja_oigusliku_vormi_alaliik kmkr_nr ettevotja_staatus ettevotja_staatus_tekstina ettevotja_esmakande_kpv  ettevotja_aadress                               teabesysteemi_link
0  000 Holdings OÜ          16372442                Osaühing                                NaN    None                 R         Registrisse kantud              23.11.2021                NaN  https://ariregister.rik.ee/est/company/16372442
1     001 group OÜ          12754230                Osaühing                                NaN    None                 R         Registrisse kantud              17.11.2014                NaN  https://ariregister.rik.ee/est/company/12754230

注意数据框中的'ettevotja_aadress'NaN,但实际上如果您查看xml 结构,它与那些子列/标题嵌套在一起。如何将这些嵌套列展开到数据框中?

我认为一种方法是简单地读取文件,删除&lt;ettevotja_aadress&gt;&lt;ettevotja_aadress&gt;标签,然后读入pandas,但似乎应该有直接的方法来做到这一点,类似到pandas'.json_normalize()

【问题讨论】:

    标签: python pandas xml


    【解决方案1】:

    因此,一种解决方法是您可以明确节点的路径,在本例中为ettevotja_aadress。然后可以合并/合并到原始数据帧。如果有人有直接通过.read_xml() 执行此操作的解决方案,请分享:

    data = pd.read_xml(xml_data_source)
    dataAddress = pd.read_xml(xml_data_source, xpath=".//ettevotja_aadress")
    data = pd.concat([data, dataAddress], axis=1)
    data = data.drop('ettevotja_aadress', axis=1)
    

    输出:

    print(data.head(2).to_string())
                  nimi  ariregistri_kood ettevotja_oiguslik_vorm  ettevotja_oigusliku_vormi_alaliik kmkr_nr ettevotja_staatus ettevotja_staatus_tekstina ettevotja_esmakande_kpv  ettevotja_aadress                               teabesysteemi_link asukoht_ettevotja_aadressis  asukoha_ehak_kood                       asukoha_ehak_tekstina  indeks_ettevotja_aadressis  ads_adr_id  ads_ads_oid                              ads_normaliseeritud_taisaadress
    0  000 Holdings OÜ          16372442                Osaühing                                NaN    None                 R         Registrisse kantud              23.11.2021                NaN  https://ariregister.rik.ee/est/company/16372442                        None                NaN                                        None                         NaN         NaN          NaN                                                         None
    1     001 group OÜ          12754230                Osaühing                                NaN    None                 R         Registrisse kantud              17.11.2014                NaN  https://ariregister.rik.ee/est/company/12754230             Õismäe tee 78-9              176.0  Haabersti linnaosa, Tallinn, Harju maakond                     13513.0   2182337.0          NaN  Harju maakond, Tallinn, Haabersti linnaosa, Õismäe tee 78-9
    

    【讨论】:

      【解决方案2】:

      这可以通过提供一个 XSL 样式表来展平原始 XML 来完成。代码如下所示:

      xml = '''<?xml version='1.0' encoding='UTF-8'?>
      <ettevotjad>
        <ettevotja>
          <nimi>000 Holdings OÜ</nimi>
          <ariregistri_kood>16372442</ariregistri_kood>
          <ettevotja_oiguslik_vorm>Osaühing</ettevotja_oiguslik_vorm>
          <ettevotja_oigusliku_vormi_alaliik/>
          <kmkr_nr/>
          <ettevotja_staatus>R</ettevotja_staatus>
          <ettevotja_staatus_tekstina>Registrisse kantud</ettevotja_staatus_tekstina>
          <ettevotja_esmakande_kpv>23.11.2021</ettevotja_esmakande_kpv>
          <ettevotja_aadress>
            <asukoht_ettevotja_aadressis/>
            <asukoha_ehak_kood/>
            <asukoha_ehak_tekstina></asukoha_ehak_tekstina>
            <indeks_ettevotja_aadressis/>
            <ads_adr_id></ads_adr_id>
            <ads_ads_oid></ads_ads_oid>
            <ads_normaliseeritud_taisaadress/>
          </ettevotja_aadress>
          <teabesysteemi_link>https://ariregister.rik.ee/est/company/16372442</teabesysteemi_link>
        </ettevotja>
        <ettevotja>
          <nimi>001 group OÜ</nimi>
          <ariregistri_kood>12754230</ariregistri_kood>
          <ettevotja_oiguslik_vorm>Osaühing</ettevotja_oiguslik_vorm>
          <ettevotja_oigusliku_vormi_alaliik/>
          <kmkr_nr/>
          <ettevotja_staatus>R</ettevotja_staatus>
          <ettevotja_staatus_tekstina>Registrisse kantud</ettevotja_staatus_tekstina>
          <ettevotja_esmakande_kpv>17.11.2014</ettevotja_esmakande_kpv>
          <ettevotja_aadress>
            <asukoht_ettevotja_aadressis>Õismäe tee 78-9</asukoht_ettevotja_aadressis>
            <asukoha_ehak_kood>0176</asukoha_ehak_kood>
            <asukoha_ehak_tekstina>Haabersti linnaosa, Tallinn, Harju maakond</asukoha_ehak_tekstina>
            <indeks_ettevotja_aadressis>13513</indeks_ettevotja_aadressis>
            <ads_adr_id>2182337</ads_adr_id>
            <ads_ads_oid></ads_ads_oid>
            <ads_normaliseeritud_taisaadress>Harju maakond, Tallinn, Haabersti linnaosa, Õismäe tee 78-9</ads_normaliseeritud_taisaadress>
          </ettevotja_aadress>
          <teabesysteemi_link>https://ariregister.rik.ee/est/company/12754230</teabesysteemi_link>
        </ettevotja>
      </ettevotjad>
      '''
      
      import pandas as pd
      
      stylesheet = '''<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output indent="yes"/>
      <xsl:template match="/">
          <ettevotjad>
              <xsl:apply-templates select="//ettevotja"/>
          </ettevotjad>
      </xsl:template>
      <xsl:template match="ettevotja">
          <ettevotja>
            <xsl:copy-of select="node()[not(self::ettevotja_aadress)]"/>
            <xsl:apply-templates select="./ettevotja_aadress"/>
          </ettevotja>
       </xsl:template>
       <xsl:template match="ettevotja_aadress">
          <xsl:copy-of select="node()"/>
        </xsl:template>
       </xsl:stylesheet>
      '''
      
      df = pd.read_xml(xml, xpath="//ettevotja", stylesheet = stylesheet)
      
      df.head()
      

      代码背后的想法是将 XSL 转换应用于 XML 文档,使其结构扁平化。转换的结果将是:

      <?xml version="1.0" encoding="UTF-8"?>
      <ettevotjad>
         <ettevotja>
            <nimi>000 Holdings OÜ</nimi>
            <ariregistri_kood>16372442</ariregistri_kood>
            <ettevotja_oiguslik_vorm>Osaühing</ettevotja_oiguslik_vorm>
            <ettevotja_oigusliku_vormi_alaliik/>
            <kmkr_nr/>
            <ettevotja_staatus>R</ettevotja_staatus>
            <ettevotja_staatus_tekstina>Registrisse kantud</ettevotja_staatus_tekstina>
            <ettevotja_esmakande_kpv>23.11.2021</ettevotja_esmakande_kpv>
            <teabesysteemi_link>https://ariregister.rik.ee/est/company/16372442</teabesysteemi_link>
        
            <asukoht_ettevotja_aadressis/>
            <asukoha_ehak_kood/>
            <asukoha_ehak_tekstina/>
            <indeks_ettevotja_aadressis/>
            <ads_adr_id/>
            <ads_ads_oid/>
            <ads_normaliseeritud_taisaadress/>
          </ettevotja>
         <ettevotja>
            <nimi>001 group OÜ</nimi>
            <ariregistri_kood>12754230</ariregistri_kood>
            <ettevotja_oiguslik_vorm>Osaühing</ettevotja_oiguslik_vorm>
            <ettevotja_oigusliku_vormi_alaliik/>
            <kmkr_nr/>
            <ettevotja_staatus>R</ettevotja_staatus>
            <ettevotja_staatus_tekstina>Registrisse kantud</ettevotja_staatus_tekstina>
            <ettevotja_esmakande_kpv>17.11.2014</ettevotja_esmakande_kpv>
            <teabesysteemi_link>https://ariregister.rik.ee/est/company/12754230</teabesysteemi_link>
        
            <asukoht_ettevotja_aadressis>Õismäe tee 78-9</asukoht_ettevotja_aadressis>
            <asukoha_ehak_kood>0176</asukoha_ehak_kood>
            <asukoha_ehak_tekstina>Haabersti linnaosa, Tallinn, Harju maakond</asukoha_ehak_tekstina>
            <indeks_ettevotja_aadressis>13513</indeks_ettevotja_aadressis>
            <ads_adr_id>2182337</ads_adr_id>
            <ads_ads_oid/>
            <ads_normaliseeritud_taisaadress>Harju maakond, Tallinn, Haabersti linnaosa, Õismäe tee 78-9</ads_normaliseeritud_taisaadress>
          </ettevotja>
      </ettevotjad>
      

      转换后,XPath //ettevotja 应用于转换结果,将 ettevotja 元素的子元素作为数据框行字段。

      【讨论】:

        猜你喜欢
        • 2019-11-15
        • 2021-12-31
        • 2023-03-07
        • 2021-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-11
        • 2016-12-01
        相关资源
        最近更新 更多