繁体   English   中英

从 2.8 GB XML 文件中提取数据并将其保存到 CSV/Pandas Dataframe

[英]Extract data from 2.8 GB XML file and save it to CSV/Pandas Dataframe

文件链接: https://bulkdata.uspto.gov/data/trademark/dailyxml/assignments/asb19550103-20211231-01.zip

我需要在这个文件中搜索一些数据,但是我不能直接将这个文件读入 python 程序,因为它很大。

我尝试使用各种方法从这个 XML 文件中提取数据,但似乎它没有正确的 XML 格式或其他一些问题。 此外,我并不完全了解该文件中的列,因为我可以打开它。 我正在添加我尝试过的所有代码。

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

     xml_data = open("/content/apc220822.xml", 'r').read()  # Read file
     root = ET.XML(xml_data)  # Parse XML

     data = []
     cols = []
     for i, child in enumerate(root):
         data.append([subchild.text for subchild in child])
         cols.append(child.tag)

     df = pd.DataFrame(data).T  # Write in DF and transpose it
     df.columns = cols  # Update column names
     print(df)

     df = pd.DataFrame(data).T  # Write in DF and transpose it
     df.columns = cols  # Update column names
     print(df)

所需解决方案:我想从此 XML 中提取数据并将其保存为 Pandas DataFrame/CSV 格式,以便我可以使用 python 从中搜索数据。 我确实有 64GB RAM 可用。 因此,只需向我建议任何其他方法,例如将此 XML 文件数据保存到数据库等,我可以从中直接将其读入 python 程序并在其中找到所需的数据。

在这个答案中,我将使用bixml库来解析大型 XML 文件。

免责声明:我是这个库的作者。

我不知道panda也不知道你到底想做什么,但既然你提到了 CSV 并且搜索是你想要做的,我展示了如何以 Python 方式从 XML 文件中获取一些数据的示例,其中应该是一个很好的起点,可以随心所欲地使用该数据。


为了将来参考,XML 文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<!-- redacted -->
<trademark-assignments>
    <!-- redacted -->
    <assignment-information>
        <assignment-entry>
            <assignment>
                <reel-no>1</reel-no>
                <frame-no>0001</frame-no>
                <last-update-date>19910716</last-update-date>
                <purge-indicator>N</purge-indicator>
                <date-recorded>19550103</date-recorded>
                <page-count>0</page-count>
                <correspondent>
                    <person-or-organization-name/>
                </correspondent>
                <conveyance-text>CHANGE OF NAME 19530513</conveyance-text>
            </assignment>
            <assignors>
                <assignor>
                    <person-or-organization-name>HAWK AND BUCK COMPANY, INC., THE</person-or-organization-name>
                    <city>DALLAS</city>
                    <state>TEXAS</state>
                    <execution-date>19530513</execution-date>
                    <legal-entity-text>UNKNOWN</legal-entity-text>
                </assignor>
            </assignors>
            <assignees>
                <assignee>
                    <person-or-organization-name>GRIFFIN, C. C., MANUFACTURING COMPANY</person-or-organization-name>
                    <city>FORT WORTH</city>
                    <state>TEXAS</state>
                    <legal-entity-text>UNKNOWN</legal-entity-text>
                </assignee>
            </assignees>
            <properties>
                <property>
                    <serial-no>71231446</serial-no>
                    <registration-no>218184</registration-no>
                </property>
                <property>
                    <serial-no>71538408</serial-no>
                    <registration-no>506247</registration-no>
                </property>
                <property>
                    <serial-no>71510081</serial-no>
                    <registration-no>509215</registration-no>
                </property>
            </properties>
        </assignment-entry>
        <!-- redacted -->
    </assignment-information>
</trademark-assignments>

假设您有兴趣为每个分配条目获取城市转让人state以及所有属性序列号注册号)。

from dataclasses import dataclass, field
from pprint import pprint
from typing import List, Optional
from zipfile import ZipFile

from bigxml import Parser, xml_handle_element


@xml_handle_element("assignor")
@dataclass
class Assignor:
    city: str = "N/A"
    state: str = "N/A"

    @xml_handle_element("city")
    def handle_city(self, node):
        self.city = node.text

    @xml_handle_element("state")
    def handle_state(self, node):
        self.state = node.text


@xml_handle_element("property")
@dataclass
class Property:
    serial: Optional[int] = None
    registration: Optional[int] = None

    @xml_handle_element("serial-no")
    def handle_serial(self, node):
        self.serial = int(node.text)

    @xml_handle_element("registration-no")
    def handle_registration(self, node):
        self.registration = int(node.text)


@xml_handle_element("trademark-assignments", "assignment-information", "assignment-entry")
@dataclass
class AssignmentEntry:
    assignor: Optional[Assignor] = None
    properties: List[Property] = field(default_factory=list)

    @xml_handle_element("assignors")
    def handle_assignors(self, node):
        self.assignor = node.return_from(Assignor)

    @xml_handle_element("properties")
    def handle_properties(self, node):
        self.properties.extend(node.iter_from(Property))


with ZipFile("asb19550103-20211231-01.zip") as zip_file:
    with zip_file.open("asb19550103-20211231-01.xml") as xml_file:
        for assignment_entry in Parser(xml_file).iter_from(AssignmentEntry):
            pprint(assignment_entry)
            # do whatever you want with assignment_entry here

运行上面的代码会 output 所有的AssignmentEntry实例:

AssignmentEntry(assignor=Assignor(city='DALLAS', state='TEXAS'),
                properties=[Property(serial=71231446, registration=218184),
                            Property(serial=71538408, registration=506247),
                            Property(serial=71510081, registration=509215)])
AssignmentEntry(assignor=Assignor(city='JERSEY CITY', state='NEW JERSEY'),
                properties=[Property(serial=71230951, registration=217985),
                            Property(serial=71224781, registration=212380),
                            Property(serial=71255202, registration=243916),
                            Property(serial=71486386, registration=420259),
                            Property(serial=71515236, registration=434974),
                            Property(serial=71620823, registration=572309)])
AssignmentEntry(assignor=Assignor(city='SANTA BARBARA', state='CALIFORNIA'),
                properties=[Property(serial=71564699, registration=542581),
                            Property(serial=71564406, registration=578399)])
... etc. ...

我选择使用数据类来保存数据,但可以随意使用其他数据表示。

有关使用bigxml库的更多信息,请参阅其文档

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM