Python Parquet 中的嵌套数据
Nested data in Parquet with Python
我有一个文件,每行有一个 JSON。这是一个示例:
{
"product": {
"id": "abcdef",
"price": 19.99,
"specs": {
"voltage": "110v",
"color": "white"
}
},
"user": "Daniel Severo"
}
我想创建一个包含以下列的镶木地板文件:
product.id, product.price, product.specs.voltage, product.specs.color, user
我知道 parquet 有一个使用 Dremel 算法的嵌套编码,但我无法在 python 中使用它(不知道为什么)。
我是一个沉重的 pandas 和愚蠢的用户,所以我试图构建的管道是 json data -> dask -> parquet -> pandas
,尽管 如果有人有一个简单的创建和使用 Python 在 parquet 中读取这些嵌套编码我认为这就足够了 :D
编辑
所以,在深入研究 PR 之后,我发现了这个:https://github.com/dask/fastparquet/pull/177
这基本上就是我想做的。虽然,我仍然无法让它一直工作。我如何准确地告诉 dask/fastparquet 我的 product
列是嵌套的?
- dask版本:0.15.1
- fastparquet版本:0.1.1
在任意 Parquet 嵌套数据的读取和写入路径上实现转换非常复杂——实现分解和重组算法以及对某些 Python 数据结构的相关转换。我们在 Arrow / parquet-cpp 的路线图上有这个(见 https://github.com/apache/parquet-cpp/tree/master/src/parquet/arrow),但它还没有完成(现在只支持简单结构和 lists/arrays)。拥有此功能很重要,因为其他使用 Parquet 的系统,如 Impala、Hive、Presto、Drill 和 Spark,在其 SQL 方言中原生支持嵌套类型,因此我们需要能够从 Python.
忠实地读写这些结构
这也可以在 fastparquet 中类似地实现,但是无论您如何分割它都将需要大量工作(和编写测试用例)。
我可能会在今年晚些时候亲自承担这项工作(在 parquet-cpp 中),如果没有人比我强的话,但我很乐意得到一些帮助。
这不是正确的答案,但它可以提供帮助。
我们可以尝试将您的字典转换为 pandas DataFrame,然后将其写入 .parquet
文件:
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)
这会引发错误:
ValueError: Can't infer object conversion type: 0 abcdef
1 19.99
2 {'voltage': '110v', 'color': 'white'}
Name: product, dtype: object
所以一个简单的解决方案是将 product
列转换为列表:
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
我相信这个功能终于在 arrow/pyarrow 2.0.0 中添加了:
我有一个文件,每行有一个 JSON。这是一个示例:
{
"product": {
"id": "abcdef",
"price": 19.99,
"specs": {
"voltage": "110v",
"color": "white"
}
},
"user": "Daniel Severo"
}
我想创建一个包含以下列的镶木地板文件:
product.id, product.price, product.specs.voltage, product.specs.color, user
我知道 parquet 有一个使用 Dremel 算法的嵌套编码,但我无法在 python 中使用它(不知道为什么)。
我是一个沉重的 pandas 和愚蠢的用户,所以我试图构建的管道是 json data -> dask -> parquet -> pandas
,尽管 如果有人有一个简单的创建和使用 Python 在 parquet 中读取这些嵌套编码我认为这就足够了 :D
编辑
所以,在深入研究 PR 之后,我发现了这个:https://github.com/dask/fastparquet/pull/177
这基本上就是我想做的。虽然,我仍然无法让它一直工作。我如何准确地告诉 dask/fastparquet 我的 product
列是嵌套的?
- dask版本:0.15.1
- fastparquet版本:0.1.1
在任意 Parquet 嵌套数据的读取和写入路径上实现转换非常复杂——实现分解和重组算法以及对某些 Python 数据结构的相关转换。我们在 Arrow / parquet-cpp 的路线图上有这个(见 https://github.com/apache/parquet-cpp/tree/master/src/parquet/arrow),但它还没有完成(现在只支持简单结构和 lists/arrays)。拥有此功能很重要,因为其他使用 Parquet 的系统,如 Impala、Hive、Presto、Drill 和 Spark,在其 SQL 方言中原生支持嵌套类型,因此我们需要能够从 Python.
忠实地读写这些结构这也可以在 fastparquet 中类似地实现,但是无论您如何分割它都将需要大量工作(和编写测试用例)。
我可能会在今年晚些时候亲自承担这项工作(在 parquet-cpp 中),如果没有人比我强的话,但我很乐意得到一些帮助。
这不是正确的答案,但它可以提供帮助。
我们可以尝试将您的字典转换为 pandas DataFrame,然后将其写入 .parquet
文件:
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)
这会引发错误:
ValueError: Can't infer object conversion type: 0 abcdef
1 19.99
2 {'voltage': '110v', 'color': 'white'}
Name: product, dtype: object
所以一个简单的解决方案是将 product
列转换为列表:
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
我相信这个功能终于在 arrow/pyarrow 2.0.0 中添加了: