Есть ли способ извлечь элементы из файла XML и преобразовать его во фрейм данных pandas? - PullRequest
0 голосов
/ 30 марта 2020

У меня возникли проблемы с извлечением элементов из большого файла XML и преобразованием его в pandas фрейм данных.

Входной файл XML (ab c. xml ):

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<brand by="hhdhdh" date="2014/01/01" name="OOP-112200" Insti="TGA">
<design name="OOP-112200" own="TGA" descri="" sound_db="JJKO">

<sec name="abcd" sound_freq="abcd" c_ty="pv">
<feature number="48">
<tfgt v="0.1466469683747654" y="0.0" units="sec"/>    
</feature>
<mwan sound_freq="abcd" first_name="g7tty" description="xyz">
</sec>

<sec name="M_20_K40745170" sound_freq="mhr17:7907527-7907589" tension="SGCGSCGSCGSCGSC" s_c="0">
<feature number="5748">
<tfgt v="0.1466469683747654" y="0.0" units="sec"/>
</feature>
<mwan sound_freq="mhr17:7907527-7907589" first_name="g7tty" description="xyz">
<xyz abc="trt" id="abc"/>
<per fre="acc" value="abc"/>
<per fre="xyz" value="abc"/>
<per fre="yy" value="abc"/>
<per fre="psc" value="abc"/>
<per fre="ttt" value="1"/>
<per fre="xyz" value="abc"/>
<per fre="Volum_5mb" value="89.00"/>
<per fre="Volum_40mb" value="44.00"/>
<per fre="Volum_70mb" value="77.00"/>
</mwan>
</sec>

<sec name="M_20_K40745171" sound_freq="mhr17:7907528-7907599" tension="SGCGSCGSCGSHHGSC" s_c="0">
<feature number="5748">
<tfgt v="0.1466469683747654" y="0.0" units="sec"/>
</feature>
<mwan sound_freq="mhr17:7907527-7907589" first_name="gtftty" description="xyz">
<xyz abc="trt" id="abc"/>
<per fre="acc" value="abc"/>
<per fre="xyz" value="abc"/>
<per fre="yy" value="abc"/>
<per fre="Volum_5mb" value="77.00"/>
<per fre="Volum_40mb" value="65.00"/>
<per fre="Volum_70mb" value="94.00"/>
</mwan>
</sec>

<sec name="M_20_K40745172" sound_freq="mhr17:7907527-7907100" tension="SGCGSCGSCGSCGSC" s_c="0">
<feature number="5748">
<tfgt v="0.1466469683747654" y="0.0" units="sec"/>
</feature>
<mwan sound_freq="mhr17:7907527-7907589" first_name="g7tty" description="xyz">
<xyz abc="trt" id="abc"/>
<per fre="acc" value="abc"/>
<per fre="xyz" value="abc"/>
</mwan>
</sec>
#file continue....
</design>
</brand>

Требуемый вывод:

                name               sound_freq     Volum_5mb      Volum_40mb     Volum_70mb
0               abcd                     abcd         None            None           None
1     M_20_K40745170    mhr17:7907527-7907589         89.00           44.00         77.00
2     M_20_K40745171    mhr17:7907528-7907599         77.00           65.00         94.00
3     M_20_K40745172    mhr17:7907527-7907100         None            None           None

Пробовал два способа получения желаемого результата 1) Использование python xml парсера 2) Использование регулярного выражения

1) Использование python xml синтаксического анализатора

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

def getvalueofnode(node):
    """ return node text or None """
   # return node.text if node is not None else None


def main():
   """ main """
    parsed_xml = et.parse("abc.xml")
    dfcols = ['name', 'sound_freq']
    df_xml = pd.DataFrame(columns=dfcols)

    for node in parsed_xml.getroot():
        name = node.attrib.get('name')
        sound_name= node.attrib.get('sound_freq')



        df_xml = df_xml.append(
            pd.Series([name,sound_freq
                       ], index=dfcols),
            ignore_index=True)

    print (df_xml)

main()

Предоставление вывода:

                   name               sound_freq         
   0               abcd                     abcd                          
   1     M_20_K40745170    mhr17:7907527-7907589                           
   2     M_20_K40745171    mhr17:7907528-7907599                      
   3     M_20_K40745172    mhr17:7907527-7907100 

2) Использование регулярного выражения:

import re 
infile = open("abc.xml")
np_array_values = []
pattern = re.compile(r'<sec name="(\D_\d\d_\w+)"\s+sound_freq="(\D\D\D\d+:\d+-\d+)".*<per fre="(Volum_+\d+Kb)"+\svalue="(\d+.+)"',re.DOTALL|re.MULTILINE)

fn_list = infile.readlines() 
for line in fn_list:
    search_obj = re.search(pattern, line)  
    print(search_obj)
    if search_obj:
        matching_group = search_obj.groups()
        print(matching_group)
        np_array_values.append(matching_group)

С помощью вышеупомянутых двух методов Я могу получить два столбца, которые являются name и sound_freq, но не другие 3 столбца, которые Volum_5mb, Volum_40mb и Volum_70mb. Есть ли способ получить желаемый результат, используя любой из двух вышеуказанных способов? Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...