Traiter les données Pubmed .xml avec python [Partie 2]

introduction

Cet article est mon propre mémo. Cependant, nous vous serions reconnaissants si vous pouviez nous donner vos avis / conseils d'amélioration.

Dans l'article précédent, j'ai compris comment utiliser la bibliothèque pour traiter des données au format xml. Dans cet article, nous allons créer une classe wrapper pour le traitement des données papier Pubmed.

La classe wrapper vous permet d'extraire des informations de base telles que l'ID pubmed, le doi, l'année de publication et le titre de chaque donnée d'article. De plus

  1. Nombre total d'auteurs,
  2. Liste des auteurs ayant répondu (si plus, tous)
  3. Quel est le numéro d'auteur d'un auteur? Etc. peut être retourné.

Il semble qu'il ne soit souvent pas inclus dans les données publiées sur l'article sur l'identité de l'auteur répondant de l'article, mais qui est l'auteur de l'article qui a répondu est une information importante, alors traitez-la aussi soigneusement que possible. Je vais

Nous pourrons également trouver des informations sur le co-premier, le co-dernier et «l'égalité».

Traitement de l'auteur correspondant

L'identité de l'auteur répondant n'est pas explicitement indiquée dans les données pubmde. En d'autres termes, vous devez examiner de près les données pour déterminer qui est l'auteur répondant. J'ai décidé de juger comme suit.

Il existe deux types d'auteurs, l'un qui représente une personne et l'autre qui représente un groupe de recherche, mais j'aimerais être en mesure de savoir si une personne en particulier est l'auteur répondant de l'article. Je ne penserai à rien d'autre qu'à "auteur humain)".

Flux de jugement: (Si chaque élément ne peut être confirmé, jugez par l'élément ci-dessous)

  1. S'il n'y a qu'un seul auteur, cette personne est l'auteur répondant.
  2. Si les informations d'affiliation de l'auteur (Auteur-> Informations d'affiliation-> Texte d'affiliation) ont une adresse e-mail, cette personne est l'auteur qui répond.
  3. S'il y a plusieurs auteurs et qu'un seul d'entre eux a des informations d'affiliation, cet auteur est l'auteur répondant (tous les auteurs sont considérés comme ayant la même affiliation).
  4. Cas où vous ne savez pas qui est l'auteur qui a répondu

En d'autres termes, 4 est un cas où il y a plusieurs auteurs, personne n'a d'informations d'adresse e-mail et plusieurs auteurs (peut-être tous) ont des informations d'affiliation. Fondamentalement, si vous passez de la page publiée à la page de l'article lié, il sera clair qui est l'auteur de la réponse, mais je ne suivrai pas cela ici.

Traitement de l'information sur «l'égalité»

Quand j'ai lu la description de Pubmed de xml, il est dit d'ajouter Y à EqualContrib pour indiquer une contribution égale. En d'autres termes <Author EqualContrib="Y"> Un exemple est donné.

Quand je l'ai recherché, il semblait y avoir un exemple où un seul auteur a Equal Contrib = "Y". Cependant, en plus de ces problèmes, il existe de nombreux exemples où les informations d'affiliation mentionnent une contribution égale.

<Author>
    <AffiliationInfo>
        <Affiliation>###C'est écrit ici à ta manière###</Affiliation>
    </AffiliationInfo>
</Author>

Exemple:Y compris égal: 
Equal authorship.
Joint last author with equal contributions.
Equal contribution.
Equal contribution as senior author.
A.P. and A.J. are the equal senior authors.
Contribute equal to this work.
Co-first authors with equal contribution.
Equal contributor.
These authors are joint senior authors with equal contribution.
Joint last author with equal contributions.
* Equal contributors.

Exemple:Y compris également
These authors contributed equally to this article.
Both authors contributed equally.
These authors contributed equally to this work.
Contributed equally.
These authors contributed equally and are co-first authors.

Dans certains cas, l'auteur, qui n'a rien à voir avec une contribution égale, a écrit sur l'égalité. Exemple 32281472 Dans certains cas, "Equal" est inclus dans le nom d'affiliation. Foundation for Research on Equal Opportunity Social and Health Inequalities Network Pakistan Center for Health Policy and Inequalities Research

La description est trop large à gérer pour lire et traiter le contenu. Donc pour chaque auteur

  1. S'il existe une description de \ 1
  2. S'il y a une description d'égale et d'égalité dans \ , 2
  3. 0 si ni l'un ni l'autre

J'ai décidé de le conserver sous forme de liste d'entrées (j'ai vérifié 63 686 éléments avec les deux descriptions et n'en ai trouvé aucun, j'ai donc décidé de ne pas en avoir. S'il y en a un, ce sera 1 en cours de traitement), Nous discuterons de cette division plus tard, ainsi que des modèles existants.

Politique de conception de classe

Les trois balises suivantes pour les données Pubmed

1.PubmedArticle、 2.Author、 3.Affiliation

Pour ce qui est, créez une classe pour le gérer. Les noms de classe sont ** PubmedArticle **, ** PubmedAuthor ** et ** PubmedAffiliation **, et les objets ElementTree correspondants sont stockés dans chacun.

Ces classes sont des classes wrapper qui conservent l'objet Element intact. Encapsulez-le pour une inspection facile. L'objet PubmedArticle a une référence à l'objet PubmedAuthor et l'objet PubmedAuthor a une référence à l'objet PubmedAffiliation. L'appel de méthode doit suivre ce flux et ne pas revenir en arrière. Ici, la description commence à partir de la classe en aval.

Combien de méthodes préparez-vous?

J'ai créé les trois classes ci-dessus et défini diverses méthodes comme suit, mais combien de méthodes dois-je créer en premier lieu?

En premier lieu, si l'utilisateur est familier avec le format de données pubmed, etc., la classe wrapper n'est pas nécessaire en premier lieu, mais même si vous ne connaissez pas du tout le format de données pubmed ou le modèle de données, vous pouvez entièrement traiter en utilisant ces classes. Je me demande un peu si c'est possible. Cela est dû au fait qu'il existe de nombreux endroits où les données sont écrites différemment pour chaque enregistrement publié et ne peuvent pas être traitées de manière uniforme (par exemple, l'année de publication est écrite et l'auteur qui répond n'est souvent pas clair. , Les informations sur l'égalité sont données de différentes manières).

Dans ce cas, je pense que nous viserons une classe qui convient aux utilisateurs qui ont une certaine connaissance de ce à quoi ressemblent les données publiées.

Classe PubmedAffiliation

Il convient de noter qu'un auteur peut avoir plusieurs affiliations Pubmed. Les numéros suivants correspondent aux numéros attribués aux méthodes dans le code.

  1. Méthode d'initialisation. Reçoit un objet xmlElement.
  2. Une méthode pour déterminer si les informations d'affiliation comprennent une adresse e-mail,
  3. Méthode qui renvoie les informations d'affiliation,
  4. Une méthode pour vérifier si les informations d'affiliation incluent toutes les chaînes de caractères incluses dans la liste spécifiée. J'ai préparé.
import xml.etree.ElementTree as ET
import re

class PubmedAffiliation():

    E_MAIL_PATTERN = re.compile(r'[0-9a-z_./?-]+@([0-9a-z-]+\.)+[0-9a-z-]+')

#1 Méthode d'initialisation
    def __init__(self, xmlElement):
        self.xml = xmlElement
        
#2 Votre affiliation comprend-elle une adresse e-mail?: bool
#référence:Si votre affiliation comprend une adresse e-mail, vous pouvez la considérer comme un auteur répondant, mais sachez que la littérature plus ancienne peut ne pas indiquer votre adresse e-mail.
    def hasAnyMailAddress(self,):
        affiliation = self.xml.text
        result = self.E_MAIL_PATTERN.search(affiliation)
        if result is not None:
            return True
        return False     

#3 Renvoyer les informations d'affiliation sous forme de texte: str
    def affiliation(self,):
        if self.xml is not None:
            return self.xml.text
        return "-"

#4 Liste avec affiliation spécifiée(words)Contient-il tous les mots contenus dans: bool
    def isAffiliatedTo(self,words):#Vrai si tous sont inclus
        for word in words:
            if not word in self.affiliation():
                return False
        return True

Classe PubmedAuthor

Les numéros suivants correspondent aux numéros attribués aux méthodes dans le code.

  1. Méthode d'initialisation. Reçoit un xmlElement.
  2. Une méthode pour vérifier s'il existe des informations d'affiliation, y compris une adresse e-mail,
  3. Une méthode qui renvoie le nom de famille,
  4. Une méthode qui renvoie le prénom (Prénom),
  5. Méthode qui renvoie les initiales,
  6. Une méthode qui renvoie une liste d'informations d'affiliation (objets PubmedAffiliation)
  7. Une méthode pour vérifier s'il existe des informations d'affiliation qui incluent toutes les chaînes incluses dans la liste de chaînes spécifiée. Préparé.

La variable singleCommonAffi, qui définit None lors de l'initialisation, est définie selon les besoins lors de l'initialisation de l'objet PubmedArticle (en fonction des données publiées, un seul auteur peut avoir des informations d'affiliation, auquel cas Décidé de considérer ces informations d'affiliation comme une affiliation commune à tous les auteurs).


class PubmedAuthor():

#1 Méthode d'initialisation
    def __init__(self, xmlElement):
        self.xml = xmlElement
        self.singleCommonAffi = None

#2 Votre adresse e-mail figure-t-elle dans votre affiliation?: bool    
    def withAnyMailAddress(self,):#Est-ce un auteur répondant?
        for x in self.xml.findall('AffiliationInfo/Affiliation'):#Affiliation
            pubmedAffiliation = PubmedAffiliation(x)
            if pubmedAffiliation.hasAnyMailAddress():
                return True
        return False

#3 renvoie le nom: str    
    def lastName(self,):
        x = self.xml.find('LastName')
        if x is not None:
            return x.text
        return "-"

#4 renvoie le prénom: str    
    def foreName(self,):
        x = self.xml.find('ForeName')
        if x is not None:
            return x.text
        return "-"

#5 Renvoyer les initiales: str    
    def initials(self,):
        x = self.xml.find('Initials')
        if x is not None:
            return x.text
        return "-"

#6 Affiliation avec cet auteur(Objet PubmedAffiliation)Liste comprenant tous: list
    def affiliations(self,):
        x = []
        for y in self.xml.findall('AffiliationInfo/Affiliation'):#Affiliation
            x.append(PubmedAffiliation(y))
        return x

#7 Les informations d'affiliation incluent-elles tous les mots spécifiés dans la liste?: bool
    def isAffiliatedTo(self,words):
        for x in self.xml.findall('AffiliationInfo/Affiliation'):#Affiliation
            pubmedAffiliation = PubmedAffiliation(x)
            if pubmedAffiliation.isAffiliatedTo(words):
                return True
        #Sans singleCommonAffi, ne cherchez plus
        if self.singleCommonAffi is None
            return False

        #Découvrez singleCommonAffi. Vrai si tous les mots spécifiés sont présents
        for word in words:
            if not word in self.singleCommonAffi:
                return False        
        return True

PubmedArticle classe

Lors de l'initialisation, il reçoit un objet xmlElement et examine les éléments suivants:

  1. Liste des auteurs humains (objets PubmedAuthor),
  2. Liste des auteurs ayant répondu (objets PubmedAuthor),
  3. Pour chaque auteur, une liste d'informations sur la qualité,
  4. Liste d'informations sur l'égalité

Il a un grand nombre de méthodes. Le numéro correspond au numéro attribué à la méthode dans le code.

  1. Informations sur les coauteurs: str
  2. Vérifier ou non: booléen
  3. S'il s'agit d'erratum (article corrigé): bool
  4. Type de publication: str
  5. Identificateur de document (doi): str
  6. pubmed id(pmid): str
  7. Titre: str
  8. Nom du journal: str
  9. Année de publication: str
  10. Mois de publication: str
  11. Langue de description: str
  12. Identifiez l'auteur de la personne spécifiée dans les taples ForeName et LastName: int
  13. Renvoie si la personne spécifiée dans les taples ForeName et LastName est incluse dans la liste des auteurs spécifiée: bool
  14. La personne indiquée dans les taples ForeName et LastName est-elle l'auteur de cet article?
  15. L'auteur correspondant est-il révélé?: Bool
  16. La personne spécifiée dans les noms ForeName et LastName est-elle l'auteur répondant?: Bool
class PubmedArticle():

#0 Méthode d'initialisation
    def __init__(self, xmlElement):
        self.xml = xmlElement
        self.humanAuthors = []
        self.corespondingAuthors = []
        self.collectiveNames = []   #Dans certains cas, le nom du groupe est inclus comme auteur. non-human author
        self.singleCommonAffi = None #
        self.equalityStatements = [] #Description de l'égalité
        self.authorStates = []

        #authorStates est pour chaque humain
        # 0:Pas de description
        # 1: EqualContrib =Il y a une description de Y.
        # 2:Il y a une description liée à la qualité dans l'affiliation.
        #Soit 0, 1, 2 pour chaque auteur.
        #Considérant l'auteur dans son ensemble, il existe plusieurs modèles
        #modèle 1:Tout 1....Tout le monde co-premier à co-last
        #Motif 2:Deux ou trois de l'avant en font un....co-1st
        #Modèle 3:Deux à l'arrière font 1.....co-last
        #Modèle 4:Le premier est 2...Il y a quelque chose dans la qualité. Je ne sais pas si je dois le lire. Cette description est conservée dans qualityStatements.
        #Modèle 5:Autre

        #Recueillez des auteurs humains.
        for x in self.xml.findall('MedlineCitation/Article/AuthorList/Author'):
            pubmedAuthor = PubmedAuthor(x)
            if x.find('CollectiveName') is not None:#<Author>Il y a des cas où le nom du groupe est écrit. Ne l'incluez pas dans l'auteur, mais gérez-le séparément.
                self.collectiveNames.append(pubmedAuthor)
            else :
                self.humanAuthors.append(pubmedAuthor)
        
        #Rassemblez les auteurs correspondants.(Incidemment, s'il n'y a qu'un seul auteur avec des informations d'affiliation, vérifiez cette affiliation.)。
        if len(self.humanAuthors) == 1:#Quand il n'y a qu'un seul auteur. Cette personne est un auteur répondant.
            self.corespondingAuthors.append(self.humanAuthors[0])
        else:
            for author in self.humanAuthors:
                if author.withAnyMailAddress():#Auteur correspondant si l'adresse e-mail est inscrite dans la pièce jointe
                    self.corespondingAuthors.append(author)
            if len(self.corespondingAuthors) == 0:
                pubmedAffiliations = []
                humanAuthorsWithAffiliation =[]
                for author in self.humanAuthors:
                    x =  author.xml.find('AffiliationInfo/Affiliation')
                    if x is not None:#Il y a des informations d'affiliation
                        humanAuthorsWithAffiliation.append(author)
                        pubmedAffiliations.append(PubmedAffiliation(x))
                        
                if (len(humanAuthorsWithAffiliation) == 1):
                    self.corespondingAuthors.append(humanAuthorsWithAffiliation[0])
                    self.singleCommonAffi = pubmedAffiliations[0]
                    #Donnez à tous les auteurs ces informations
                    for author in self.humanAuthors:
                        author.singleCommonAffi = self.singleCommonAffi
        
        #Dans la littérature, co-premier ou co-Informations sur le dernier(Information sur l'égalité)Déterminer si est inclus
        for author in self.humanAuthors:
            state = 0
            if 'EqualContrib' in author.xml.attrib:
                if author.xml.attrib['EqualContrib'] == 'Y':
                    state = 1
            else :
                for x in author.xml.findall('AffiliationInfo/Affiliation'):
                    if ' equal ' in x.text or 'Equal ' in x.text or ' equally ' in x.text or 'Equally ' in x.text:
                        state = 2
                        self.equalityStatements.append(x.text)
                        break
            self.authorStates.append(state)

#1 Renvoie des informations sur la co-création.
    def coauthorshipInfo(self,):
        if all(map(lambda x: x == 1,self.authorStates)):#Tout 1
            return "All authors are equal contributors."
        if any(map(lambda x: x == 2,self.authorStates)):#Au moins un vaut 2
            return "Specific descriptions on co-authorship."
        if self.authorStates[0] == 1 and self.authorStates[-1] == 1:#1 au début et 1 à la fin
            return "co-first and co-last authorships are described."
        if self.authorStates[0] == 1:#Le premier est 1
            count = 0
            for x in self.authorStates:
                if x == 1:
                    count += 1
                else:
                    break
            return "co-first authorship is described. " + str(count) + " co-first authors"
        if self.authorStates[-1] == 1:#Le dernier est 1
            count = 0
            for x in reversed(self.authorStates):
                if x == 1:
                    count += 1
                else:
                    break
            return "co-last authorship is described." + str(count) + " co-last authors"
        return None

#2 avis ou pas:valeur booléenne
    def isReview(self,):
        for x in self.xml.findall('MedlineCitation/Article/PublicationTypeList/PublicationType'):
            if (x.text == 'Review'):
                return True
        return False

#3 S'il s'agit d'un article corrigé:valeur booléenne
    def isErratum(self,):
        for x in self.xml.findall('MedlineCitation/Article/PublicationTypeList/PublicationType'):
            if (x.text == 'Published Erratum'):
                return True
        return False

#4 Type de publication
    def PublicationType(self,):
        for x in self.xml.findall('MedlineCitation/Article/PublicationTypeList/PublicationType'):
            if x.text is not None:
                return x.text
        return "-"

#5 Identifiant du document(doi): str
    def doi(self,):
        for x in self.xml.findall('MedlineCitation/Article/ELocationID'):
            if(x.get('EIdType') == 'doi'):
                return x.text
        return "-"

#6 pubmed id(pmid): str
    def pmid(self,):
        element = self.xml.find('MedlineCitation/PMID')
        if element is not None:
            return element.text
        else:
            return "-"

#7 titres: str
    def title(self,):
        element = self.xml.find('MedlineCitation/Article/ArticleTitle')
        if element is not None:
            return element.text
        else:
            return "-"

#8 Nom du journal: str
    def journal(self,):
        element = self.xml.find('MedlineCitation/Article/Journal/Title')
        if element is not None:
            return element.text
        else:
            return "-"

#9 Année de publication: str
#référence: <MedlineDate>À"2019 Mar - Apr"Il y a un cas où c'est écrit.
#référence: <MedlineDate>À"2012-2013"Il y a un cas où c'est écrit.
    def year(self,flag="all"):
        element = self.xml.find('MedlineCitation/Article/Journal/JournalIssue/PubDate/Year')
        if element is not None:
            return element.text
        else:
            element = self.xml.find('MedlineCitation/Article/Journal/JournalIssue/PubDate/MedlineDate')
            if element is not None:
                if flag == "all":#Renvoie la chaîne entière par défaut
                    return element.text
                else:#Sinon, retournez la première année à 4 chiffres
                    m = re.search('(\d{4})',element.text)
                    if m is not None:
                        return m.group(0)
                    else:
                        return "0"
            return "0"

#10 Mois de publication: str
    def month(self,):
        element = self.xml.find('MedlineCitation/Article/Journal/JournalIssue/PubDate/Month')
        if element is not None:
            return element.text
        else:
            element = self.xml.find('MedlineCitation/Article/Journal/JournalIssue/PubDate/MedlineDate')
            if element is not None:
                return element.text.split(' ')[1]
            return "-"

#11 Langue de description
    def language(self,):
        element = self.xml.find('MedlineCitation/Article/Language')
        if element is not None:
            return element.text
        else:
            return "-"



#################################################################################
##########Le nom de l'auteur(Taple)Contactez-nous à.
#################################################################################
#Découvrez le numéro de l'auteur(0 sinon l'auteur):int。
#12 La requête est un tapple de ForeName et LastName
    def positionInAuthors(self,query):#S'il s'agit du premier auteur, la valeur de retour est 1(Pas 0).. la requête est un taple(ForeName, LastName) 
        for x in range( len(self.humanAuthors) ):
            if self.humanAuthors[x].foreName() == query[0] and self.humanAuthors[x].lastName() == query[1]:
                return x + 1
            if self.humanAuthors[x].initials() == query[0] and self.humanAuthors[x].lastName() == query[1]:
                return x + 1
        return 0            

#13 auteurs sont inclus ou renvoyés dans la liste des auteurs spécifiée: bool
#La liste des auteurs désignés est, par exemple, une liste d'auteurs ayant répondu.
    def isAuthorIn(self,query,authors):#Nom_Renvoie si le nom de famille est inclus dans les auteurs spécifiés. la requête est un taple
        for author in authors:
            if ( author.foreName() == query[0] and author.lastName() == query[1]):
                return True
            if ( author.initials() == query[0] and author.lastName() == query[1]):
                return True
        return False

#14 Vérifiez si l'auteur spécifié dans le taple est l'auteur: bool
    def isAuthor(self,query):
        for author in self.humanAuthors:
            if author.foreName == query[0] and author.lastName == query[1]:
                return True
            if author.initials == query[0] and author.lastName == query[1]:
                return True
        return False

#15 Découvrez si l'auteur répondant est connu: bool
    def isCorrespondingAuthorDefined(self,):
        if len(self.corespondingAuthors) == 0:
            return False
        else:
            return True

#16 Découvrez si l'auteur spécifié dans le tuple est un auteur répondant: bool
    def isCorrespondingAuthor(self,query):
        for author in self.corespondingAuthors:
            if ( author.foreName() == query[0] and author.lastName() == query[1]):
                return True
            if ( author.initials() == query[0] and author.lastName() == query[1]):
                return True
        return False

En fait utiliser

Lisons les données. pubmed_result.xml est un fichier de données au format xml téléchargé depuis la page pubmed. Le fichier de données contient plusieurs enregistrements Pubmed, que nous lisons dans leur intégralité et stockons l'arborescence des éléments dans la variable racine.

test_data = open("/Users/yoho/Downloads/pubmed_result.xml", "r")
contents = test_data.read()
root = ET.fromstring(contents)

Comment accéder aux informations de base:

for pubmedArticleElement in root.findall('PubmedArticle'):
    p = PubmedArticle(pubmedArticleElement)#Créer un enregistrement comme objet PubmedArticle
    
    print(
        p.pmid(),# pubmed id
        p.doi(),# doi (Identifiant du document)
        p.year(flag=1),#Année de publication. Informations sur l'année uniquement. Drapeau pour tous= "all"
        p.month(),#Mois de publication
        p.title(),#Titre du papier
        p.language(),#Langue
        p.PublicationType(),#Type de publication
        sep = "\t",end="\n")

Comment accéder à des informations autres que de base:

for pubmedArticleElement in root.findall('PubmedArticle'):
    p = PubmedArticle(pubmedArticleElement)#Créer un enregistrement comme objet PubmedArticle
    
    #Nombre d'auteurs humains
    print (str(p.numberOfAuthors()))

    #Accès au nom de l'auteur
    for x in p.humanAuthors:
        print(
            x.foreName(), # First Name
            x.lastName(), # Last Name
            sep="\t",end="\t")
    print("")

    #Découvrez si l'auteur répondant a été identifié
    if len(p.corespondingAuthors) != 0:
        print("L'auteur correspondant peut être trouvé à partir des informations publiées",end="\t")
    else :
        print("Les informations publiées ne disent pas qui est l'auteur qui a répondu",end="\t")

    #Accès à l'auteur correspondant
    if len(p.corespondingAuthors) == 0:
        print("Qui est l'auteur répondant est inconnu des informations publiées",end="\t")
    else:
        print("Nombre d'auteurs ayant répondu:"+str(len(p.corespondingAuthors)),end="\t")
        for x in p.corespondingAuthors:
           print(
            x.foreName(), # First Name
            x.lastName(), # Last Name
            sep=" ",end="\t")
    
    #Découvrez si vous êtes un auteur répondant en spécifiant le prénom et le nom dans le taple
    author = ("Taro","Tohoku")

    if p.isAuthorIn(author,p.corespondingAuthors):
        print(author[0] + " " + author[1] + "Est l'auteur répondant de cet article.",end="\t")
    else :
        print(author[0] + " " + author[1] + "N'est pas l'auteur répondant de cet article.",end="\t")

    #Découvrez si vous êtes l'auteur en spécifiant le prénom et le nom dans le taple
    if p.isAuthor(author):
        print(author[0] + " " + author[1] + "Est l'auteur de cet article.",end="\t")
    else:
        print(author[0] + " " + author[1] + "N'est pas l'auteur de cet article.",end="\t")
       
    #Découvrez le numéro de l'auteur en spécifiant le prénom et le nom dans le clavier.
    position = p.positionInAuthors(author)
    if position != 0:
        print(str(position) + "Deuxième auteur",end="\t")
    else: 
        print(author[0] + " " + author[1] + "N'est-ce pas l'auteur",end="\t")
    

Modèle de description pour la co-création

Ici, j'ai analysé toutes les données publiées qui incluent le SIDA dans le titre. Vous pouvez trouver l'égalité dans la liste des entiers "authorStates". Le nombre d'enregistrements est de 63 686 (taille du fichier 500 Mo).


for pubmedArticleElement in root.findall('PubmedArticle'):
    p = PubmedArticle(pubmedArticleElement)

    if any(p.authorStates):
        print(p.pmid(),end="\t")
        print("".join(map(str,p.authorStates)),end="\n")
        if p.authorStates[0] == 2:#Quand il est 2, co-Il y a une description de la paternité.
            pass #Impression omise(" ".join(p.equalityStatements),end="\t")
#production
# pumed id      co-Description état de la paternité(1 auteur 1 chiffre)
# 32209633	000000011
# 30914431	110000000000
# 30912750	100
# 30828360	11000000000000
# 30421884	1100
# 30467102	10000
# 30356992	1100000000
# 29563205	1100000011
# 29728344	111111111
# 29588307	110000000000
# 29254269	110000000000
# 27733330	10
# 26990633	200000000
# 26949197	111000000000000
# 26595543	200000000000
# 26825036	20000000000000
# 26691548	20000
# 26397046	01110000
# 26535055	110
# 26544576	2000000000000
# 26173930	110000000011
# 26166108	20000000000
# 26125144	20000
# 25949269	1111111
# 24906111	20000000
# 24401642	200
# 22350831	110000000000000
# 22192455	11000
# 22098625	1110
# 21129197	11
# 20540714	11

Il semble qu'il existe divers cas comme les cas où 1 est donné à tout le monde, les cas où seul le début est 2, les cas où les deux premiers et les deux derniers ont 1 et ainsi de suite. Je voudrais adopter 1 parce qu'il est écrit selon les règles, mais il y a des cas où seul le début est 1 (qui et égal?), Le début est 0, et les deuxième et troisième personnes sont 1 (données insuffisantes? ) Etc.

Il existe différents types de descriptions dans le cas où 2 est attribué, et vous ne pouvez pas comprendre ce que cela signifie à moins de lire la description une par une. Par conséquent, j'ai décidé de "déterminer de quel type de papier il s'agit en se référant à cette liste d'ints selon les besoins", et de faire référence aux informations en 2 dans le texte.

Découvrez tout un institut de recherche

Il y a des moments où vous voulez savoir qui écrit et à quel point une institution de recherche dans son ensemble. Il s'agit d'un cas où vous spécifiez un établissement de recherche avec pubmed, effectuez une recherche et analysez le xml obtenu. Tout d'abord, créez un dictionnaire avec "Tupple du prénom et du nom" comme clé et "Liste contenant les objets de l'article Pubmed" comme valeur.

#Créer un dictionnaire
authorAndArticle = {}#dictionnaire
for pubmedArticleElement in root.findall('PubmedArticle'):
    p = PubmedArticle(pubmedArticleElement)

    for author in p.humanAuthors:
        if author.isAffiliatedTo(['Graduate School','Sciences']):
            authorFullName = (author.foreName(),author.lastName()) #Utiliser taple comme clé
            if authorFullName in authorAndArticle:#Si le dictionnaire a déjà une clé
                authorAndArticle[authorFullName].append(p)
            else:#Si la clé n'est pas encore dans le dictionnaire
                authorAndArticle[authorFullName] = [p]

Sort des données pour chaque personne.

for authorFN in authorAndArticle:
    pubmedArticles = authorAndArticle[authorFN]
    print(authorFN[0] + " " + authorFN[1])
    for pma in pubmedArticles:
        
        print('            ',end= '')

        #Informations sur le journal
        print(pma.pmid(), pma.year(), pma.journal(), sep="\t",end='\t')

        # co-Condition de jugement de la paternité
        print(pma.coauthorshipInfo(),end='\t')
        
        # co-informations sur le statut d'auteur. Au début pour qu'il soit traité comme une chaîne de caractères sur Excel'Ajouter
        print("'" + "".join(map(str,pma.authorStates)),end="\t")

        #Quel nombre d'auteur
        print(str(pma.positionInAuthors(authorFN)),end='\t')
        
        #Nombre d'auteurs
        print(str(len(pma.humanAuthors)),end='\t')
        
        #Découvrez si c'est le premier auteur
        if pma.positionInAuthors(authorFN) == 1:
            print("First Author",end='\t')
        else:
            print("____",end='\t')

        #Découvrez s'il s'agit d'un auteur répondant
        if len(pma.corespondingAuthors) == 0:
            print("Auteur correspondant inconnu",end="\t")
        elif pma.isAuthorIn(authorFN,pma.corespondingAuthors):
            if len(pma.corespondingAuthors) == 1:
                print("Coresponding author",end="\t")
            else:
                print("Coresponding author of total " + str(len(pma.corespondingAuthors)) + " coresponding authors",end='\t')
        else:
            print("",end="\t")
        
        #Découvrez s'il s'agit du dernier auteur.
        if pma.positionInAuthors(authorFN) == len(pma.humanAuthors):
            print("Last author",end='\t')
        else:
            print("",end='\t')

        print("")

Il est maintenant possible de convertir les données de qui a écrit quel type de papier à partir des données de chaque article en données de chaque personne. Dans les documents plus anciens, si le prénom de l'auteur n'est pas inclus dans les données, ou si le nom change en raison d'un mariage, etc., il sera traité comme une personne différente. De plus, s'ils ont le même nom et le même nom, ils ne peuvent pas être distingués. Dans les nouveaux articles, ORCID peut être utilisé pour faire la distinction entre les personnes, mais à moins que ORCID ne soit attribué rétroactivement aux auteurs, il semble très difficile de connaître l'identité de l'auteur de manière uniforme.

À la fin

J'ai essayé de faire diverses choses, mais c'était difficile parce que les données publiées étaient écrites de différentes manières et ne pouvaient pas être traitées uniformément. En ce qui concerne l'égalité, nous avons uniquement créé une liste indiquant s'il existe ou non une description pour chaque auteur, le reste doit donc être géré du côté de l'utilisateur.

Recommended Posts

Traiter les données Pubmed .xml avec python [Partie 2]
Traiter les données Pubmed .xml avec python
Traitez le XML avec Python.
Traitez le Big Data avec Dataflow (ApacheBeam) + Python3
Analyse de données avec Python
Créez des données de test comme ça avec Python (partie 1)
Traitement d'image avec Python (partie 2)
Exemple de données créées avec python
Etudier Python avec freeCodeCamp part1
Images en bordure avec python Partie 1
Générer du XML (RSS) avec Python
Obtenez des données Youtube avec python
Etudier Python avec freeCodeCamp part2
Traitement d'image avec Python (partie 1)
Résolution de Nampre avec Python (partie 2)
Traitement d'image avec Python (3)
Traiter les données csv avec python (traitement du comptage à l'aide de pandas)
Grattage avec Selenium + Python Partie 2
Lire des données json avec python
Je veux pouvoir analyser des données avec Python (partie 3)
Je veux pouvoir analyser des données avec Python (partie 1)
Je veux pouvoir analyser des données avec Python (partie 4)
Je veux pouvoir analyser des données avec Python (partie 2)
[Je l'ai fait avec Python] Outil pour la sortie par lots de données XML
Jouez des nombres manuscrits avec Python Partie 1
Application de Python: Nettoyage des données Partie 1: Notation Python
[Automatisé avec python! ] Partie 1: fichier de configuration
Application Python: Traitement des données # 3: Format des données
[Python] Obtenez des données économiques avec DataReader
Structure de données Python apprise avec la chimioinfomatique
Visualisez facilement vos données avec Python seaborn.
Automatisez des tâches simples avec Python Part0
Application Python: visualisation de données partie 1: basique
[Automatisé avec python! ] Partie 2: Fonctionnement des fichiers
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
[Note] Obtenir des données de PostgreSQL avec Python
Application de Python: visualisation de données Partie 3: divers graphiques
Jouez des nombres manuscrits avec python, partie 2 (identifier)
Modulation et démodulation FM avec Python Partie 3
Obtenez des données alimentaires avec l'API Amazon (Python)
Essayez de travailler avec des données binaires en Python
Automatisez des tâches simples avec Python Part1 Scraping
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
100 traitements de langage avec Python (chapitre 2, partie 2)
Manipulation des données DynamoDB avec Lambda (Node et Python)
Manipulation d'Azure CosmosDB à partir de Python Part.2
Convertissez des données FX 1 minute en données 5 minutes avec Python
Traiter plusieurs listes avec for en Python
100 traitements de langage avec Python (chapitre 2, partie 1)
Modulation et démodulation FM avec Python Partie 2
Recommandation d'Altair! Visualisation des données avec Python