代码之家  ›  专栏  ›  技术社区  ›  Tomato_Dog

用Python提取科技论文信息?

  •  2
  • Tomato_Dog  · 技术社区  · 7 年前

    我刚刚接触Python,碰巧需要从几篇科学论文中提取一些信息。

    如果给定的是纯文本,如:

    1. 介绍
      一些长篇大论
    2. 方法论
      一些长篇大论
    3. 后果
      一些长篇大论

    我怎么能把一篇论文像下面这样放到字典里呢?

    paper_1 = {
               'Introduction': some long writings,
               'Methodology': some long writings,
               'Results': some long writings
              }
    

    非常感谢:-)


    尝试之后,我运行了一些代码,但效果并不理想:

    text = 'introduction This is the FIRST part.' \
           'Methodologies This is the SECOND part.' \
           'results This is the THIRD part.'
    
    import re
    from re import finditer
    
    d={}
    first =[]
    second =[]
    title_list=[]
    all =[]
    
    for match in finditer("Methodology|results|methodologies|introduction|", text, re.IGNORECASE):
        if match.group() is not '':
            title = match.group()
            location = match.span()
            first.append(location[0])
            second.append(location[1])
            title_list.append(title)
    
    all.append(first)
    all.append(second)
    
    a=[]
    for i in range(2):
        j = i+1
        section = text[all[1][i]:all[0][j]]
        a.append(section)
    
    for i in zip(title_list, a):
        d[i[0]] = i[1]
    print (d)
    

    这将产生以下结果:

    {
    'introduction': ' This is the FIRST part.', 
    'Methodologies': ' This is the SECOND part.'
    }
    

    然而

    i) 它无法提取最后一位,这是结果部分。

    ii)。在循环中,我给range()函数输入了2,因为我知道只有3个部分(简介、方法和结果),但在一些论文中,人们会添加更多的部分,我如何才能自动为range()指定正确的值?例如,一些论文可能有以下部分:

    1. 介绍
      一些长篇大论
    2. 关于某事的一般背景
      一些长篇大论
    3. 某种类型的章节标题
      一些长篇大论
    4. 方法论
      一些长篇大论
    5. 后果
      一些长篇大论

    iii)。有没有更有效的方法可以在每个循环中构建字典?所以我不需要使用第二个循环。


    2018年3月30日更新:

    代码更新如下:

    def section_detection(text):
        title_list=[]
        all =[[],[]]
        dic={}
        count = 0
        pattern = '\d\. [A-Z][a-z]*'
    
        for match in finditer(pattern, text, re.IGNORECASE):
            if match.group() is not '':
                all[0].append(match.span()[0])
                all[1].append(match.span()[1])
                title_list.append(match.group())
                count += 1
    
        for i in range(count):
            j = i+1
            try:
                dic[title_list[i]]=text[all[1][i]:all[0][j]]
            except IndexError:
                dic[title_list[i]]=text[all[1][i]:]
    
        return dic
    

    如果按以下方式执行:

    import re
    from re import finditer
    text = '1. introduction This is the FIRST part.' \
           '2. Methodologies This is the SECOND part.' \
           '3. results This is the THIRD part.'\
           '4. somesection This SOME section'
    
    dic = section_detection(text)
    print(dic)
    

    提供:

    {'1. introduction': ' This is the FIRST part.', '2. Methodologies': ' This is the SECOND part.', '3. results': ' This is the THIRD part.', '4. somesection': ' This SOME section'}
    

    非常感谢大家!:-)

    2 回复  |  直到 7 年前
        1
  •  2
  •   Franz Forstmayr    7 年前

    尝试以下操作:

    text = 'introduction This is the FIRST part. ' \
           'Methodologies This is the SECOND part. ' \
           'results This is the THIRD part. ' \
    
    import re
    
    kw = ['methodology', 'results', 'methodologies', 'introduction']
    
    pat = re.compile(r'(%s)' % '|'.join(kw), re.IGNORECASE)
    
    sp = [x for x  in re.split(pat, text) if x]
    dic = {k:v for k,v in zip(sp[0::2],sp[1::2])}
    
    print(dic)
    

    但这只是您的示例,在现实世界的文档中,不要例外太多。您还没有指定,“简介”之前的文字是什么,以及有人在纯文本中提到“结果”是什么?

        2
  •  1
  •   shouldsee    7 年前

    真的很喜欢@franzforstmayr写的regex。只是想指出一些方法来打破它。

    text = '''
    introduction This is the FIRST part.
    introductionMethodologies This is the SECOND part.
    results This is the THIRD part.
    '''
    
    import re
    #### Regex based on https://stackoverflow.com/a/49546458/8083313
    kw = ['methodology', 'results', 'methodologies', 'introduction']
    pat = re.compile(r'(%s)' % '|'.join(kw), re.IGNORECASE)
    
    sp = [x for x  in re.split(pat, text) if x]
    print sp
    dic = {k:v for k,v in zip(sp[0::2],sp[1::2])}
    
    print(dic)
    
    
    # {'\n': 'introduction',
    #  'Methodologies': ' This is the SECOND part.\n',
    #  ' This is the FIRST part.\n': 'introduction', 
    #  'results': ' This is the THIRD part.\n'}
    

    您可以看到,由于字符的原因,列表发生了移动,并且字典已损坏。因此,我建议放置一个硬切片

    out = re.split(pat, text)
    lead = out[0:1]; ### Keep the lead available in case needed
    sp = out[1:]
    
    print sp
    dic = {k:v for k,v in zip(sp[0::2],sp[1::2])}
    
    print(dic)
    
    # {'introduction': '',
    #  'Methodologies': ' This is the SECOND part.\n',
    #  'results': ' This is the THIRD part.\n'}