Чтение XML-файла в Pandas DataFrame

Может кто-нибудь, пожалуйста, помогите преобразовать следующий файл XML в фрейм данных Pandas:

<?xml version="1.0" encoding="UTF-8" ?>
<root>
 <bathrooms type="dict">
  <n35237 type="number">1.0</n35237>
  <n32238 type="number">3.0</n32238>
  <n44699 type="number">nan</n44699>
 </bathrooms>
 <price type="dict">
  <n35237 type="number">7020000.0</n35237>
  <n32238 type="number">10000000.0</n32238>
  <n44699 type="number">4128000.0</n44699>
 </price>
 <property_id type="dict">
  <n35237 type="number">35237.0</n35237>
  <n32238 type="number">32238.0</n32238>
  <n44699 type="number">44699.0</n44699>
 </property_id>
</root>

Это должно выглядеть так -

ВЫХОД

Это код, который я написал:

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

tree = ET.parse('real_state.xml')
root = tree.getroot()

dfcols = ['property_id', 'price', 'bathrooms']
df_xml = pd.DataFrame(columns=dfcols)

for node in root:
    property_id = node.attrib.get('property_id')
    price = node.attrib.get('price')
    bathrooms = node.attrib.get('bathrooms')

    df_xml = df_xml.append(
            pd.Series([property_id, price, bathrooms], index=dfcols),
            ignore_index=True)


print(df_xml)

Я получаю None везде, а не фактические значения. Может кто-нибудь подскажите, пожалуйста, как это можно исправить. Спасибо!

2 ответа

Решение

Если данные простые, как это, то вы можете сделать что-то вроде:

from lxml import objectify
xml = objectify.parse('Document1.xml')
root = xml.getroot()

bathrooms = [child.text for child in root['bathrooms'].getchildren()]
price = [child.text for child in root['price'].getchildren()]
property_id = [child.text for child in root['property_id'].getchildren()]

data = [bathrooms, price, property_id]
df = pd.DataFrame(data).T
df.columns = ['bathrooms', 'price', 'property_id']

    bathrooms   price      property_id
0   1.0        7020000.0    35237.0
1   3.0        10000000.0   32238.0
2   nan        4128000.0    44699.0

если это сложнее, то цикл лучше. Вы можете сделать что-то вроде

from lxml import objectify
xml = objectify.parse('Document1.xml')
root = xml.getroot()

data=[]
for i in range(len(root.getchildren())):
    data.append([child.text for child in root.getchildren()[i].getchildren()])

df = pd.DataFrame(data).T
df.columns = ['bathrooms', 'price', 'property_id']

Привет всем, я нашел еще один простой способ решить этот вопрос. ссылка: https://www.youtube.com/watch?v=WVrg5-cjr5k

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

## open notebook and save your xml file to text.xml 
with codecs.open('text.xml', 'r', encoding='utf8') as f:
    tt = f.read()


def xml2df(xml_data):
    root = ET.XML(xml_data)
    all_records = []
    for i, child in enumerate(root):
        record = {}
        for sub_child in child:
            record[sub_child.tag] = sub_child.text
        all_records.append(record)
    return pd.DataFrame(all_records)


df_xml1 = xml2df(tt)
print(df_xml1)

для лучшего понимания ET вы можете использовать код под кодом, чтобы увидеть, что находится в вашем xml

import xml.etree.ElementTree as ET
import pandas as pd
import codecs
with codecs.open('text.xml', 'r', encoding='utf8') as f:
    tt = f.read()

root = ET.XML(tt)

print(type(root))
print(root[0])
for ele in root[0]:
    print(ele.tag + '////' + ele.text)

print(root[0][0].tag)

После того, как вы закончите запуск программы, вы увидите результат внизу:

C:\Users\username\Documents\pycode\Scripts\python.exe C:/Users/username/PycharmProjects/DestinationLight/try.py
      n35237      n32238     n44699
0        1.0         3.0        nan
1  7020000.0  10000000.0  4128000.0
2    35237.0     32238.0    44699.0

<class 'xml.etree.ElementTree.Element'>
<Element 'bathrooms' at 0x00000285006B6180>
n35237////1.0
n32238////3.0
n44699////nan
n35237

Process finished with exit code 0

Я имел успех, используя эту функцию

import xmltodict

xmlDict = xmltodict.parse(xmlData)
df = pd.DataFrame.from_dict(xmlDict)

Что мне нравится в этом, так это то, что я могу легко выполнить некоторые манипуляции со словарем между парсингом xml и созданием df. Кроме того, это помогает исследовать данные как подсказку, если структура хитрая.

Другие вопросы по тегам