Traiter les données Pubmed .xml avec python

introduction

Cet article est une note personnelle sur la façon d'utiliser python pour lire les données de la littérature (format xml) qui ont été capturées lors d'une recherche sur Pubmed.

Je vous serais reconnaissant de bien vouloir souligner les points que vous avez remarqués.

Données que vous souhaitez traiter

Une donnée ressemble à ce qui suit. En fait, je souhaite traiter plusieurs données, mais je vais d'abord permettre de les traiter une par une.

001.xml


<PubmedArticle>
    <MedlineCitation Status="Publisher" Owner="NLM">
        <PMID Version="1">12345678</PMID>
        <DateRevised>
            <Year>2020</Year>
            <Month>03</Month>
            <Day>27</Day>
        </DateRevised>
        <Article PubModel="Print-Electronic">
            <Journal>
                <ISSN IssnType="Electronic">1873-3700</ISSN>
                <JournalIssue CitedMedium="Internet">
                    <PubDate>
                        <Year>2020</Year>
                        <Month>Mar</Month>
                    </PubDate>
                </JournalIssue>
                <Title>Journal of XXX</Title>
            </Journal>
            <ArticleTitle>Identification of XXX.</ArticleTitle>
            <AuthorList CompleteYN="Y">
                <Author ValidYN="Y">
                    <LastName>Sendai</LastName>
                    <ForeName>Shiro</ForeName>
                    <Initials>S</Initials>
                    <AffiliationInfo>
                        <Affiliation>Sendai, Japan.</Affiliation>
                    </AffiliationInfo>
                </Author>
                <Author ValidYN="Y">
                    <LastName>Tohoku</LastName>
                    <ForeName>Taro</ForeName>
                    <Initials>T</Initials>
                    <AffiliationInfo>
                        <Affiliation>Miyagi, Japan.</Affiliation>
                    </AffiliationInfo>
                </Author>
            </AuthorList>
            <Language>eng</Language>
            <PublicationTypeList>
                <PublicationType UI="D016428">Journal Article</PublicationType>
            </PublicationTypeList>
            <ArticleDate DateType="Electronic">
                <Year>2020</Year>
                <Month>03</Month>
                <Day>23</Day>
            </ArticleDate>
        </Article>
        <CitationSubset>IM</CitationSubset>
    </MedlineCitation>
    <PubmedData>
        <PublicationStatus>aheadofprint</PublicationStatus>
        <ArticleIdList>
            <ArticleId IdType="pubmed">32213359</ArticleId>
            <ArticleId IdType="pii">S0031-9422(19)30971-9</ArticleId>
            <ArticleId IdType="doi">10.1016/j.phytochem.2020.112349</ArticleId>
        </ArticleIdList>
    </PubmedData>
</PubmedArticle>

Comprendre l'utilisation de base

Chargez la bibliothèque pour lire xml.

001.py


import xml.etree.ElementTree as ET

Lisez les données XML du fichier. Il semble que plusieurs données soient alignées avec deux sauts de ligne, alors divisez-les en une liste.

002.py


test_data = open("./xxxx/pubmed.xml", "r")
contents = test_data.read()
records = contents.split('\n\n')

Les premières données du document (enregistrements [0]) sont lues par ET.fromstring () et stockées dans la racine de la variable. Si vous regardez root avec type (), vous verrez que c'est un objet Element.

003.py


root = ET.fromstring(records[0])
type(root)
#<class 'xml.etree.ElementTree.Element'>

Vous pouvez vérifier la balise avec root.tag. Je vais vérifier.

004.py


root.tag
#'PubmedArticle'

En gros, une donnée a la forme suivante. J'ai pu accéder à la balise la plus externe avec root.tag.

002.xml


<PubmedArticle>
    <MedlineCitation>
    </MedlineCitation>
    <PubmedData>
    </PubmedData>
</PubmedArticle>

À l'intérieur de \ <PubmedArticle > se trouvent deux éléments (MedlineCitation et PubmedData), auxquels il est possible d'accéder à l'aide d'indices. Accédez en utilisant des indices et recherchez le type plus loin.

005.py


root[0]
#<Element 'MedlineCitation' at 0x10a9d5b38>
type(root[0])
#<class 'xml.etree.ElementTree.Element'>

root[1]
#<Element 'PubmedData' at 0x10aa78868>
type(root[1])
#<class 'xml.etree.ElementTree.Element'>

Vous pouvez voir que les deux sont des objets Element.

En bref, il semble que tous les nœuds soient des objets Element. Les objets élément peuvent être itérés et les nœuds enfants peuvent être récupérés et traités un par un.

for i in root:
    print(i.tag)

Les balises d'élément peuvent être recherchées dans .tag, et .attrib peut rechercher les attributs et les valeurs d'attribut attachés à cette balise.

root[0].tag
#'MedlineCitation'

root[0].attrib
#{'Status': 'Publisher', 'Owner': 'NLM'}
# root[0]La zone autour de l'étiquette est la suivante.
#    <MedlineCitation Status="Publisher" Owner="NLM">


type(root[0].attrib)
#<class 'dict'> #Classe de dictionnaire

Comment accéder à l'objet Element

Il y en aura probablement trois. Dans chaque cas, vous pouvez spécifier une ou plusieurs balises. Mettez la balise entière entre guillemets et, lorsque vous spécifiez plusieurs balises, séparez les balises par une barre oblique.

  1. find('tag1/tag2')
  2. findall('tag1/tag2')
  3. iter('tag1/tag2')

Si c'est 1, l'objet Element est retourné, s'il vaut 2, la liste des objets Element est retournée, et si c'est 3, c'est un objet pour l'itération? Sera retourné. Je vais vérifier.

root.find('MedlineCitation/DateRevised/Year')
#<Element 'Year' at 0x10a9f8ae8>

root.findall('MedlineCitation')
#[<Element 'MedlineCitation' at 0x10a9d5b38>]

root.iter('Author')
#<_elementtree._element_iterator object at 0x10aa65990>

#Répétons avec l'instruction for.
for i in root.iter('Author'):
    print(i)
#<Element 'Author' at 0x10aa6e9f8>
#<Element 'Author' at 0x10aa6ec28>

Il semble que findall () ne regarde que les nœuds enfants de l'objet Element, et iter () regarde tous les nœuds enfants, nœuds petits-enfants, nœuds arrière-petits-enfants ... de l'objet Element.

Accès à la valeur de l'objet Element

L'objet Element a deux valeurs. Valeur d'attribut et données textuelles. Les valeurs d'attribut peuvent être obtenues avec .get ('* nom de propriété ') pour les objets Element. Sinon, .attrib [' nom de la propriété *'] semble convenir.

#.get()Ou
root.find('MedlineCitation').get('Status')
#'Publisher'

#.attrib()Ou
root.find('MedlineCitation').attrib['Status']
#'Publisher'

Vous pouvez également obtenir des données texte en utilisant .text pour l'objet Element.

Les données de texte ici sont la partie entourée de balises, 2020 dans l'exemple ci-dessous. <Year>2020</Year>

Essayez d'obtenir la valeur en spécifiant le chemin vers l'objet Element avec find ().

root.find('MedlineCitation/Article/Journal/JournalIssue/PubDate/Year').text
#'2020'

Pour obtenir des informations sur plusieurs auteurs, parcourez la liste obtenue avec findall ().

Corrigé en tenant compte des affiliations multiples d'auteurs (31 mars 2020).

for x in root.findall('MedlineCitation/Article/AuthorList/Author'):
    x.find('LastName').text   #Nom de l'auteur
    x.find('ForeName').text    #Le nom de l'auteur
    for y in x.findall('AffiliationInfo'):
        y.find('Affiliation').text

Le doi (identifiant de document) est décrit dans la balise ELocationID, mais la balise ELocationID a des valeurs d'attribut, et il est nécessaire d'obtenir les données texte dans le cas de EIdType = "doi".

for x in root.findall('MedlineCitation/Article/ELocationID'):
    if(x.get('EIdType') == 'doi'):
        x.text

Il est nécessaire de distinguer si l'enregistrement est une revue ou un article de revue, qui est décrit dans le type de publication. Cependant, il existe généralement plusieurs types de publication, et si l'un d'entre eux a une valeur de révision, il semble que ce soit une révision.

Par exemple, si vous regardez l'enregistrement de révision, il ressemble à ceci:

.xml


<PublicationTypeList>
    <PublicationType UI="D016428">Journal Article</PublicationType>
    <PublicationType UI="D016454">Review</PublicationType>
    <PublicationType UI="D013485">Research Support, Non-U.S. Gov't</PublicationType>
</PublicationTypeList>

Donc, qu'il s'agisse d'un examen ou non, c'est

isReview = False
for x in root.findall('MedlineCitation/Article/PublicationTypeList'):
    if (x.text == 'Review'):
        isReview = TRUE

Je pense que c'est bien de le faire.

Pour résumer ce qui précède, y compris d'autres informations que vous souhaiterez peut-être acquérir

import xml.etree.ElementTree as ET

test_data = open("./pubmed.xml", "r")
contents = test_data.read()
records = contents.split('\n\n')
root = ET.fromstring(records[0])#Pour le moment, seul le premier cas.

#Informations sur l'auteur
for x in root.findall('MedlineCitation/Article/AuthorList/Author'):
    x.find('LastName').text   #Nom de l'auteur
    x.find('ForeName').text    #Le nom de l'auteur
    for y in x.findall('AffiliationInfo'):
        y.find('Affiliation').text#Fixé.

#Juger s'il s'agit d'un examen
isReview = False
for x in root.findall('MedlineCitation/Article/PublicationTypeList'):
    if (x.text == 'Review'):
        isReview = TRUE

# doi
for x in root.findall('MedlineCitation/Article/ELocationID'):
    if(x.get('EIdType') == 'doi'):
        x.text

#PMID
root.find('MedlineCitation/PMID').text
#Titre du papier
root.find('MedlineCitation/Article/ArticleTitle').text
#Nom du journal
root.find('MedlineCitation/Article/Journal/Title').text
#Année de publication
root.find('MedlineCitation/Article/Journal/JournalIssue/PubDate/Year').text
#Mois de publication
root.find('MedlineCitation/Article/Journal/JournalIssue/PubDate/Month').text
#Langue
root.find('MedlineCitation/Article/Language').text

Je pense que cela devrait être fait. Dans le code ci-dessus, il n'y a qu'un seul processus,

for record in records:
    root = ET.fromstring(record)
    #Décrivez le processus

Vous devriez le faire comme.

Maintenant, si vous avez des données xml, vous pouvez extraire les informations nécessaires à la fois. Tout ce que vous avez à faire est de réfléchir à la façon de le façonner.

Vous savez maintenant comment gérer les données XML.

Recommended Posts

Traiter les données Pubmed .xml avec python
Traiter les données Pubmed .xml avec python [Partie 2]
Traitez le XML avec Python.
Traitez le Big Data avec Dataflow (ApacheBeam) + Python3
Analyse de données avec python 2
Analyse de données avec Python
Exemple de données créées avec python
Générer du XML (RSS) avec Python
Obtenez des données Youtube avec python
Lire des données json avec python
Traiter les données csv avec python (traitement du comptage à l'aide de pandas)
[Python] Obtenez des données économiques avec DataReader
Visualisez facilement vos données avec Python seaborn.
Analyse de données à partir de python (visualisation de données 1)
Analyse de données à partir de python (visualisation de données 2)
Application de Python: Nettoyage des données Partie 2: Nettoyage des données à l'aide de DataFrame
Obtenez des données supplémentaires vers LDAP avec python
Construction de pipeline de données avec Python et Luigi
Recevoir des données textuelles de mysql avec python
[Note] Obtenir des données de PostgreSQL avec Python
Essayez de travailler avec des données binaires en Python
Générer des données de test japonais avec Python Faker
Convertir des données Excel en JSON avec python
Téléchargez les données de cours des actions japonaises avec Python
Traiter plusieurs listes avec for en Python
Recommandation d'Altair! Visualisation des données avec Python
Analyse de données à partir de python (pré-traitement des données-apprentissage automatique)
Faisons la manipulation des données MySQL avec Python
Organisez les données séparées par dossier avec Python
FizzBuzz en Python3
Grattage avec Python
Statistiques avec python
Grattage avec Python
Python avec Go
Analyse de données python
Twilio avec Python
Intégrer avec Python
Jouez avec 2016-Python
AES256 avec python
Testé avec Python
python commence par ()
avec syntaxe (Python)
Bingo avec python
Zundokokiyoshi avec python
Excel avec Python
[python] Lecture de données
Micro-ordinateur avec Python
Cast avec python
Créez des données de test comme ça avec Python (partie 1)
Lire les données csv Python avec Pandas ⇒ Graphique avec Matplotlib
Lire les données de la table dans un fichier PDF avec Python
Obtenez des données sur le cours de l'action avec l'API Quandl [Python]
J'ai essayé d'obtenir des données CloudWatch avec Python
Une histoire sur la gestion des données binaires en Python
Comparez les vitesses d'analyse XML avec Python et Go
Écrire des données CSV sur AWS-S3 avec AWS-Lambda + Python
J'ai commencé l'apprentissage automatique avec le prétraitement des données Python
Extraire des données d'une page Web avec Python
Communication série avec Python