Как извлечь XML значений узлов с Elementtree - PullRequest
0 голосов
/ 18 января 2020

У меня следующая структура данных (весь файл размером около 2,5 ГБ, с гораздо большим количеством людей, поэтому я полагаюсь на синтаксический анализ):

<!-- ====================================================================== -->

    <person id="10004136">
        <attributes>
            <attribute name="age" class="java.lang.Integer" >41</attribute>
            <attribute name="bikeAvailability" class="java.lang.String" >none</attribute>
            <attribute name="carAvailability" class="java.lang.String" >some</attribute>
            <attribute name="censusId" class="java.lang.Integer" >3675631</attribute>
            <attribute name="employed" class="java.lang.Boolean" >false</attribute>
            <attribute name="hasLicense" class="java.lang.String" >yes</attribute>
            <attribute name="htsId" class="java.lang.Long" >2403610200001</attribute>
            <attribute name="isOutside" class="java.lang.Boolean" >true</attribute>
            <attribute name="isPassenger" class="java.lang.Boolean" >false</attribute>
            <attribute name="ptSubscription" class="java.lang.Boolean" >false</attribute>
            <attribute name="sex" class="java.lang.String" >f</attribute>
        </attributes>
        <plan score="-0.0375" selected="yes">
            <activity type="outside" link="284251" facility="outside_1" x="653218.0059491959" y="6857536.564730054" end_time="19:22:27" >
            </activity>
            <leg mode="car" dep_time="19:22:27" trav_time="00:02:07">
                <route type="links" start_link="284251" end_link="525753" trav_time="00:02:07" distance="2349.4934769631172" vehicleRefId="10004136">284251 660231 129607 129599 139064 641998 641663 159806 170160 85864 635804 572378 435246 362748 643661 525753</route>
            </leg>
            <activity type="outside" link="525753" facility="outside_11" x="655306.9611509901" y="6858641.834279304" end_time="19:24:31" >
            </activity>
        </plan>

    </person>


<!-- ====================================================================== -->

    <person id="10010770">
        <attributes>
            <attribute name="age" class="java.lang.Integer" >24</attribute>
            <attribute name="bikeAvailability" class="java.lang.String" >some</attribute>
            <attribute name="carAvailability" class="java.lang.String" >some</attribute>
            <attribute name="censusId" class="java.lang.Integer" >3677845</attribute>
            <attribute name="employed" class="java.lang.Boolean" >false</attribute>
            <attribute name="hasLicense" class="java.lang.String" >yes</attribute>
            <attribute name="htsId" class="java.lang.Long" >1124150200003</attribute>
            <attribute name="isOutside" class="java.lang.Boolean" >true</attribute>
            <attribute name="isPassenger" class="java.lang.Boolean" >true</attribute>
            <attribute name="ptSubscription" class="java.lang.Boolean" >true</attribute>
            <attribute name="sex" class="java.lang.String" >f</attribute>
        </attributes>
        <plan score="-0.35194444444444445" selected="yes">
            <activity type="outside" link="284251" facility="outside_1" x="653218.0059491959" y="6857536.564730054" end_time="16:05:33" >
            </activity>
            <leg mode="car" dep_time="16:05:33" trav_time="00:02:54">
                <route type="links" start_link="284251" end_link="63873" trav_time="00:02:54" distance="3117.285137236383" vehicleRefId="10010770">284251 660231 129607 129599 139064 641998 641663 159806 170160 85864 635804 572378 435246 190032 526059 525761 525778 525779 450362 63873</route>
            </leg>
            <activity type="outside" link="63873" facility="outside_2" x="656055.3097541996" y="6859009.979613776" end_time="18:02:10" >
            </activity>
            <leg mode="outside" dep_time="18:02:10" trav_time="00:00:00">
                <route type="generic" start_link="63873" end_link="531441" trav_time="00:00:00" distance="7.921674674372883"></route>
            </leg>
            <activity type="outside" link="531441" facility="outside_23" x="656049.8621041798" y="6859015.730790952" end_time="18:04:26" >
            </activity>
            <leg mode="car" dep_time="18:04:26" trav_time="00:07:12">
                <route type="links" start_link="531441" end_link="76440" trav_time="00:07:12" distance="4324.898454630868" vehicleRefId="10010770">531441 54359 620532 526744 675063 675065 675067 622150 187357 187359 405887 405889 405891 675093 187342 510620 510622 618111 255114 355287 355832 355901 356681 35070 667694 386021 259997 386040 667683 291568 291569 141412 160326 85863 346168 541189 327819 541224 171474 171475 171476 611499 611500 611501 171477 171478 461457 461459 461425 258702 258703 258704 628069 650240 677498 677500 677502 76440</route>
            </leg>
            <activity type="leisure" link="76440" facility="12091" x="653496.9" y="6861203.5" start_time="18:17:10" end_time="20:02:10" >
                <attributes>
                    <attribute name="innerParis" class="java.lang.Boolean" >true</attribute>
                </attributes>
            </activity>
            <leg mode="car" dep_time="20:02:10" trav_time="00:06:35">
                <route type="links" start_link="76440" end_link="398730" trav_time="00:06:35" distance="3993.949273139461" vehicleRefId="10010770">76440 461424 461458 461456 475586 294496 475801 18792 475802 475614 475571 427140 557773 557774 610993 215210 445731 445734 445729 445727 445738 603918 603916 603914 603912 603910 607789 608821 445742 445740 445736 661078 509430 509428 509426 509424 509422 509420 509418 509416 345514 200784 264839 200782 200783 200795 31424 205252 205254 205256 205258 610138 434374 434352 434412 434414 434416 356593 356595 356597 356599 356601 356587 356589 356591 516681 624296 624343 212721 212723 212725 524366 506168 398730</route>
            </leg>
            <activity type="outside" link="398730" facility="outside_10" x="653013.2075560454" y="6857532.214432823" end_time="20:07:01" >
            </activity>
        </plan>

    </person>

Я хочу сохранить фрейм данных который имеет один столбец, показывающий значение person id, и другой столбец, показывающий значение атрибута age, который находится от первого лица 41 (<attribute name="age" class="java.lang.Integer" >41</attribute>).

Код ниже показывает мой текущий подход:

import gzip
import xml.etree.ElementTree as ET
from collections import defaultdict
import pandas as pd
import numpy as np

tree = ET.iterparse(gzip.open('V0_1pm/output_plans.xml.gz', 'r'))
age = defaultdict(list)
for xml_event, elem in tree:
    if elem.tag == 'person' and target.attrib == "name":
        items = list(elem)
        target = items[0]
        if target.attrib["name"]=="age":
               print(target.attrib["name"]=="age".text)

age = pd.DataFrame.from_dict(age, orient='index').rename_axis('id')  
age 

Любая помощь очень ценится!

1 Ответ

1 голос
/ 18 января 2020

В вашем коде есть такой недостаток, что, хотя вы определили age как defaultdict (list) , но вы его абсолютно не используете. Так как вы ожидаете, что словарь age содержит какие-либо данные для создания вашего DataFrame?

Решение состоит в том, что после анализа исходного файла (вы установили переменную tree ), запустите следующий код:

root = tree.getroot()
rows = []
for it in root.iter('person'):
    id = it.attrib['id']
    age = it.findtext('attributes/attribute[@name="age"]', '-1')
    rows.append([id, int(age)])
df = pd.DataFrame(rows, columns=['id', 'age'])

Я поставил здесь -1 в качестве значения "замены" для возраст , если есть человек элемент не может содержать обязательный атрибут .

Для вашего примера ввода я получил:

         id age
0  10004136  41
1  10010770  24
...