如何将 sparql 查询调整为 return 甚至简短信息
How to adjust sparql query to return even brief info
我是这边的新手,问问题的这边,所以如果您需要任何其他信息,请告诉我。
我有一个包含 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', '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)
但不幸的是,我注意到查询只有 returns 信息,而对于 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', 'birthday': 'Onbekend', 'death': 'Onbekend', 'nationality': 'Onbekend'}
14
{'gender': 'Onbekend', 'birthday': 'Onbekend', 'death': 'Onbekend', 'nationality': 'Onbekend'}
15
{'gender': 'Onbekend', 'birthday': 'Onbekend', 'death': 'Onbekend', 'nationality': 'Onbekend'}
16
{'gender': 'Onbekend', 'birthday': 'Onbekend', 'death': '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。
我是这边的新手,问问题的这边,所以如果您需要任何其他信息,请告诉我。
我有一个包含 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', '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)
但不幸的是,我注意到查询只有 returns 信息,而对于 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', 'birthday': 'Onbekend', 'death': 'Onbekend', 'nationality': 'Onbekend'}
14
{'gender': 'Onbekend', 'birthday': 'Onbekend', 'death': 'Onbekend', 'nationality': 'Onbekend'}
15
{'gender': 'Onbekend', 'birthday': 'Onbekend', 'death': 'Onbekend', 'nationality': 'Onbekend'}
16
{'gender': 'Onbekend', 'birthday': 'Onbekend', 'death': '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。