首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用pyarrow编写拼图面板元数据?

如何使用pyarrow编写拼图面板元数据?
EN

Stack Overflow用户
提问于 2018-09-01 05:15:29
回答 2查看 2.5K关注 0票数 17

我使用pyarrow来创建和分析具有生物信息的镶嵌板表格,我需要存储一些元数据,例如数据来自哪个样本,它是如何获得和处理的。

Parquet似乎支持file-wide metadata,但我找不到如何通过pyarrow编写它。我能找到的最接近的是how to write row-group metadata,但这似乎有点过分了,因为我的元数据对于文件中的所有行组都是相同的。

有没有办法用pyarrow编写文件范围内的Parquet元数据?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-29 09:10:15

此示例说明如何使用PyArrow创建包含文件元数据和列元数据的Parquet文件。

假设您有以下CSV数据:

代码语言:javascript
复制
movie,release_year
three idiots,2009
her,2013

将CSV读入PyArrow表,并使用列/文件元数据定义自定义架构:

代码语言:javascript
复制
import pyarrow.csv as pv
import pyarrow.parquet as pq
import pyarrow as pa

table = pv.read_csv('movies.csv')

my_schema = pa.schema([
    pa.field("movie", "string", False, metadata={"spanish": "pelicula"}),
    pa.field("release_year", "int64", True, metadata={"portuguese": "ano"})],
    metadata={"great_music": "reggaeton"})

使用my_schema创建一个新表,并将其写出为Parquet文件:

代码语言:javascript
复制
t2 = table.cast(my_schema)

pq.write_table(t2, 'movies.parquet')

读取Parquet文件并获取文件元数据:

代码语言:javascript
复制
s = pq.read_table('movies.parquet').schema

s.metadata # => {b'great_music': b'reggaeton'}
s.metadata[b'great_music'] # => b'reggaeton'

获取与release_year列关联的元数据:

代码语言:javascript
复制
parquet_file.schema.field('release_year').metadata[b'portuguese'] # => b'ano'
票数 4
EN

Stack Overflow用户

发布于 2019-11-21 23:32:08

Pyarrow将文件范围内的元数据映射到一个名为field in the table's schema的元数据。遗憾的是,(目前)还没有关于这方面的文档。

Parquit元数据格式和Pyarrow元数据格式都将元数据表示为键/值对的集合,其中键和值都必须是字符串。这很不幸,因为如果它只是一个UTF-8编码的JSON对象,它会更灵活。此外,由于这些对象在C++实现中是std::string对象,因此它们在Python中是"b字符串“(字节)对象。

Pyarrow目前在元数据字段中存储了它自己的一些信息。它有一个内置的key b'ARROW:schema'和另一个内置的key b'pandas'。在pandas示例中,该值是一个用UTF-8编码的JSON对象。这允许命名空间。"pandas“模式可以拥有所需的任意多个字段,并且它们都在"pandas”下命名。Pyarrow使用" pandas“模式来存储有关表的索引类型以及列使用的编码类型的信息(当给定数据类型有多个可能的pandas编码时)。我不确定b'ARROW:schema'代表什么。它似乎是以某种我不认识的方式编码的,我并没有真正地使用它。我假设它的目的是记录类似于"pandas“模式的事情。

为了回答你的问题,我们需要知道的最后一件事是所有的pyarrow对象都是不可变的。因此,无法简单地将字段添加到模式中。Pyarrow确实有模式实用程序方法with_metadata,它返回模式对象的克隆,但带有您自己的元数据,但这将替换现有的元数据,并且不会追加到它。在表对象replace_schema_metadata上也有实验方法,但它也会替换,并且不会更新。因此,如果你想保留现有的元数据,你必须做更多的工作。把这些放在一起我们就得到了..。

代码语言:javascript
复制
custom_metadata = {'Sample Number': '12', 'Date Obtained': 'Tuesday'}
existing_metadata = table.schema.metadata
merged_metadata = { **custom_metadata, **existing_metadata }
fixed_table = table.replace_schema_metadata(merged_metadata)

将此表另存为地块文件后,它将包括Sample NumberDate Obtained的键/值元数据字段(在文件级)。

另外,请注意replace_schema_metadatawith_metadata方法可以接受常规的python字符串(如我的示例所示)。但是,它会将这些字符串转换为"b字符串“,因此如果要访问模式中的字段,则必须使用"b字符串”。例如,如果您刚刚读入一个表,并希望获得样本编号,则必须使用table.schema.metadata[b'Sample Number'],而table.schema.metadats['Sample Number']将为您提供一个KeyError

当您开始使用它时,您可能会意识到必须不断地将Sample Number来回映射到一个整数是一件很痛苦的事情。此外,如果您的元数据在您的应用程序中表示为一个大型嵌套对象,那么将此对象映射到字符串/字符串对的集合可能会很麻烦。此外,经常记住"b字符串“键也是一件痛苦的事情。解决方案是做与pandas模式相同的事情。首先,将元数据转换为JSON对象。然后将JSON对象转换为"b字符串“。

代码语言:javascript
复制
custom_metadata_json = {'Sample Number': 12, 'Date Obtained': 'Tuesday'}
custom_metadata_bytes = json.dumps(custom_metadata_json).encode('utf8')
existing_metadata = table.schema.metadata
merged_metadata = { **{'Record Metadata': custom_metadata_bytes}, **existing_metadata }

现在,您可以使用任何标准JSON类型,以任何您想要的方式嵌套任意数量的元数据字段,所有这些字段都将被命名为单个键/值对(在本例中称为“记录元数据”)。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52122674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档