PyArrow:使用嵌套类型在镶木地板中存储字典列表
PyArrow: Store list of dicts in parquet using nested types
我想使用 PyArrow 将以下 pandas 数据框存储在镶木地板文件中:
import pandas as pd
df = pd.DataFrame({'field': [[{}, {}]]})
field
列的类型是字典列表:
field
0 [{}, {}]
我先定义对应的PyArrow schema:
import pyarrow as pa
schema = pa.schema([pa.field('field', pa.list_(pa.struct([])))])
然后我用from_pandas()
:
table = pa.Table.from_pandas(df, schema=schema, preserve_index=False)
这将引发以下异常:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "table.pxi", line 930, in pyarrow.lib.Table.from_pandas
File "/anaconda3/lib/python3.6/site-packages/pyarrow/pandas_compat.py", line 371, in dataframe_to_arrays
convert_types)]
File "/anaconda3/lib/python3.6/site-packages/pyarrow/pandas_compat.py", line 370, in <listcomp>
for c, t in zip(columns_to_convert,
File "/anaconda3/lib/python3.6/site-packages/pyarrow/pandas_compat.py", line 366, in convert_column
return pa.array(col, from_pandas=True, type=ty)
File "array.pxi", line 177, in pyarrow.lib.array
File "error.pxi", line 77, in pyarrow.lib.check_status
File "error.pxi", line 87, in pyarrow.lib.check_status
pyarrow.lib.ArrowTypeError: Unknown list item type: struct<>
我是不是做错了什么或者 PyArrow 不支持这个?
我用的是pyarrow 0.9.0, pandas 23.4, python 3.6.
根据 this Jira issue,在版本 2.0.0 中实现了使用结构和列表嵌套级别的混合读取和写入嵌套 Parquet 数据。
以下示例通过往返演示了实现的功能:pandas 数据框 -> 拼花文件 -> pandas 数据框。使用的 PyArrow 版本是 3.0.0.
初始pandas数据框有一个字典类型列表字段和一个条目:
field
0 [{'a': 1}, {'a': 2}]
示例代码:
import pandas as pd
import pyarrow as pa
import pyarrow.parquet
df = pd.DataFrame({'field': [[{'a': 1}, {'a': 2}]]})
schema = pa.schema(
[pa.field('field', pa.list_(pa.struct([('a', pa.int64())])))])
table_write = pa.Table.from_pandas(df, schema=schema, preserve_index=False)
pyarrow.parquet.write_table(table_write, 'test.parquet')
table_read = pyarrow.parquet.read_table('test.parquet')
table_read.to_pandas()
输出数据帧与输入数据帧相同,应该是:
field
0 [{'a': 1}, {'a': 2}]
我已经能够将 pandas 在列中具有数组的数据帧保存为 parquet,并通过将对象的数据帧数据类型转换为 str 将它们从 parquet 读回数据帧。
def mapTypes(x):
return {'object': 'str', 'int64': 'int64', 'float64': 'float64', 'bool': 'bool',
'datetime64[ns, ' + timezone + ']': 'datetime64[ns, ' + timezone + ']'}.get(x,"str") # string is default if type not mapped
table_names = [x for x in df.columns]
table_types = [mapTypes(x.name) for x in df.dtypes]
parquet_table = dict(zip(table_names, table_types))
df_pq = df.astype(parquet_table)
import awswrangler as wr
wr.s3.to_parquet(df=df_pq,path=path,dataset=True,database='test',mode='overwrite',table=table.lower(),partition_cols=['realmid'],sanitize_columns=True)
下面的图片显示了使用 AWS datawrangler 库从存储在 s3 中的镶木地板文件读取到数据帧,我也用 pyarrow
这是重现此错误的片段:
#!/usr/bin/env python3
import pandas as pd # type: ignore
def main():
"""Main function"""
df = pd.DataFrame()
df["nested"] = [[dict()] for i in range(10)]
df.to_feather("test.feather")
print("Success once")
df = pd.read_feather("test.feather")
df.to_feather("test.feather")
if __name__ == "__main__":
main()
请注意,从 pandas 到 feather,没有任何中断,但是一旦从 feather 加载数据帧并尝试写回它,它就会中断。
要解决这个问题,只需更新到 pyarrow 2.0.0:
pip3 install pyarrow==2.0.0
截至 2020 年 11 月 16 日可用的 pyarrow 版本:
0.9.0, 0.10.0, 0.11.0, 0.11.1, 0.12.0, 0.12.1, 0.13.0, 0.14.0, 0.15.1, 0.16.0, 0.17.0, 0.17.1, 1.0.0, 1.0.1, 2.0.0
我想使用 PyArrow 将以下 pandas 数据框存储在镶木地板文件中:
import pandas as pd
df = pd.DataFrame({'field': [[{}, {}]]})
field
列的类型是字典列表:
field
0 [{}, {}]
我先定义对应的PyArrow schema:
import pyarrow as pa
schema = pa.schema([pa.field('field', pa.list_(pa.struct([])))])
然后我用from_pandas()
:
table = pa.Table.from_pandas(df, schema=schema, preserve_index=False)
这将引发以下异常:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "table.pxi", line 930, in pyarrow.lib.Table.from_pandas
File "/anaconda3/lib/python3.6/site-packages/pyarrow/pandas_compat.py", line 371, in dataframe_to_arrays
convert_types)]
File "/anaconda3/lib/python3.6/site-packages/pyarrow/pandas_compat.py", line 370, in <listcomp>
for c, t in zip(columns_to_convert,
File "/anaconda3/lib/python3.6/site-packages/pyarrow/pandas_compat.py", line 366, in convert_column
return pa.array(col, from_pandas=True, type=ty)
File "array.pxi", line 177, in pyarrow.lib.array
File "error.pxi", line 77, in pyarrow.lib.check_status
File "error.pxi", line 87, in pyarrow.lib.check_status
pyarrow.lib.ArrowTypeError: Unknown list item type: struct<>
我是不是做错了什么或者 PyArrow 不支持这个?
我用的是pyarrow 0.9.0, pandas 23.4, python 3.6.
根据 this Jira issue,在版本 2.0.0 中实现了使用结构和列表嵌套级别的混合读取和写入嵌套 Parquet 数据。
以下示例通过往返演示了实现的功能:pandas 数据框 -> 拼花文件 -> pandas 数据框。使用的 PyArrow 版本是 3.0.0.
初始pandas数据框有一个字典类型列表字段和一个条目:
field
0 [{'a': 1}, {'a': 2}]
示例代码:
import pandas as pd
import pyarrow as pa
import pyarrow.parquet
df = pd.DataFrame({'field': [[{'a': 1}, {'a': 2}]]})
schema = pa.schema(
[pa.field('field', pa.list_(pa.struct([('a', pa.int64())])))])
table_write = pa.Table.from_pandas(df, schema=schema, preserve_index=False)
pyarrow.parquet.write_table(table_write, 'test.parquet')
table_read = pyarrow.parquet.read_table('test.parquet')
table_read.to_pandas()
输出数据帧与输入数据帧相同,应该是:
field
0 [{'a': 1}, {'a': 2}]
我已经能够将 pandas 在列中具有数组的数据帧保存为 parquet,并通过将对象的数据帧数据类型转换为 str 将它们从 parquet 读回数据帧。
def mapTypes(x):
return {'object': 'str', 'int64': 'int64', 'float64': 'float64', 'bool': 'bool',
'datetime64[ns, ' + timezone + ']': 'datetime64[ns, ' + timezone + ']'}.get(x,"str") # string is default if type not mapped
table_names = [x for x in df.columns]
table_types = [mapTypes(x.name) for x in df.dtypes]
parquet_table = dict(zip(table_names, table_types))
df_pq = df.astype(parquet_table)
import awswrangler as wr
wr.s3.to_parquet(df=df_pq,path=path,dataset=True,database='test',mode='overwrite',table=table.lower(),partition_cols=['realmid'],sanitize_columns=True)
下面的图片显示了使用 AWS datawrangler 库从存储在 s3 中的镶木地板文件读取到数据帧,我也用 pyarrow
这是重现此错误的片段:
#!/usr/bin/env python3
import pandas as pd # type: ignore
def main():
"""Main function"""
df = pd.DataFrame()
df["nested"] = [[dict()] for i in range(10)]
df.to_feather("test.feather")
print("Success once")
df = pd.read_feather("test.feather")
df.to_feather("test.feather")
if __name__ == "__main__":
main()
请注意,从 pandas 到 feather,没有任何中断,但是一旦从 feather 加载数据帧并尝试写回它,它就会中断。
要解决这个问题,只需更新到 pyarrow 2.0.0:
pip3 install pyarrow==2.0.0
截至 2020 年 11 月 16 日可用的 pyarrow 版本:
0.9.0, 0.10.0, 0.11.0, 0.11.1, 0.12.0, 0.12.1, 0.13.0, 0.14.0, 0.15.1, 0.16.0, 0.17.0, 0.17.1, 1.0.0, 1.0.1, 2.0.0