13

我有一个.ttl表格文件。它有 4 个属性/列,其中包含以下形式的四元组:

  1. (id, student_name, student_address, student_phoneno).
  2. (id, faculty_name, faculty_address, faculty_phoneno).

我知道如何.n3用 RDFLib 解析三元组;

from rdflib import Graph
g = Graph()
g.parse("demo.nt", format="nt")

但我不确定如何解析这些四元组。

我的目的是解析和提取与特定 ID 有关的所有信息。学生和教师的 id 可以相同。

如何使用 RDFLib 处理这些四元组并将其用于基于 的聚合id

文件中的示例片段.ttl

#@ <id1>
<Alice> <USA> <12345>

#@ <id1>
<Jane> <France> <78900>
4

4 回答 4

14

TurtleNotation 3语法的子集,因此rdflib应该能够使用format='n3'. 检查是否rdflib保留注释(在示例中的注释 ( ) 中id指定了 s )。#...如果不是,并且输入格式与示例中所示的一样简单,那么您可以手动解析它:

import re
from collections import namedtuple
from itertools import takewhile

Entry = namedtuple('Entry', 'id name address phone')

def get_entries(path):
    with open(path) as file:
        # an entry starts with `#@` line and ends with a blank line
        for line in file:
            if line.startswith('#@'):
                buf = [line]
                buf.extend(takewhile(str.strip, file)) # read until blank line
                yield Entry(*re.findall(r'<([^>]+)>', ''.join(buf)))

print("\n".join(map(str, get_entries('example.ttl'))))

输出:

Entry(id='id1', name='Alice', address='USA', phone='12345')
Entry(id='id1', name='Jane', address='France', phone='78900')

要将条目保存到数据库:

import sqlite3

with sqlite3.connect('example.db') as conn:
    conn.execute('''CREATE TABLE IF NOT EXISTS entries
             (id text, name text, address text, phone text)''')
    conn.executemany('INSERT INTO entries VALUES (?,?,?,?)',
                     get_entries('example.ttl'))

如果您需要在 Python 中进行一些后处理,则按 id 分组:

import sqlite3
from itertools import groupby
from operator import itemgetter

with sqlite3.connect('example.db') as c:
    rows = c.execute('SELECT * FROM entries ORDER BY id LIMIT ?', (10,))
    for id, group in groupby(rows, key=itemgetter(0)):
        print("%s:\n\t%s" % (id, "\n\t".join(map(str, group))))

输出:

id1:
    ('id1', 'Alice', 'USA', '12345')
    ('id1', 'Jane', 'France', '78900')
于 2013-03-02T15:09:43.353 回答
2

看起来至少从 rdflib 5.0.0 开始支持turtle。我做了

from rdflib import Graph
graph = Graph()
graph.parse('myfile.ttl', format='ttl')

这解析得很好。

于 2021-07-10T18:22:46.310 回答
0

您可以按照 Snakes 和 Coffee 的建议进行操作,仅将该函数(或其代码)包装在带有 yield 语句的循环中。这将创建一个生成器,可以迭代地调用它来动态创建下一行的字典。假设您要将这些写入 csv,例如,使用 Snakes 的 parse_to_dict:

import re
import csv

writer = csv.DictWriter(open(outfile, "wb"), fieldnames=["id", "name", "address", "phone"])
# or whatever

您可以将生成器创建为函数或内联理解:

def dict_generator(lines): 
    for line in lines: 
        yield parse_to_dict(line)

- 或者 -

dict_generator = (parse_to_dict(line) for line in lines)

这些几乎是等价的。在这一点上,您可以通过调用获得一个 dict-parsed 行dict_generator.next(),并且您会神奇地一次获得一个 - 不涉及额外的 RAM 抖动。

如果你有 16 gigs 的原始数据,你也可以考虑制作一个生成器来拉线。它们真的很有用。

来自 SO 和一些文档的生成器的更多信息: 你可以使用 Python 生成器函数做什么? http://wiki.python.org/moin/Generators

于 2013-03-02T07:56:43.890 回答
-2

似乎目前没有这样的库来解析Turtle - Terse RDF Triple Language

正如您已经知道语法一样,最好的办法是使用PyParsing首先创建语法,然后解析文件。

我还建议根据您的需要调整以下EBNF 实现

于 2013-03-02T07:31:00.083 回答