【问题标题】:Convert a xml to pandas data frame python将xml转换为pandas数据框python
【发布时间】:2019-02-12 14:02:45
【问题描述】:

我必须将 xml 文件转换为数据框 pandas。我在很多模式下尝试过,但结果是一样的:无,无……我错了什么?另一个图书馆更好吗?有可能是因为我的 XML 格式吗? xml 文件的类型为:

<Document xmlns="xxx/zzz/yyy">  
 <Header>    
  <DocumentName>GXXXXXXXXXX</DocumentName>    
  <DocumentType>G10</DocumentType>    
  <Version>2.0.0.0</Version>    
  <Created>2018-12-11T09:00:02.987777+00:00</Created>    
  <TargetProcessingDate>2019-02-11</TargetProcessingDate>    
  <Part>      
  <CurrentPage>1</CurrentPage>      
  <TotalPages>1</TotalPages>    
  </Part>  
 </Header> 
 <Body>    
  <Accounts>      
    <Account>        
     <Type>20WE</Type>        
     <OldType>19WE</OldType>        
     <Kids>          
      <Kid>            
       <Name>marc</Name>            
       <BirthDate>2000-02-06</BirthDate>                       
       <Year>19</Year>            
       <Email>marc@xxx.com</Email>                         
      </Kid>           
     </Kids>      
    </Account>
   </Accounts> 
  </Body>  
</Document>  

尝试过的代码之一

import xml.etree.ElementTree as ET
import pandas as pd
class XML2DataFrame:

   def __init__(self, xml_data):
        self.root = ET.XML(xml_data)

    def parse_root(self, root):
        """Return a list of dictionaries from the text and attributes of the
        children under this XML root."""
        return [parse_element(child) for child in root.getchildren()]

    def parse_element(self, element, parsed=None):
    """ Collect {key:attribute} and {tag:text} from thie XML
     element and all its children into a single dictionary of strings."""
        if parsed is None:
            parsed = dict()

        for key in element.keys():
            if key not in parsed:
                parsed[key] = element.attrib.get(key)
            if element.text:
                parsed[element.tag] = element.text                
            else:
                raise ValueError('duplicate attribute {0} at element {1}'.format(key, element.getroottree().getpath  (element)))           

    """ Apply recursion"""
        for child in list(element):
            self.parse_element(child, parsed)
        return parsed

    def process_data(self):
    """ Initiate the root XML, parse it, and return a dataframe"""
        structure_data = self.parse_root(self.root)
        return pd.DataFrame(structure_data)

xml2df = XML2DataFrame(xml_data)
xml_dataframe = xml2df.process_data()

预期输出

Type  OldType  Name  BirthDate  Year  Email
20WE  19WE     marc  2000-02-06 19    marc@xxx.com

【问题讨论】:

标签: python xml pandas


【解决方案1】:

你可以用xmltodict把它转成json然后解析:

import xmltodict
import pandas as pd

with open('file.xml', 'r') as f:
    data = xmltodict.parse(f.read())['Document']['Body']['Accounts']['Account']

data_pd = {'Type': [data['Type']],
           'OldType': [data['OldType']],
           'Name': [data['Kids']['Kid']['Name']],
           'BirthDate': [data['Kids']['Kid']['BirthDate']],
           'Year': [data['Kids']['Kid']['Year']],
           'Email': [data['Kids']['Kid']['Email']]}

df = pd.DataFrame(data_pd)
print(df)

输出:

   Type OldType  Name   BirthDate Year         Email
0  20WE    19WE  marc  2000-02-06   19  marc@xxx.com

【讨论】:

  • 非常感谢!但在我的情况下,它给了我错误“列表索引必须是整数或切片,而不是 str”
  • 不幸的是我无法显示原始文件。但这好像数据是一个列表而不是字典。
  • 由于您不能共享 XML,您必须自己调试它。似乎数据格式与您共享的示例不同。
【解决方案2】:

点赞BeautifulSoup

from bs4 import BeautifulSoup
data = BeautifulSoup(#xmldata)
all_account = data.find_all('accounts')

l = []
df = pd.DataFrame(columns=['Type','OldType','Name','BirthDate','Year','Email'])
pos= 0
for account in all_account:
    l.append(account.find('type').text)
    l.append(account.find('oldtype').text)
    l.append(account.find('name').text)
    l.append(account.find('birthdate').text)
    l.append(account.find('year').text)
    l.append(account.find('email').text)

    # all account details
    df.loc[pos] = l
    l = []
    pos+=1

输出

   Type OldType  Name   BirthDate Year         Email
0  20WE    19WE  marc  2000-02-06   19  marc@xxx.com

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    相关资源
    最近更新 更多