XML到pandas:导出到csv并使子级位于同一行



我正处于"萌芽阶段",试图用panda将XML文件转换为csv。我终于用下面的代码做到了:

for element in etree.iterparse(path):     
    data.append({element.tag: element.text})
df = pd.DataFrame(data,columns=['NOME_DISTRITO', 'NR_CPE', 'MARCA_EQUIPAMENTO',
                                'NR_EQUIPAMENTO','VALOR_LEITURA','REGISTADOR',
                                'TIPO_REGISTADOR','TIPO_DADOS_RECOLHIDOS','FACTOR_MULTIPLICATIVO_FINAL',
                                'NR_DIGITOS_INTEIRO','UNIDADE_MEDIDA','TIPO_LEITURA','MOTIVO_LEITURA',
                                'ESTADO_LEITURA','DATA_LEITURA','HORA_LEITURA'])
df.to_csv('/lecture.csv')

这是XML文件:

<DISTRITO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <NOME_DISTRITO>BRAGANCA</NOME_DISTRITO>
  <CPE>
    <NR_CPE>PT000200003724</NR_CPE>
    <LEITURA>
      <MARCA_EQUIPAMENTO>102</MARCA_EQUIPAMENTO>
      <NR_EQUIPAMENTO>30806746</NR_EQUIPAMENTO>
      <VALOR_LEITURA>16858</VALOR_LEITURA>
      <REGISTADOR>001</REGISTADOR>
      <TIPO_REGISTADOR>S</TIPO_REGISTADOR>
      <TIPO_DADOS_RECOLHIDOS>1</TIPO_DADOS_RECOLHIDOS>
      <FACTOR_MULTIPLICATIVO_FINAL>1</FACTOR_MULTIPLICATIVO_FINAL>
      <NR_DIGITOS_INTEIRO>5</NR_DIGITOS_INTEIRO>
      <UNIDADE_MEDIDA>kWh</UNIDADE_MEDIDA>
      <TIPO_LEITURA>2</TIPO_LEITURA>
      <MOTIVO_LEITURA>2</MOTIVO_LEITURA>
      <ESTADO_LEITURA>A</ESTADO_LEITURA>
      <DATA_LEITURA>20151218</DATA_LEITURA>
      <HORA_LEITURA>083800</HORA_LEITURA>
    </LEITURA>
    <LEITURA>
      <MARCA_EQUIPAMENTO>102</MARCA_EQUIPAMENTO>
      <NR_EQUIPAMENTO>30806746</NR_EQUIPAMENTO>
      <VALOR_LEITURA>16925</VALOR_LEITURA>
      <REGISTADOR>001</REGISTADOR>
      <TIPO_REGISTADOR>S</TIPO_REGISTADOR>
      <TIPO_DADOS_RECOLHIDOS>1</TIPO_DADOS_RECOLHIDOS>
      <FACTOR_MULTIPLICATIVO_FINAL>1</FACTOR_MULTIPLICATIVO_FINAL>
      <NR_DIGITOS_INTEIRO>5</NR_DIGITOS_INTEIRO>
      <UNIDADE_MEDIDA>kWh</UNIDADE_MEDIDA>
      <TIPO_LEITURA>1</TIPO_LEITURA>
      <MOTIVO_LEITURA>1</MOTIVO_LEITURA>
      <ESTADO_LEITURA>A</ESTADO_LEITURA>
      <DATA_LEITURA>20160119</DATA_LEITURA>
      <HORA_LEITURA>203000</HORA_LEITURA>
    </LEITURA>
   </CPE>

这是Excel中的最终结果:

NOME_stritto NR_CPE MARCA_aequipmento NR_EQUIPAMENTO VALOR_LEITURA REGISTADOR TIPO_regdos recohidos FACTOR_multipilitativo_FINAL NR_DIGITOS_iteiro unidad_MEDIDA TIPO_reitura MOTIVO_leitur ESTADO_leituradata_LEITURA-HORA_laeituraBRAGANCA

PT000200003724                          
    102                                                 
        30806746                                                
            16925                                           
                1                                       
                    S                                   
                        1                               
                            1                           
                                5                       
                                    kWh                 
                                        1               
                                            1           
                                                A       
                                                    20160119    
                                                        203000

我只想在"MARCA_EQUIPAMENTO"列之后的同一行中有这些数据,但正如你所看到的,这就像一个"形状楼梯行"。我能用熊猫做些什么吗?或者在excel中以一种很好的方式修复和拥有它吗?

NOME_stritto NR_CPE MARCA_aequipmento NR_EQUIPAMENTO VALOR_LEITURA REGISTADOR TIPO_regdos recohidos FACTOR_multipilitativo_FINAL NR_DIGITOS_iteiro unidad_MEDIDA TIPO_reitura MOTIVO_leitur ESTADO_leituradata_LEITURA-HORA_laeituraBRAGANCA
PT0002000021673724JE
102 30806746 16858 1 S 1 5 kWh 2 A 20151218 83800102 30806746 16925 1 S 1 1 5 kWh 1 1 A 20160119 203000

考虑在iterparse()中运行条件语句。因为<NOME_DISTRITO><NR_CPE>位于重复的<LEITURA>元素之外,所以将它们的值保存在标量中,以便添加到inner{}字典中,以便附加到数据帧:

import xml.etree.ElementTree as et
import pandas as pd
path ='/path/to/Input.xml'
data = []
for (ev, el) in et.iterparse(path):
    if el.tag == 'NOME_DISTRITO': nome = el.text
    if el.tag == 'NR_CPE': nr = el.text
    if el.tag == "LEITURA":
        inner = {}
        inner['NOME_DISTRITO'] = nome
        inner['NR_CPE'] = nr
        for i in el:
            inner[i.tag] = i.text        
        data.append(inner)
df = pd.DataFrame(data)
print(df)
#   DATA_LEITURA ESTADO_LEITURA FACTOR_MULTIPLICATIVO_FINAL HORA_LEITURA  
# 0     20151218              A                           1       083800   
# 1     20160119              A                           1       203000   
#   MARCA_EQUIPAMENTO MOTIVO_LEITURA NOME_DISTRITO          NR_CPE  
# 0               102              2      BRAGANCA  PT000200003724   
# 1               102              1      BRAGANCA  PT000200003724   
#   NR_DIGITOS_INTEIRO NR_EQUIPAMENTO REGISTADOR TIPO_DADOS_RECOLHIDOS  
# 0                  5       30806746        001                     1   
# 1                  5       30806746        001                     1   
#   TIPO_LEITURA TIPO_REGISTADOR UNIDADE_MEDIDA VALOR_LEITURA  
# 0            2               S            kWh         16858  
# 1            1               S            kWh         16925 

最新更新