首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Python在Parquet中嵌套数据

用Python在Parquet中嵌套数据
EN

Stack Overflow用户
提问于 2017-07-27 04:01:41
回答 3查看 17K关注 0票数 18

我有一个文件,每行有一个JSON。以下是一个示例:

代码语言:javascript
复制
{
    "product": {
        "id": "abcdef",
        "price": 19.99,
        "specs": {
            "voltage": "110v",
            "color": "white"
        }
    },
    "user": "Daniel Severo"
}

我想要创建一个包含如下列的拼花文件:

代码语言:javascript
复制
product.id, product.price, product.specs.voltage, product.specs.color, user

我知道parquet有一个使用Dremel算法的嵌套编码,但是我还不能在python中使用它(不知道为什么)。

我是一个沉重的熊猫和达克用户,所以我试图构建的管道是json data -> dask -> parquet -> pandas,尽管如果有人有一个使用Python创建和读取这些嵌套编码的简单示例,我认为这就足够好了:D

编辑

所以,在深入研究这些PRs之后,我发现了这个:https://github.com/dask/fastparquet/pull/177

这基本上就是我想做的。不过,我还是不能让它一直运作下去。我如何确切地告诉达克/紧固件,我的product列是嵌套的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-07-28 21:05:39

实现对任意Parquet嵌套数据的读和写路径的转换是相当复杂的--实现分解和重新组装算法,并将关联的转换转换到某些Python数据结构。我们在Arrow / parquet-cpp (参见https://github.com/apache/parquet-cpp/tree/master/src/parquet/arrow)中的路线图上有这一点,但是它还没有完成(现在只支持简单的结构和列表/数组)。具有此功能非常重要,因为其他使用Parquet的系统,如Impala、Hive、Presto、their和Spark,都对SQL方言中的嵌套类型有原生支持,因此我们需要能够从Python中忠实地读取和编写这些结构。

这也可以在快速拼花中类似地实现,但是无论你如何分割它,它都是大量的工作(以及需要编写的测试用例)。

如果没有人比我更好的话,我可能会在今年晚些时候亲自接手这项工作(在cpp中),但我希望得到一些帮助。

票数 16
EN

Stack Overflow用户

发布于 2020-12-09 19:18:31

我相信这个特性最终被添加到了箭头/py箭头2.0.0中:

https://issues.apache.org/jira/browse/ARROW-1644

https://arrow.apache.org/docs/python/json.html

票数 1
EN

Stack Overflow用户

发布于 2020-07-23 15:12:41

这不完全是正确的答案,但它可以帮助。

我们可以尝试将您的字典转换为熊猫DataFrame,然后将其写入.parquet文件:

代码语言:javascript
复制
import pandas as pd
from fastparquet import write, ParquetFile

d = {
    "product": {
        "id": "abcdef",
        "price": 19.99,
        "specs": {
            "voltage": "110v",
            "color": "white"
        }
    },
    "user": "Daniel Severo"
}

df_test = pd.DataFrame(d)
write('file_test.parquet', df_test)

这将引发和错误:

代码语言:javascript
复制
ValueError: Can't infer object conversion type: 0                                   abcdef
1                                    19.99
2    {'voltage': '110v', 'color': 'white'}
Name: product, dtype: object

因此,一个简单的解决方案是将product列转换为列表:

代码语言:javascript
复制
df_test['product'] = df_test['product'].apply(lambda x: [x])

# this should now works
write('file_test.parquet', df_test)

# and now compare the file with the initial DataFrame
ParquetFile('file_test.parquet').to_pandas().explode('product')
    index            product                                 user
0   id               abcdef                             Daniel Severo
1   price             19.99                             Daniel Severo
2   specs   {'voltage': '110v', 'color': 'white'}       Daniel Severo
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45341182

复制
相关文章

相似问题

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