在Python中,如何使用xml.etree.ElementTree创建数据帧?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Python中,如何使用xml.etree.ElementTree创建数据帧?相关的知识,希望对你有一定的参考价值。

在Python 3中,我有一个XML文件,我想将其转换为pandas数据框

为此,我想到了使用xml.etree.ElementTree Python模块

XML具有此结构:

<?xml version="1.0" encoding="UTF-8"?>
<estacao_rd><row item="1" SiglaServico="TV" id="57dbaad053c60" state="TV-C1" entidade="X-MEDIAGROUP S.A." fistel="50410887137" cnpj="0321181400
0163" CodMunicipio="1200336" municipio="Mâncio Lima" uf="AC"><entidade entidade_nome_entidade="X-MEDIAGROUP S.A." entidade_nome_fantasia="" ent
idade_ddd="" entidade_telefone="" entidade_email="" entidade_codtipotaxa="" entidade_tipotaxa="" entidade_idttipoorgao="" entidade_tipoorgao=""
 localEspecifico="" responsavel_legal_cpf="" responsavel_legal_nome_completo="" responsavel_legal_email="" num_servico="248" srd_planobasico_in
d_carater="P" num_fistel="50410887137" habilitacao_NumScradJur="16082" habilitacao_NumScradTec="16081" habilitacao_DataLimiteInstalacao="" habi
litacao_DataValFreq="" habilitacao_DataContrato="" habilitacao_IndEducativo="0" network="" carater="P" fase="1" canalCidadania="N" codFinalidad
e="0" finalidade="Comercial"><observacao>RESOLUCAO 291/02;Ato nº 2.720, de 29/04/2011, publicado no DOU. de 03/05/2011.</observacao></entidade>
<administrativo numero_estacao="" NomeIndicativo="" FindCodSituacaoLicenca="" FindDatalimiteInstalacao="" DataEmissaoLicenca="" DataReemissaoLi
cenca="" NumLicenca=""><aprovacao_locais seq="1" NumProcesso="" NumDocumento="" IdtTipoDocumento="" TipoDocumento="" CodOrgao="" DataDocumento=
"" DataDOU="" IdtRazao="" Razao="" IndNatureza="" Natureza=""/><historico_documentos seq="1" NumProcesso="9999" NumDocumento="123" IdtTipoDocum
ento="18" TipoDocumento="Despacho" CodOrgao="CMPRL" DataDocumento="20/08/2012" DataDOU="22/08/2012" IdtRazao="2" Razao="Consol. Carac. Técnicas
" IndNatureza="Técnico" Natureza="Técnico"/><historico_documentos seq="2" NumProcesso="9999" NumDocumento="245" IdtTipoDocumento="3" TipoDocume
nto="Decreto Legislativo" CodOrgao="CN" DataDocumento="20/10/2015" DataDOU="21/10/2015" IdtRazao="7" Razao="Deliber.  do C. Nacional" IndNature
za="Jurídico" Natureza="Jurídico"/></administrativo><enderecos><estacao estacao_EndLogradouro="" estacao_EndBairro="" estacao_CodMunicipio="" e
stacao_NomeMunicipio="" estacao_SiglaUF="" estacao_CodCep=""/><estacaoprincipal estacaoprincipal_EndLogradouro="" estacaoprincipal_EndBairro=""
 estacaoprincipal_CodMunicipio="" estacaoprincipal_NomeMunicipio="" estacaoprincipal_SiglaUF="" estacaoprincipal_CodCep=""/><estacaoauxiliar es
tacaoauxiliar_EndLogradouro="" estacaoauxiliar_EndBairro="" estacaoauxiliar_CodMunicipio="" estacaoauxiliar_NomeMunicipio="" estacaoauxiliar_Si
glaUF="" estacaoauxiliar_CodCep=""/></enderecos><estacao_principal transmissor_CodHomologacao="" transmissor_fabricante="" transmissor_Modelo="
" transmissor_Potencia_Operacao="" linhaTransmissao_Principal_Modelo="" linhaTransmissao_Principal_Fabricante="" linhaTransmissao_Principal_Med
Comprimento="" linhaTransmissao_Principal_MedAtenLinhaTransmissaodB100m="" linhaTransmissao_Principal_PerdasAcessorias_db="0.5" linhaTransmissa
o_Principal_MedImpedanciaCarac="" antena_Principal_Fabricante="" antena_Principal_Modelo="" antena_Principal_Ganho_dBd="" antena_Principal_Beam
Tilt="" antena_Principal_OrientacaoNV="" antena_Principal_Polarizacao="" antena_Principal_HCI="" antena_Principal_Nulos="" antena_Principal_Obs
ervacao="" ERP="" latitude="" longitude=""/><estacao_auxiliar/><transmissor_auxiliar transmissoraux_CodHomologacao="" transmissoraux_fabricante
="" transmissoraux_Modelo="" transmissoraux_Potencia_Operacao=""/><transmissor_auxiliar2 transmissoraux2_CodHomologacao="" transmissoraux2_fabr
icante="" transmissoraux2_Modelo="" transmissoraux2_Potencia_Operacao=""/><linha_auxiliar linhaTransmissao_Auxiliar_Modelo="" linhaTransmissao_
Auxiliar_Fabricante="" linhaTransmissao_Auxiliar_MedComprimento="" linhaTransmissao_Auxiliar_MedAtenLinhaTransmissaodB100m="" linhaTransmissao_
Auxiliar_PerdasAcessorias_db="" linhaTransmissao_Auxiliar_MedImpedanciaCarac=""/><antena_auxiliar antena_Auxiliar_Fabricante="" antena_Auxiliar
_Modelo="" antena_Auxiliar_Ganho_dBd="" antena_Auxiliar_BeamTilt="" antena_Auxiliar_OrientacaoNV="" antena_Auxiliar_Polarizacao="" antena_Auxil
iar_HCI="" antena_Auxiliar_Nulos="" antena_Auxiliar_Observacao=""/><horario_funcionamento><item seq="0" dia_inicio="" dia_fim="" hora_inicio=""
 hora_fim=""/></horario_funcionamento></row>...

这是关于电视和广播频道的XML,具有每个广播公司的名称和位置

我为数据框列选择了一些信息,并通过这种方式进行了转换:

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

xtree = et.parse("concessoes/dez_2019/estacao_rd.xml")
xroot = xtree.getroot()

df_cols = ["row item", 
           "SiglaServico", 
           "id", 
           "state", 
           "entidade", 
           "fistel", 
           "cnpj", 
           "CodMunicipio", 
           "municipio", 
           "uf", 
           "responsavel_legal_cpf", 
           "responsavel_legal_nome_completo", 
           "entidade_nome_fantasia",
           "finalidade"]
rows = []

for node in xroot: 
    s_row_item = node.attrib.get("row item")
    s_SiglaServico = node.attrib.get("SiglaServico")
    s_id = node.attrib.get("id")
    s_state = node.attrib.get("state")
    s_entidade = node.attrib.get("entidade")
    s_fistel = node.attrib.get("fistel")
    s_cnpj = node.attrib.get("cnpj")
    s_CodMunicipio = node.attrib.get("CodMunicipio")
    s_municipio = node.attrib.get("municipio")
    s_uf = node.attrib.get("uf")
    s_responsavel_legal_cpf = node.attrib.get("responsavel_legal_cpf")
    s_responsavel_legal_nome_completo = node.attrib.get("responsavel_legal_nome_completo")
    s_entidade_nome_fantasia = node.attrib.get("entidade_nome_fantasia")
    s_finalidade = node.attrib.get("finalidade")


    rows.append("row_item": s_row_item, 
                 "SiglaServico": s_SiglaServico, 
                 "id": s_id, 
                 "state": s_state,
                 "entidade": s_entidade,
                 "fistel": s_fistel,
                 "cnpj": s_cnpj,
                 "CodMunicipio": s_CodMunicipio,
                 "municipio": s_municipio,
                 "uf": s_uf,
                 "responsavel_legal_cpf": s_responsavel_legal_cpf,
                 "responsavel_legal_nome_completo": s_responsavel_legal_nome_completo,
                 "entidade_nome_fantasia": s_entidade_nome_fantasia,
                 "finalidade": s_finalidade,
                )

out_df = pd.DataFrame(rows, columns = df_cols)

转换有效,但某些列为空

out_df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 27956 entries, 0 to 27955
Data columns (total 14 columns):
row item                           0 non-null float64
SiglaServico                       27956 non-null object
id                                 27956 non-null object
state                              27956 non-null object
entidade                           27956 non-null object
fistel                             27956 non-null object
cnpj                               27956 non-null object
CodMunicipio                       27956 non-null object
municipio                          27956 non-null object
uf                                 27956 non-null object
responsavel_legal_cpf              0 non-null object
responsavel_legal_nome_completo    0 non-null object
entidade_nome_fantasia             0 non-null object
finalidade                         0 non-null object
dtypes: float64(1), object(13)
memory usage: 3.0+ MB

可以下载XML文件here

[请问有人知道为什么有些列用这种方法会空白吗?以及如何解决这个问题?

答案

那是因为您在ROWS内有子元素。我在NODE中添加了另一个循环,导出到csv

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

xtree = et.parse("estacao_rd.xml")
xroot = xtree.getroot()

df_cols = ["item",
           "SiglaServico",
           "id",
           "state",
           "entidade",
           "fistel",
           "cnpj",
           "CodMunicipio",
           "municipio",
           "uf",
           "responsavel_legal_cpf",
           "responsavel_legal_nome_completo",
           "entidade_nome_fantasia",
           "finalidade"]
rows = []

for node in xroot:

    s_row_item = node.attrib.get("item")
    s_SiglaServico = node.attrib.get("SiglaServico")
    s_id = node.attrib.get("id")
    s_state = node.attrib.get("state")
    s_entidade = node.attrib.get("entidade")
    s_fistel = node.attrib.get("fistel")
    s_cnpj = node.attrib.get("cnpj")
    s_CodMunicipio = node.attrib.get("CodMunicipio")
    s_municipio = node.attrib.get("municipio")
    s_uf = node.attrib.get("uf")
    for child in node.iter():
        s_responsavel_legal_cpf = child.attrib.get("responsavel_legal_cpf")
        s_responsavel_legal_nome_completo = child.attrib.get("responsavel_legal_nome_completo")
        s_entidade_nome_fantasia = child.attrib.get("entidade_nome_fantasia")
        s_finalidade = child.attrib.get("finalidade")
        rows.append("item": s_row_item,
                     "SiglaServico": s_SiglaServico,
                     "id": s_id,
                     "state": s_state,
                     "entidade": s_entidade,
                     "fistel": s_fistel,
                     "cnpj": s_cnpj,
                     "CodMunicipio": s_CodMunicipio,
                     "municipio": s_municipio,
                     "uf": s_uf,
                     "responsavel_legal_cpf": s_responsavel_legal_cpf,
                     "responsavel_legal_nome_completo": s_responsavel_legal_nome_completo,
                     "entidade_nome_fantasia": s_entidade_nome_fantasia,
                     "finalidade": s_finalidade,
                    )
#
out_df = pd.DataFrame(rows, columns = df_cols)
#Export to csv
out_df.to_csv('test.csv',index=False)

以上是关于在Python中,如何使用xml.etree.ElementTree创建数据帧?的主要内容,如果未能解决你的问题,请参考以下文章

我如何在 Python 中使用 GCP 枚举?

如何在python中使用nice命令?

如何在 Python 中使用 Selenium?

如何在Python中使用textcat?

当python使用“Python.h”调用该c++进程时,如何在python中停止一个c++进程

如何使用 Boost.Python 在 Python 中调用内置函数