python - 用数组读取 Parquet 文件
问题描述
我正在使用 Dask 读取由 PySpark 生成的 Parquet 文件,其中一列是字典列表(即array<map<string,string>>'
)。df 的一个例子是:
import pandas as pd
df = pd.DataFrame.from_records([
(1, [{'job_id': 1, 'started': '2019-07-04'}, {'job_id': 2, 'started': '2019-05-04'}], 100),
(5, [{'job_id': 3, 'started': '2015-06-04'}, {'job_id': 9, 'started': '2019-02-02'}], 540)],
columns=['uid', 'job_history', 'latency']
)
使用时engine='fastparquet
,Dask 可以很好地读取所有其他列,但会None
为复杂类型的列返回 s 列。当我设置engine='pyarrow'
时,我得到以下异常:
ArrowNotImplementedError: lists with structs are not supported.
许多谷歌搜索清楚地表明,现在并不真正支持使用嵌套数组读取列,而且我不完全确定处理这个问题的最佳方法是什么。我想我的选择是:
- 一些如何告诉 dask/fastparquet 使用标准
json
库解析列。架构很简单,如果可能的话就可以完成这项工作 - 看看我是否可以重新运行生成输出的 Spark 作业并将其另存为其他内容,尽管这几乎不是一个可接受的解决方案,因为我的公司到处都使用镶木地板
- 将映射的键转换为列,并使用 dtype 将数据分解为多个列,
list
并注意这些列中的数据通过索引相互关联/映射(例如,0
这些键/列中 idx 中的元素都来自同一来源)。这会起作用,但坦率地说,让我心碎:(
我很想听听其他人是如何绕过这个限制的。我的公司经常在他们的 parquest 中使用嵌套数组,因此我不想放弃使用 Dask。
解决方案
更公平地说,pandas(目前)不太支持非简单类型。pyarrow 可能会在没有转换为 pandas 的情况下,并且作为未来的某个点,pandas 将直接使用这些箭头结构。
实际上,我认为您可以使用的最直接的方法是将列重写为 B/JSON 编码的文本,然后使用 fastparquet 加载,指定使用 B/JSON 加载。您应该在列中获得 dicts 列表,但性能会很慢。
请注意,旧项目oamap及其后继项目笨拙提供了一种使用 Python 语法迭代和聚合嵌套列表/映射/结构树的方法,但使用 Numba 编译,这样您就不需要实例化中间 Python 对象。它们不是为镶木地板设计的,但具有镶木地板的兼容性,因此可能对您有用。
推荐阅读
- java - 如何裁剪为 1:1、压缩、上传到 Firebase 存储并获取它?
- linux - 我在哪里可以找到 yum 存储库的错误?
- amp-html - 我只想自动播放一次 amp 视频
- swift - 在应用程序委托中全局更改 UITextView 键盘外观
- javascript - 在数据表中加载 JSON
- javascript - 尝试创建 javascript 函数来搜索文本文件并返回密钥对
- ios - MKMapView 在初始化时崩溃
- java - 如何删除java中两个单词之间除下划线之外的所有特殊字符?
- vb.net - 使用 vb.Net XmlTextReader 读取 XML 节点对象
- aws-lambda - 具有 lambda 集成的 Api Gateway 直接返回 lambda 输出