如何获取rdflib中空白节点的所有项目
How to get all items of a blank node in rdflib
我是 RDflib 的新手,我想实现这样的功能:
也就是说,Person hasProperty Weight(kg) , Height(m),
BMI (Body Mass Index)=Weight/Height^2,所以如果 Bob 的体重=70,身高=1.75,如何从这个模型中推导出 Bob 的 BMI?
我使用下面的RDF文件来存储以上信息:
@prefix : <http://ex.org/BMI#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
:Person rdf:type owl:Class;
:hasProperty :Height, :Weight, :BMI.
:OriginalProperty rdf:type owl:Class .
:DerivedProperty rdf:type owl:Class .
:Weight rdf:type owl:Class ;
rdfs:subClassOf :OriginalProperty .
:Height rdf:type owl:Class ;
rdfs:subClassOf :OriginalProperty .
:BMI rdf:type owl:Class ;
rdfs:subClassOf :DerivedProperty ;
:equalTo [:divide (:Weight [:power :Height])] .
:MathOperator rdf:type owl:Class .
:equalTo rdf:type owl:Class ;
rdfs:subClassOf :MathOperator .
:divide rdf:type owl:Class ;
rdfs:subClassOf :MathOperator .
:power rdf:type owl:Class ;
rdfs:subClassOf :MathOperator .
:Bob rdf:type owl:NamedIndividual , :Person ;
:hasProperty :BMIOfBob ,
:HeightOfBob ,
:WeightOfBob .
:HeightOfBob rdf:type owl:NamedIndividual , :Height ;
:hasValue 1.75 .
:WeightOfBob rdf:type owl:NamedIndividual , :Weight ;
:hasValue 70 .
:BMIOfBob rdf:type owl:NamedIndividual ,:BMI.
我的python代码如下:
from rdflib import Graph
from rdflib.namespace import Namespace
g = Graph()
x = Graph()
g.parse("BMI.ttl")
n = Namespace("http://ex.org/BMI#")
x = g.triples((None,n.equalTo,None))
for s, p, o in x:
print(s,p,o)
只返回空白节点本身,不包括BNode的其他数据。
http://ex.org/BMI#BMI http://ex.org/BMI#equalTo n2dd6baee104f49189928ce08eb003834b1
如何获取BNode的额外信息?或者有没有更好的方法用RDF来实现这个模型的功能?
感谢您的帮助和建议。
Joylix
- 始终将您的 RDF 数据通过转换器进行验证和整理。尝试 http://rdftools.surroundaustralia.com/convert。使用它你会得到:
@prefix : <http://ex.org/BMI#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
:Bob a :Person,
owl:NamedIndividual ;
:hasProperty :BMIOfBob,
:HeightOfBob,
:WeightOfBob .
:divide a owl:Class ;
rdfs:subClassOf :MathOperator .
:equalTo a owl:Class ;
rdfs:subClassOf :MathOperator .
:power a owl:Class ;
rdfs:subClassOf :MathOperator .
:BMIOfBob a :BMI,
owl:NamedIndividual .
:DerivedProperty a owl:Class .
:HeightOfBob a :Height,
owl:NamedIndividual ;
:hasValue 1.75 .
:Person a owl:Class ;
:hasProperty :BMI,
:Height,
:Weight .
:WeightOfBob a :Weight,
owl:NamedIndividual ;
:hasValue 70 .
:BMI a owl:Class ;
:equalTo [ :divide ( :Weight [ :power :Height ] ) ] ;
rdfs:subClassOf :DerivedProperty .
:OriginalProperty a owl:Class .
:Height a owl:Class ;
rdfs:subClassOf :OriginalProperty .
:MathOperator a owl:Class .
:Weight a owl:Class ;
rdfs:subClassOf :OriginalProperty .
- 以标准方式重塑您的数值 - 使用已建立的本体。您做事的方式如下:
:WeightOfBob
a :Weight, owl:NamedIndividual ;
:hasValue 70 .
非常好 - 您已经指出了数量类型(测量的事物类型)- 重量 - 和价值 - 70 但您还应该包括单位。尝试 QUDT 建模,看起来像这样:
@prefix qk: <http://qudt.org/vocab/quantitykind/> .
@prefix qudt: <http://qudt.org/schema/qudt/> .
@prefix unit: <http://qudt.org/vocab/unit/> .
:WeightOfBob
a qudt:Quantity ;
qudt:hasQuantityKind qk:Weight ;
qudt:numericValue 70 ;
qudt:unit unit:KiloGM ; # kilogram
有很多定义的度量单位,参见http://www.qudt.org/doc/DOC_VOCAB-UNITS.html
鲍勃现在的身高:
:WeightOfBob
a qudt:Quantity ;
qudt:hasQuantityKind qk:Height ;
qudt:numericValue 1.75 ;
qudt:unit unit:M ; # metre
所以现在,使用常见的 ontology [schema.org](https://schema.org]: for 'Person':
@prefix : <http://ex.org/BMI#> .
@prefix sdo: <https://schema.org/> .
:Bob
a sdo:Person ;
:hasProperty [
a qudt:Quantity ;
qudt:hasQuantityKind qk:Weight ;
qudt:numericValue 70 ;
qudt:unit unit:KiloGM ; # kilogram
] ,
[
a qudt:Quantity ;
qudt:hasQuantityKind qk:Height ;
qudt:numericValue 1.75 ;
qudt:unit unit:M ; # metre
] ;
.
现在,根据更常见的数据模式,让我们回答您的问题。
How can I get additional information of the BNode?
您需要做的是循环遍历图形以获取所需的空白节点,然后从那里遍历图形,将该空白节点作为另一个循环中的主题。
不要像 g.triples((...))
这样的代码,而是使用更简单的 g.subjects(...)
、g.subject_objects(...)
等
还有一个 g.value(..)
函数,您可以通过指定您知道的其他两个三元组值来获取任何主语、谓语或宾语的单个值。
因此,要使用上面建模的新数据获取体重和身高值:
# get the Blank Nodes for Bob for weight & height
height_bn = g.value(predicate=qudt.hasQuantityKind, object=qk.Height)
weight_bn = g.value(predicate=qudt.hasQuantityKind, object=qk.Weight)
# get the numeric values from those Blank Nodes
height_value = g.value(subject=height_bn, predicate=qudt.numericValue)
weight_value = g.value(subject=weight_bn, predicate=qudt.numericValue)
# if you needed to know units, you could do that here...
然后,使用正常 Python,计算 BMI:
import math
bmi_value = float(weight_value) / math.pow(float(height_value), 2)
当然,您的 BMI 算法在这里是用 Python 表示的,而不是 RDF,但您也可以用 SPARQL 表示,或者您可以从 RDF 结构生成算法,这可能是您的最终目标,但这简单的方法至少回答了你的一些问题。
您也可以将 bmi_value
作为另一个 Quantity
写回到您的 RDF 数据中,并使用适当的 quantityKind
、unit
等值
我是 RDflib 的新手,我想实现这样的功能: 也就是说,Person hasProperty Weight(kg) , Height(m), BMI (Body Mass Index)=Weight/Height^2,所以如果 Bob 的体重=70,身高=1.75,如何从这个模型中推导出 Bob 的 BMI? 我使用下面的RDF文件来存储以上信息:
@prefix : <http://ex.org/BMI#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
:Person rdf:type owl:Class;
:hasProperty :Height, :Weight, :BMI.
:OriginalProperty rdf:type owl:Class .
:DerivedProperty rdf:type owl:Class .
:Weight rdf:type owl:Class ;
rdfs:subClassOf :OriginalProperty .
:Height rdf:type owl:Class ;
rdfs:subClassOf :OriginalProperty .
:BMI rdf:type owl:Class ;
rdfs:subClassOf :DerivedProperty ;
:equalTo [:divide (:Weight [:power :Height])] .
:MathOperator rdf:type owl:Class .
:equalTo rdf:type owl:Class ;
rdfs:subClassOf :MathOperator .
:divide rdf:type owl:Class ;
rdfs:subClassOf :MathOperator .
:power rdf:type owl:Class ;
rdfs:subClassOf :MathOperator .
:Bob rdf:type owl:NamedIndividual , :Person ;
:hasProperty :BMIOfBob ,
:HeightOfBob ,
:WeightOfBob .
:HeightOfBob rdf:type owl:NamedIndividual , :Height ;
:hasValue 1.75 .
:WeightOfBob rdf:type owl:NamedIndividual , :Weight ;
:hasValue 70 .
:BMIOfBob rdf:type owl:NamedIndividual ,:BMI.
我的python代码如下:
from rdflib import Graph
from rdflib.namespace import Namespace
g = Graph()
x = Graph()
g.parse("BMI.ttl")
n = Namespace("http://ex.org/BMI#")
x = g.triples((None,n.equalTo,None))
for s, p, o in x:
print(s,p,o)
只返回空白节点本身,不包括BNode的其他数据。
http://ex.org/BMI#BMI http://ex.org/BMI#equalTo n2dd6baee104f49189928ce08eb003834b1
如何获取BNode的额外信息?或者有没有更好的方法用RDF来实现这个模型的功能?
感谢您的帮助和建议。
Joylix
- 始终将您的 RDF 数据通过转换器进行验证和整理。尝试 http://rdftools.surroundaustralia.com/convert。使用它你会得到:
@prefix : <http://ex.org/BMI#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
:Bob a :Person,
owl:NamedIndividual ;
:hasProperty :BMIOfBob,
:HeightOfBob,
:WeightOfBob .
:divide a owl:Class ;
rdfs:subClassOf :MathOperator .
:equalTo a owl:Class ;
rdfs:subClassOf :MathOperator .
:power a owl:Class ;
rdfs:subClassOf :MathOperator .
:BMIOfBob a :BMI,
owl:NamedIndividual .
:DerivedProperty a owl:Class .
:HeightOfBob a :Height,
owl:NamedIndividual ;
:hasValue 1.75 .
:Person a owl:Class ;
:hasProperty :BMI,
:Height,
:Weight .
:WeightOfBob a :Weight,
owl:NamedIndividual ;
:hasValue 70 .
:BMI a owl:Class ;
:equalTo [ :divide ( :Weight [ :power :Height ] ) ] ;
rdfs:subClassOf :DerivedProperty .
:OriginalProperty a owl:Class .
:Height a owl:Class ;
rdfs:subClassOf :OriginalProperty .
:MathOperator a owl:Class .
:Weight a owl:Class ;
rdfs:subClassOf :OriginalProperty .
- 以标准方式重塑您的数值 - 使用已建立的本体。您做事的方式如下:
:WeightOfBob
a :Weight, owl:NamedIndividual ;
:hasValue 70 .
非常好 - 您已经指出了数量类型(测量的事物类型)- 重量 - 和价值 - 70 但您还应该包括单位。尝试 QUDT 建模,看起来像这样:
@prefix qk: <http://qudt.org/vocab/quantitykind/> .
@prefix qudt: <http://qudt.org/schema/qudt/> .
@prefix unit: <http://qudt.org/vocab/unit/> .
:WeightOfBob
a qudt:Quantity ;
qudt:hasQuantityKind qk:Weight ;
qudt:numericValue 70 ;
qudt:unit unit:KiloGM ; # kilogram
有很多定义的度量单位,参见http://www.qudt.org/doc/DOC_VOCAB-UNITS.html
鲍勃现在的身高:
:WeightOfBob
a qudt:Quantity ;
qudt:hasQuantityKind qk:Height ;
qudt:numericValue 1.75 ;
qudt:unit unit:M ; # metre
所以现在,使用常见的 ontology [schema.org](https://schema.org]: for 'Person':
@prefix : <http://ex.org/BMI#> .
@prefix sdo: <https://schema.org/> .
:Bob
a sdo:Person ;
:hasProperty [
a qudt:Quantity ;
qudt:hasQuantityKind qk:Weight ;
qudt:numericValue 70 ;
qudt:unit unit:KiloGM ; # kilogram
] ,
[
a qudt:Quantity ;
qudt:hasQuantityKind qk:Height ;
qudt:numericValue 1.75 ;
qudt:unit unit:M ; # metre
] ;
.
现在,根据更常见的数据模式,让我们回答您的问题。
How can I get additional information of the BNode?
您需要做的是循环遍历图形以获取所需的空白节点,然后从那里遍历图形,将该空白节点作为另一个循环中的主题。
不要像 g.triples((...))
这样的代码,而是使用更简单的 g.subjects(...)
、g.subject_objects(...)
等
还有一个 g.value(..)
函数,您可以通过指定您知道的其他两个三元组值来获取任何主语、谓语或宾语的单个值。
因此,要使用上面建模的新数据获取体重和身高值:
# get the Blank Nodes for Bob for weight & height
height_bn = g.value(predicate=qudt.hasQuantityKind, object=qk.Height)
weight_bn = g.value(predicate=qudt.hasQuantityKind, object=qk.Weight)
# get the numeric values from those Blank Nodes
height_value = g.value(subject=height_bn, predicate=qudt.numericValue)
weight_value = g.value(subject=weight_bn, predicate=qudt.numericValue)
# if you needed to know units, you could do that here...
然后,使用正常 Python,计算 BMI:
import math
bmi_value = float(weight_value) / math.pow(float(height_value), 2)
当然,您的 BMI 算法在这里是用 Python 表示的,而不是 RDF,但您也可以用 SPARQL 表示,或者您可以从 RDF 结构生成算法,这可能是您的最终目标,但这简单的方法至少回答了你的一些问题。
您也可以将 bmi_value
作为另一个 Quantity
写回到您的 RDF 数据中,并使用适当的 quantityKind
、unit
等值