(首先,我很抱歉,因为这是一个公然的交叉帖子。我认为 opendata.SE 会是这个地方,但那里几乎没有任何意见,而且它似乎不是一个非常活跃的网站,所以我想我应该在这里尝试一下,因为它与编程相关。)
我正在尝试获取世界主要城市的列表:它们的名称、人口和位置。我在Wikidata上发现了一个看起来不错的查询,稍微调整了其中一个内置查询示例:
SELECT DISTINCT ?cityLabel ?population ?gps WHERE {
?city (wdt:P31/wdt:P279*) wd:Q515.
?city wdt:P1082 ?population.
?city wdt:P625 ?gps.
FILTER (?population >= 500000) .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY DESC(?population)
乍一看,结果似乎不错,但它缺少大量重要城市。例如,旧金山(人口 80 万+)和西雅图(人口 65 万+)不在列表中,当时我专门询问了所有人口超过 50 万的城市。
我的查询有问题吗?如果不是,那么 Wikidata 使用的数据一定有问题。无论哪种方式,如何使用可以从 Python 脚本查询的 API 获得有效的数据集?(我的脚本都为此工作;我只是没有取回有效数据。)
from SPARQLWrapper import SPARQLWrapper, JSON
from geopy.distance import great_circle
def parseCoords(gps):
base = gps[6:-1]
coords=base.split()
return (float(coords[1]), float(coords[0]))
sparql = SPARQLWrapper("https://query.wikidata.org/sparql")
sparql.setReturnFormat(JSON)
sparql.setQuery("""SELECT DISTINCT ?cityLabel ?population ?gps WHERE {
?city (wdt:P31/wdt:P279*) wd:Q515.
?city wdt:P1082 ?population.
?city wdt:P625 ?gps.
FILTER (?population >= 500000) .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY DESC(?population)""")
queryResults = sparql.query().convert()
cities = [(city["cityLabel"]["value"], int(city["population"]["value"]), parseCoords(city["gps"]["value"])) for city in queryResults["results"]["bindings"]]
print (cities)