13

フォームにファイルがあります.ttl。次の形式の 4 倍体を含む 4 つの属性/列があります。

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

.n3RDFLib でフォーム トリプルを解析する方法を知っています。

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 に答える
0

Snakes and Coffee が示唆するように、その関数 (またはそのコード) を yield ステートメントでループにラップするだけで済みます。これにより、次の行の辞書をその場で作成するために繰り返し呼び出すことができるジェネレーターが作成されます。たとえば、Snakes の parse_to_dict を使用して、これらを csv に書き込むと仮定します。

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_generator.next()、 を呼び出すことで dict で解析された行を取得でき、魔法のように一度に 1 行ずつ取得できます。追加の RAM スラッシングは必要ありません。

16 ギガの生データがある場合は、線を引き込むジェネレーターを作成することも検討できます。彼らは本当に便利です。

SO および一部のドキュメントのジェネレーターに関する詳細情報: What can you can you use Python generator functions for? http://wiki.python.org/moin/Generators

于 2013-03-02T07:56:43.890 に答える
-2

現在、 Turtle - Terse RDF Triple Languageを解析するライブラリは存在しないようです。

既に grammar を知っているので、PyParsingを使用して最初に文法を作成し、次にファイルを解析することをお勧めします。

また、必要に応じて次のEBNF 実装を適応させることをお勧めします。

于 2013-03-02T07:31:00.083 に答える