我有一个dask数据框,它的列类型为List [MyClass]。我想将此数据帧保存到镶木地板文件中。 Dask使用pyarrow作为后端,但仅支持基本类型。
import pandas as pd
import dask.dataframe as dd
class MyClass:
def __init__(self, a):
self.a = a
def transform(v):
return [MyClass(v)]
a = [[1], [2], [3]]
pdf = pd.DataFrame.from_dict(a)
ddf = dd.from_pandas(pdf, npartitions=1)
result = ddf.assign(mycol=ddf[0].apply(transform))
result.to_parquet('my_parquet.parquet')
因此,当我尝试保存它时,出现此错误:
ArrowInvalid: Error inferring Arrow data type for collection of Python objects. Got Python object of type MyClass but can only handle these types: bool, float, integer, date, datetime, bytes, unicode, decimal
。
很明显,我必须将MyClass
转换为pyarrow兼容的结构类型,但是我找不到方法。 Pyarrow&dask具有一些序列化功能(例如https://arrow.apache.org/docs/python/ipc.html#serializing-custom-data-types),但似乎并不是我所需要的。
答案 0 :(得分:1)
有点晚了,但是也许link可以帮助别人。
基本上,这取决于定义定制的手工序列化函数。例如,这是您的课程:
class MyData:
def __init__(self, name, data):
self.name = name
self.data = data
您编写的函数可以与此类进行转换,例如:
def _serialize_MyData(val):
return {'name': val.name, 'data': val.data}
def _deserialize_MyData(data):
return MyData(data['name'], data['data']
然后从这些函数初始化上下文,以稍后提供给序列化/反序列化方法:
context = pa.SerializationContext()
context.register_type(MyData, 'MyData',
custom_serializer=_serialize_MyData,
custom_deserializer=_deserialize_MyData)
现在,您调用serialize
/ deserialize
方法并将其传递给上下文:
buf = pa.serialize(val, context=context).to_buffer()
restored_val = pa.deserialize(buf, context=context)