一个用于读取和写入CLDF数据集的Python库
项目描述
pycldf
一个用于读取和写入CLDF数据集的Python包。
安装
从PyPI安装pycldf
。
pip install pycldf
命令行使用
安装pycldf
包还会安装命令行界面cldf
,它提供了一些子命令来管理CLDF数据集。
数据集发现
cldf
子命令支持数据集发现,具体可参考标准。
因此,涉及远程数据集的典型工作流程可能如下所示。
创建一个本地目录以下载数据集(理想情况下包含版本信息)
$ mkdir wacl-1.0.0
从Zenodo验证数据集会隐式下载它,因此运行
$ cldf validate https://zenodo.org/record/7322688#rdf:ID=wacl --download-dir wacl-1.0.0/
将数据集下载到wacl-1.0.0
。
随后我们可以本地访问数据以提高性能
$ cldf stats wacl-1.0.0/#rdf:ID=wacl
<cldf:v1.0:StructureDataset at wacl-1.0.0/cldf>
value
------------------------ --------------------------------------------------------------------
dc:bibliographicCitation Her, One-Soon, Harald Hammarström and Marc Allassonnière-Tang. 2022.
dc:conformsTo http://cldf.clld.org/v1.0/terms.rdf#StructureDataset
dc:identifier https://wacl.clld.org
dc:license https://creativecommons.org/licenses/by/4.0/
dc:source sources.bib
dc:title World Atlas of Classifier Languages
dcat:accessURL https://github.com/cldf-datasets/wacl
rdf:ID wacl
rdf:type http://www.w3.org/ns/dcat#Distribution
Type Rows
-------------- -------------- ------
values.csv ValueTable 3338
parameters.csv ParameterTable 1
languages.csv LanguageTable 3338
codes.csv CodeTable 2
sources.bib Sources 2000
(请注意,在Zenodo上定位数据集需要安装cldfzenodo。)
摘要统计
$ cldf stats mydataset/Wordlist-metadata.json
<cldf:v1.0:Wordlist at mydataset>
Path Type Rows
--------------------- ---------- ------
forms.csv Form Table 1
mydataset/sources.bib Sources 1
验证
可以说,pycldf
最重要的功能之一是验证CLDF数据集。
默认情况下,数据文件以严格模式读取,即无效行会导致抛出异常。要验证数据文件,可以以验证模式读取。
例如,以下输出是在读取文件时生成的
$ cldf validate mydataset/forms.csv
WARNING forms.csv: duplicate primary key: (u'1',)
WARNING forms.csv:4:Source missing source key: Mei2005
时
ID,Language_ID,Parameter_ID,Value,Segments,Comment,Source
1,abcd1234,1277,word,,,Meier2005[3-7]
1,stan1295,1277,hand,,,Meier2005[3-7]
2,stan1295,1277,hand,,,Mei2005[3-7]
提取可读的元数据
CLDF元数据文件中的信息可以通过运行转换为markdown(一种可读的标记语言)
cldf markdown PATH/TO/metadata.json
此功能的典型用途是创建数据集的README.md
(当上传到例如GitHub时,将在浏览器中良好渲染)。
下载数据集中MediaTable中列出的媒体
通常,CLDF数据集只引用媒体项。然而,MediaTable提供了足够的信息来下载和保存项的内容。这可以通过以下操作完成
cldf downloadmedia PATH/TO/metadata.json PATH/TO/DOWNLOAD/DIR
为了最小化带宽使用,可以通过传递形式为COLUMN_NAME=SUBSTRING
的选择标准作为可选参数来过滤相关项。例如,可以通过以下操作将下载限制为音频文件,通过Media_Type=audio/
(假设Media_Type
是具有propertyUrl
http://cldf.clld.org/v1.0/terms.rdf#mediaType的列名)
将CLDF数据集转换为SQLite数据库
CSVW的一般功能和CLDF的特别之处在于它提供了足够的元数据,可以将一组CSV文件加载到关系数据库中,包括表之间的关系。这可以通过运行cldf createdb
命令完成
$ cldf createdb -h
usage: cldf createdb [-h] [--infer-primary-keys] DATASET SQLITE_DB_PATH
Load a CLDF dataset into a SQLite DB
positional arguments:
DATASET Dataset specification (i.e. path to a CLDF metadata
file or to the data file)
SQLITE_DB_PATH Path to the SQLite db file
有关结果数据库模式的规范,请参阅src/pycldf/db.py
中的文档。
Python API
有关Python API的详细文档,请参阅ReadTheDocs上的文档。
读取CLDF
以示例,我们将从WALS Online,v2020读取数据
>>> from pycldf import Dataset
>>> wals2020 = Dataset.from_metadata('https://raw.githubusercontent.com/cldf-datasets/wals/v2020/cldf/StructureDataset-metadata.json')
出于探索目的,通过HTTP访问远程数据集是可以的。但对于实际分析,您首先需要下载数据集,然后本地访问它们,将本地文件路径传递给Dataset.from_metadata
。
让我们看看我们得到了什么
>>> print(wals2020)
<cldf:v1.0:StructureDataset at https://raw.githubusercontent.com/cldf-datasets/wals/v2020/cldf/StructureDataset-metadata.json>
>>> for c in wals2020.components:
... print(c)
...
ValueTable
ParameterTable
CodeTable
LanguageTable
ExampleTable
正如预期的那样,我们得到了一个StructureDataset,除了所需的ValueTable
之外,我们还有一些额外的组件。
我们可以使用pycldf
的ORM(对象关系映射)功能来调查值,即映射CLDF数据文件中的行到方便的Python对象。(请注意orm.py中描述的限制。)
>>> for value in wals2020.objects('ValueTable'):
... break
...
>>> value
<pycldf.orm.Value id="81A-aab">
>>> value.language
<pycldf.orm.Language id="aab">
>>> value.language.cldf
Namespace(glottocode=None, id='aab', iso639P3code=None, latitude=Decimal('-3.45'), longitude=Decimal('142.95'), macroarea=None, name='Arapesh (Abu)')
>>> value.parameter
<pycldf.orm.Parameter id="81A">
>>> value.parameter.cldf
Namespace(description=None, id='81A', name='Order of Subject, Object and Verb')
>>> value.references
(<Reference Nekitel-1985[94]>,)
>>> value.references[0]
<Reference Nekitel-1985[94]>
>>> print(value.references[0].source.bibtex())
@misc{Nekitel-1985,
olac_field = {syntax; general_linguistics; typology},
school = {Australian National University},
title = {Sociolinguistic Aspects of Abu', a Papuan Language of the Sepik Area, Papua New Guinea},
wals_code = {aab},
year = {1985},
author = {Nekitel, Otto I. M. S.}
}
如果性能很重要,可以直接以Python dict
的形式读取数据行,在这种情况下,必须在“手动”中解析表之间的引用
>>> params = {r['id']: r for r in wals2020.iter_rows('ParameterTable', 'id', 'name')}
>>> for v in wals2020.iter_rows('ValueTable', 'parameterReference'):
... print(params[v['parameterReference']]['name'])
... break
...
Order of Subject, Object and Verb
请注意,我们将CLDF术语的名称传递给Dataset.iter_rows
(例如id
),指定我们想要通过CLDF术语访问的列 - 而不是通过数据集中它们映射到的列名。
编写CLDF
警告:使用pycldf
编写CLDF并不会自动生成有效的CLDF!但是,它确实生成了可以通过cldf validate
进行检查的数据(见下文),因此您在编写后应始终进行验证。
from pycldf import Wordlist, Source
dataset = Wordlist.in_dir('mydataset')
dataset.add_sources(Source('book', 'Meier2005', author='Hans Meier', year='2005', title='The Book'))
dataset.write(FormTable=[
{
'ID': '1',
'Form': 'word',
'Language_ID': 'abcd1234',
'Parameter_ID': '1277',
'Source': ['Meier2005[3-7]'],
}])
结果
$ ls -1 mydataset/
forms.csv
sources.bib
Wordlist-metadata.json
mydataset/forms.csv
ID,Language_ID,Parameter_ID,Value,Segments,Comment,Source
1,abcd1234,1277,word,,,Meier2005[3-7]
mydataset/sources.bib
@book{Meier2005,
author = {Meier, Hans},
year = {2005},
title = {The Book}
}
mydataset/Wordlist-metadata.json
高级编写
要将预定义的CLDF组件添加到数据集中,请使用add_component
方法
from pycldf import StructureDataset, term_uri
dataset = StructureDataset.in_dir('mydataset')
dataset.add_component('ParameterTable')
dataset.write(
ValueTable=[{'ID': '1', 'Language_ID': 'abc', 'Parameter_ID': '1', 'Value': 'x'}],
ParameterTable=[{'ID': '1', 'Name': 'Grammatical Feature'}])
还可以添加通用表
dataset.add_table('contributors.csv', term_uri('id'), term_uri('name'))
这些表也可以与其他表链接
dataset.add_columns('ParameterTable', 'Contributor_ID')
dataset.add_foreign_key('ParameterTable', 'Contributor_ID', 'contributors.csv', 'ID')
处理表和列
可以使用数据集的__getitem__
方法引用数据集中的表,传递
- 对应组件的完整CLDF本体URI
- CLDF本体中组件的本地名称
- 表的
url
可以使用数据集的__getitem__
方法引用数据集中的列,传递一个元组(<TABLE>, <COLUMN>)
,其中<TABLE>
指定一个表,如上所述,而<COLUMN>
是
- 用作列的
propertyUrl
的完整CLDF本体URI - 列的
name
属性
面向对象的CLDF数据访问
pycldf.orm
模块实现了通过ORM访问CLDF数据的功能。有关详细信息,请参阅https://pycldf.readthedocs.io/en/latest/orm.html。
通过SQL访问CLDF数据
pycldf.db
模块实现了将CLDF数据加载到SQLite数据库中的功能。有关详细信息,请参阅https://pycldf.readthedocs.io/en/latest/ext_sql.html。
另请参阅
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。