有没有Python库支持将结构数组写入Parquet文件?

20
我想将一些列字符串数组或结构体数组(通常是键值对)的数据写入Parquet文件,以供在AWS Athena中使用。
在找到两个支持写入Parquet文件的Python库(Arrow和fastparquet)之后,我花了一段时间尝试实现结构体数组。
在写入Parquet文件的问题上,最佳答案列出了这两个库(并提到缺乏对嵌套数据的支持)。
那么从Python有没有一种方法可以将嵌套数据写入Parquet文件?

我尝试使用Arrow来存储键/值,具体操作如下:

import pyarrow as pa
import pyarrow.parquet as pq

countries = []
populations = []

countries.append('Sweden')
populations.append([{'city': 'Stockholm', 'population': 1515017}, {'city': 'Gothenburg', 'population': 590580}])
countries.append('Norway')
populations.append([{'city': 'Oslo', 'population': 958378}, {'city': 'Bergen', 'population': 254235}])


ty = pa.struct([pa.field('city', pa.string()),
                pa.field('population', pa.int32())
])

fields = [
    pa.field('country', pa.string()),
    pa.field('populations', pa.list_(ty)),
]
sch1 = pa.schema(fields)

data = [
    pa.array(countries),
    pa.array(populations, type=pa.list_(ty))
]
batch = pa.RecordBatch.from_arrays(data, ['country', 'populations'])
table = pa.Table.from_batches([batch], sch1)
writer = pq.ParquetWriter('cities.parquet', sch1)
writer.write_table(table)
writer.close()

当我运行代码时,出现了以下消息:
Traceback (most recent call last):
  File "stackoverflow.py", line 30, in <module>
    writer.write_table(table)
  File "/Users/moonhouse/anaconda2/envs/parquet/lib/python3.6/site-packages/pyarrow/parquet.py", line 327, in write_table
    self.writer.write_table(table, row_group_size=row_group_size)
  File "_parquet.pyx", line 955, in pyarrow._parquet.ParquetWriter.write_table
  File "error.pxi", line 77, in pyarrow.lib.check_status
pyarrow.lib.ArrowInvalid: Nested column branch had multiple children

在最近的Arrow JIRA票据中提到了相同的错误信息,答案表明正在进行支持结构体的工作,尽管我不确定它是否覆盖了编写还是仅限于读取。

当我尝试使用fastparquet存储数据时(例如在这里当我有一个字符串列表):

import pandas as pd
from fastparquet import write

data = [{  'cities': ['Stockholm', 'Copenhagen', 'Oslo', 'Helsinki']}]

df = pd.DataFrame(data)
write('test.parq', df, compression='SNAPPY')

没有错误信息,但是在使用parquet-tools查看时,我注意到数据是Base64编码的JSON。

cities = WyJTdG9ja2hvbG0iLCAiQ29wZW5oYWdlbiIsICJPc2xvIiwgIkhlbHNpbmtpIl0=

我猜这是可以预料的,因为fastparquet不支持嵌套对象数组


嘿,你最终解决了这个问题吗? - Shadi
1
不,我还没有检查支持此功能的当前状态。 - moonhouse
从PyArrow 8.0.0开始,不再需要使用pa.field(...)。您只需传递一个(name, type)元组即可。 - Addison Klinke
1个回答

4

这个修复了吗,@moonhouse? - Mike Williamson
2
@MikeWilliamson 是的,我可以确认它与最近版本的pyarrow兼容。(已测试10.0.0),我的示例代码现在产生了我期望的结果。 - moonhouse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接