如何调整 sparql 查询以返回甚至简短的信息

问题描述

我是这方面的新手,即提问方面,所以如果您需要任何其他信息,请告诉我。

我有一个包含 2900 个条目的数据集,其中大部分是荷兰和佛兰德诗人。我想通过查询 wikidata 向这个数据框添加信息;性别、国籍、出生日期、死亡日期。现在两个小国能有多少诗人?并非所有这些都可以在 wikidata 上找到(我稍后会处理),对于那些有的,信息有时非常稀缺。

我使用了以下查询

import requests

def get_data_for_poet(poet):
    url = 'https://query.wikidata.org/sparql'
    query = '''
    prefix schema: <http://schema.org/>
            SELECT ?item ?occupation ?genderLabel ?bdayLabel ?bnatLabel ?deathLabel
            WHERE {
                ?item ?label "''' + poet + '''"@en.
                ?item wdt:P106 ?occupation .
                ?item wdt:P21 ?gender .
                ?item wdt:P569 ?bday .
                ?item wdt:P27 ?bnat .
                ?item wdt:P570 ?death .

            SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
        }
'''

r = requests.get(url,params = {'format': 'json','query': query})
try:
    #print(r.content)
    data = r.json()
    return {
        'gender': data['results']['bindings'][0]['genderLabel']['value'],'birthday': data['results']['bindings'][0]['bdayLabel']['value'],'death': data['results']['bindings'][0]['deathLabel']['value'],'nationality': data['results']['bindings'][0]['bnatLabel']['value'],}
except:
    return {
        'gender': 'Onbekend','birthday': 'Onbekend','death' : 'Onbekend','nationality': 'Onbekend'
    }

然后我为前 20 个条目运行以下代码

import time
import math

def get_poet_Metadata_for_row(row):
    f = math.floor(row['index']/80) # the API returns errors 472 if it goes any faster
    print(row['index'])
    time.sleep(1+f)
    poet = row['Dichter']    
          
    
    if poet == 'Onbekend':
        return pd.Series(['Onbekend','Onbekend','Onbekend'])
                         
    data = get_data_for_poet(poet)
    
    print(data)
    
    poets[poet] = data
    
    return pd.Series([data['birthday'],data['nationality'],data['gender'],data['death']])


df[['Geboortedatum','Nationaliteit','Geslacht','Gestorven']] = df[:20].apply(get_poet_Metadata_for_row,axis=1)

但不幸的是,我注意到查询仅在 Q ID 的所有四条信息都可用时返回信息。

这是输出的一部分:

12
{'gender': 'male','birthday': '1934-08-04T00:00:00Z','death': '2012-07-11T00:00:00Z','nationality': 'Kingdom of the Netherlands'}
13
{'gender': 'Onbekend','death': 'Onbekend','nationality': 'Onbekend'}
14
{'gender': 'Onbekend','nationality': 'Onbekend'}
15
{'gender': 'Onbekend','nationality': 'Onbekend'}
16
{'gender': 'Onbekend','nationality': 'Onbekend'}

然后我试图一个一个查询这些信息(第一个性别,然后是生日,等等),但这实际上需要永远。

如何调整查询以返回所有信息,即使假设只有性别已知?我用 OPTIONAL 尝试了一些东西,但它变得非常快。我是 SPARQL 的新手,因此非常感谢您的帮助。

另外,考虑到我在这个数据集上花费的时间,我可能会受到隧道视觉的影响,但是如果有可以做到这一点的 python 包,我很想知道。

解决方法

使用 OPTIONAL 的直觉是正确的。您必须为要考虑为可选(即不必要)的每个信息添加它。

此外,为了避免误报,我认为您还应该使用 rdfs:label 而不是通用的 ?label(可以指代任何属性)。

PREFIX schema: <http://schema.org/>
SELECT ?item ?occupation ?genderLabel ?bdayLabel ?bnatLabel ?deathLabel
WHERE {
    ?item rdfs:label "Marc Tritsmans"@en.
    ?item wdt:P106 ?occupation .
    OPTIONAL { ?item wdt:P21 ?gender . }
    OPTIONAL { ?item wdt:P569 ?bday . }
    OPTIONAL { ?item wdt:P27 ?bnat . }
    OPTIONAL { ?item wdt:P570 ?death . }
    SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}

观看演示here

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...