通过Python程序完成对Protege中知识图谱中数据的读取和写入

本文展示了如何利用Python的RDFlib库读取和更新知识图谱中的坐标信息。通过创建命名空间,加载图谱,执行SPARQL查询来获取特定对象的位置,然后更新这些坐标,并保存更新后的图谱。代码示例包括了将功能封装进函数和类的不同版本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建的知识图谱可以参考上一篇博客:使用Protege创建机器人的知识图谱_阿呀三的博客-CSDN博客

接下来我们通过python完成对x,y,z坐标的读取和写入

完整代码在最下方

第一步:安装读取rdf文件的库:

pip install rdflib
# conda环境使用
conda install rdflib

第二步骤:导入相关的库

from rdflib import Graph, Namespace, RDF, Literal

第三步:加载知识图谱并且导入命名空间

g = Graph()
g.parse("C:\\Users\\46494\\Desktop\\yolov5-6.0\\图谱F.rdf")  # 填入知识图谱的路径
# 创建命名空间
ns = Namespace("http://www.semanticweb.org/46494/ontologies/2023/3/untitled-ontology-14#") #命名空间就是软件上方的地址,可以看见的

 如图所示,记得末尾有一个”#“不要漏掉了

第四步:读取知识图谱所需要的内容

        query = f"""
        PREFIX : <{self.ns}>
        SELECT ?Red ?Red_position ?x_position ?y_position ?z_position
        WHERE {{
            ?Red rdf:type :Block .
            ?Red_position rdf:type :Position .
            ?Red :hasPosition :Red_position .
            ?Red_position :x_position ?x_position .
            ?Red_position :y_position ?y_position .
            ?Red_position :z_position ?z_position .
            FILTER (str(?Red_position)= "{ns}Red_position" )

        }}
        """

"""
Block有实例Red
Position有实例Red_position
Red实例和Red_position有属性hasPosition
Red_position有数据属性x_position
Red_position有数据属性y_position
Red_position有数据属性z_position
指定搜索Red_position的x、y、z_position,因为Purple和Green共用一个x、y、z_position
"""

第五步:输出查询结果

        result = g.query(query) # result存储查询到的值

        # 输出查询结果
        for row in result: # 在查询到的值里进行搜索需要输出的值
            print("更新前坐标:", f"X: {row[2]}, Y: {row[3]}, Z: {row[4]}")

第六步:更新坐标信息

    # 更新坐标信息
    new_x = 10
    new_y = 20
    new_z = 30

    for row in result:
        Position2 = row[1]
        g.set((Position2, ns.x_position, Literal(new_x)))
        g.set((Position2, ns.y_position, Literal(new_y)))
        g.set((Position2, ns.z_position, Literal(new_z)))

第七步:保存更新后的图谱,并且输出更新后的坐标信息

    # 保存更新后的知识图谱
    g.serialize(destination="图谱F.rdf", format="xml")

    # 输出更新后的坐标信息
    result = g.query(query)
    for row in result:
        print("更新后坐标:", f"X: {row[2]}, Y: {row[3]}, Z: {row[4]}")

根据自己的需要进行改进,将代码封装进函数方便自己调用,完整代码如下(版本1)

from rdflib import Graph, Namespace, RDF, Literal


# 读取知识图谱(本体)文件
g = Graph()
g.parse("C:/Users/46494/Desktop/图谱F.rdf")  # 将 'your_ontology_file.owl' 替换为您的本体文件名

# 创建命名空间
ns = Namespace("http://www.semanticweb.org/46494/ontologies/2023/3/untitled-ontology-14#")


object = 'Green' # 创建变量,需要什么就读取什么



def findObject(object):

    position = f"{object}_position"
    query = f"""
    PREFIX : <{ns}>
    SELECT ?{object} ?{position} ?x_position ?y_position ?z_position
    WHERE {{
        ?{object} rdf:type :Block .
        ?{position} rdf:type :Position .
        ?{object} :hasPosition :{position} .
        ?{position} :x_position ?x_position .
        ?{position} :y_position ?y_position .
        ?{position} :z_position ?z_position .
        FILTER (str(?{position})= "{ns}{position}" )

    }}
    """

    result = g.query(query)

    # 输出查询结果
    for row in result:
        print("更新前坐标:", f"X: {row[2]}, Y: {row[3]}, Z: {row[4]}")

    # 更新坐标信息
    new_x = 10
    new_y = 20
    new_z = 30

    for row in result:
        Position2 = row[1] # row[1]是一个地址
        g.set((Position2, ns.x_position, Literal(new_x))) # 这里先调用地址定位,然后更新坐标信息
        g.set((Position2, ns.y_position, Literal(new_y)))
        g.set((Position2, ns.z_position, Literal(new_z)))

    # 保存更新后的知识图谱
    g.serialize(destination="图谱F.rdf", format="xml")

    # 输出更新后的坐标信息
    result = g.query(query)
    for row in result:
        print("更新后坐标:", f"X: {row[2]}, Y: {row[3]}, Z: {row[4]}")

findObject(object)

版本2:封装进类,将读取和更新写进两个函数,并且当我们没有识别坐标时,坐标的读取值为None

from rdflib import Graph, Namespace, RDF, Literal


# 创建类,方便在其他程序中调用
class ontology:
    # 初始化函数
    def __init__(self):
        self.g = Graph()
        self.g.parse("C:\\Users\\46494\\Desktop\\yolov5-6.0\\图谱F.rdf")  # 将 'your_ontology_file.owl' 替换为您的本体文件名

        # 创建命名空间
        self.ns = Namespace("http://www.semanticweb.org/46494/ontologies/2023/3/untitled-ontology-14#")

        # 在启动程序前,设置所有对象的坐标为 None,检测到后自动更新
        for obj in self.g.subjects(RDF.type, self.ns.Block):
            position = self.g.value(obj, self.ns.hasPosition)
            self.g.set((position, self.ns.x_position, Literal(None)))
            self.g.set((position, self.ns.y_position, Literal(None)))
            self.g.set((position, self.ns.z_position, Literal(None)))
    # 读取坐标函数
    def findObject(self,object):

        position = f"{object}_position"
        query = f"""
        PREFIX : <{self.ns}>
        SELECT ?{object} ?{position} ?x_position ?y_position ?z_position
        WHERE {{
            ?{object} rdf:type :Block .
            ?{position} rdf:type :Position .
            ?{object} :hasPosition :{position} .
            ?{position} :x_position ?x_position .
            ?{position} :y_position ?y_position .
            ?{position} :z_position ?z_position .
            FILTER (str(?{position})= "{self.ns}{position}" )

        }}
        """

        result = self.g.query(query)

        # 输出查询结果
        for row in result:
            print("更新前坐标:", f"X: {row[2]}, Y: {row[3]}, Z: {row[4]}")


    # 更新坐标函数
    def updateObject(self,object,x,y):
        position = f"{object}_position"
        query = f"""
        PREFIX : <{self.ns}>
        SELECT ?{position} ?x_position ?y_position ?z_position
        WHERE {{
            ?{object} rdf:type :Block .
            ?{position} rdf:type :Position .
            ?{object} :hasPosition :{position} .
            ?{position} :x_position ?x_position .
            ?{position} :y_position ?y_position .
            ?{position} :z_position ?z_position 
            FILTER (str(?{position})= "{self.ns}{position}" )
        }}
        """
        result = self.g.query(query)
        new_z = 30

        for row in result:
            Position2 = row[0]
            self.g.set((Position2, self.ns.x_position, Literal(x)))
            self.g.set((Position2, self.ns.y_position, Literal(y)))
            self.g.set((Position2, self.ns.z_position, Literal(new_z)))

        # 保存更新后的知识图谱
        self.g.serialize(destination="图谱F.rdf", format="xml")

        # 输出更新后的坐标信息
        result = self.g.query(query)
        for row in result:
            print(f"{object}:", f"X: {row[1]}, Y: {row[2]}, Z: {row[3]}")
# 读取知识图谱(本体)文件


if __name__ == "__main__":
    object = 'Green'
    ot = ontology()
    ot.findObject(object)
    ot.updateObject(object,x=1,y=10) # 项目需要的z是不变的,这里我们不进行z的更新

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值