मेरे पास निम्न संरचना वाला एक एक्सएमएल है:

<population desc="Switzerland Baseline">
    <attributes>
        <attribute name="coordinateReferenceSystem" class="java.lang.String" >Atlantis</attribute>
    </attributes>

    <person id="1015600">
        <attributes>
            <attribute name="age" class="java.lang.Integer" >86</attribute>
            <attribute name="ptSubscription" class="java.lang.Boolean" >false</attribute>
            <attribute name="sex" class="java.lang.String" >f</attribute>
        </attributes>
    </person>
    <person id="10002042">
        <attributes>
            <attribute name="age" class="java.lang.Integer" >86</attribute>
            <attribute name="ptSubscription" class="java.lang.Boolean" >false</attribute>
            <attribute name="sex" class="java.lang.String" >f</attribute>
        </attributes>
    </person>
    <person id="1241567">
        <attributes>
            <attribute name="age" class="java.lang.Integer" >86</attribute>
            <attribute name="ptSubscription" class="java.lang.Boolean" >true</attribute>
            <attribute name="sex" class="java.lang.String" >f</attribute>
        </attributes>
    </person>   
    <person id="1218895">
        <attributes>
            <attribute name="age" class="java.lang.Integer" >86</attribute>
            <attribute name="ptSubscription" class="java.lang.Boolean" >true</attribute>
            <attribute name="sex" class="java.lang.String" >f</attribute>
        </attributes>
    </person>   
    <person id="10002042">
        <attributes>
            <attribute name="age" class="java.lang.Integer" >86</attribute>
            <attribute name="ptSubscription" class="java.lang.Boolean" >true</attribute>
            <attribute name="sex" class="java.lang.String" >f</attribute>
        </attributes>
    </person>
</population>

मेरे पास एक पांडा डेटा फ्रेम है, जिसे agents कहा जाता है, प्रासंगिक ids . के साथ

    id
0   1015600
1   1218895
2   1241567

मैं जो चाहता हूं वह बड़े एक्सएमएल के माध्यम से जाना है और ptSubscription का मान person के लिए प्रासंगिक id के साथ निकालना है।

वांछित आउटपुट id और मान के साथ एक डेटा फ़्रेम या सूची है:

    id          ptSubscription
0   1015600     false
1   1218895     true
2   1241567     true

मेरा दृष्टिकोण एक खाली आउटपुट देता है:

import gzip
import xml.etree.cElementTree as ET
import pandas as pd
from collections import defaultdict

file = 'output_plans.xml.gz'
data = gzip.open(file, 'r')
root = ET.parse(data).getroot()

rows = []
for it in root.iter('person'):
    if it.attrib['id'] in agents[["id"]]:
        id = it.attrib['id']
        age = it.find('attributes/attribute[@name="ptSubscription"]').text
        rows.append([id, age])
#root.clear()

pt = pd.DataFrame(rows, columns=['id', 'PTSubscription'])
pt
0
Yves 16 मई 2020, 21:45

2 जवाब

सबसे बढ़िया उत्तर

एलएक्सएमएल का उपयोग करके अनुरोध जानकारी निकालने में सक्षम एक सामान्य कार्य होगा

from lxml import etree
from io import StringIO

with open("sample.xml") as fd:
    tree = etree.parse(fd)

xpath_fmt = '/population/person[@id="{}"]/attributes/attribute[@name="ptSubscription"]'


agents = [1015600,1218895,1241567]

rows = []
for pid in agents:
    xpath = xpath_fmt.format(pid)
    r = tree.xpath(xpath)
    for res in r:
        rows.append([pid, res.text])

pd.DataFrame(rows, columns=['id', 'PTSubscription'])

मानक पुस्तकालय का उपयोग करते हुए, कोड को फिर से जोड़ा जाएगा

import xml.etree.cElementTree as ET

with open("sample.xml") as fd:
    root = ET.parse(fd).getroot()

xpath_fmt = 'person[@id="{}"]/attributes/attribute[@name="ptSubscription"]'


agents = [1015600,
1218895,
1241567]

rows = []
for pid in agents:
    xpath = xpath_fmt.format(pid)
    r = root.findall(xpath)
    for res in r:
        rows.append([pid, res.text])

pd.DataFrame(rows, columns=['id', 'PTSubscription'])

चूंकि xpath जनसंख्या तत्व के सापेक्ष होना चाहिए।

2
nilleb 16 मई 2020, 22:59

हम विवरण निकालने के लिए पार्सल का उपयोग कर सकते हैं:

#read in data : 

with open("test.xml") as fd:
    tree = fd.read()

import library and parse xml :
from parsel import Selector

selector = Selector(text=tree, type='xml')

#checklist : 
agents = ['1015600','1218895','1241567']

#track the ids
#this checks and selects ids in agents
ids = selector.xpath(f".//person[contains({' '.join(agents)!r},@id)]")

#pair ids with attribute where the name == ptSubscription : 

d = {}
for ent in ids:
    vals = ent.xpath(".//attribute[@name='ptSubscription']/text()").get()
    key = ent.xpath(".//@id").get()
    d[key] = vals

print(d)

{'1015600': 'false', '1241567': 'true', '1218895': 'true'}

#put into a dataframe : 
pd.DataFrame.from_dict(d,orient='index', columns=['PTSubscription'])

वैकल्पिक: ElementTree के साथ elementpath :

import xml.etree.ElementTree as ET
import elementpath
root = ET.parse("test.xml").getroot()

agents = ('1015600','1218895','1241567')

id_path = f".//person[@id={agents}]"
subscription_path = ".//attribute[@name='ptSubscription']/text()"

d = {}
for entry in elementpath.select(root,path):
    key = elementpath.select(entry,"./@id")[0]
    val = elementpath.select(entry,subscription_path)[0]
    d[key] = val
1
sammywemmy 17 मई 2020, 03:10