如何在Polars DataFrame中保存与加载Spacy编码?加载报错求助
解决Polars加载含Spacy Doc对象DataFrame的ArrowInvalid错误
错误原因
ArrowInvalid: Could not convert Hello with type spacy.tokens.doc.Doc: did not recognize Python value type when inferring an Arrow data type 错误的核心问题是:Polars底层依赖Arrow数据格式,而Spacy的Doc是Python自定义对象,没有对应的Arrow原生数据类型,因此从Pandas转换回Polars时无法识别该类型。
解决方案
你实际需求是生成文本嵌入,而非保存完整的Doc对象,因此优先推荐提取Doc中的向量嵌入来存储,而非保留Doc实例。
方案1:提取嵌入向量(推荐)
修改生成encoding列的逻辑,直接提取Doc的向量值,同时用Polars原生方法读写,避免转Pandas的额外类型问题:
from io import StringIO import polars as pl import spacy nlp = spacy.load("de_core_news_sm") json_str = '[{"foo":"Hello","bar":6},{"foo":"What a lovely day","bar":7},{"foo":"Nice to meet you","bar":8}]' # 初始化DataFrame并生成嵌入向量 df = pl.read_json(StringIO(json_str)) # 提取Doc的向量(de_core_news_sm返回96维的平均词向量) df = df.with_columns(pl.col("foo").map_elements(lambda x: nlp(x).vector).alias("encoding")) # 用Polars原生方法保存到磁盘 df.write_pickle('pickled_df.pkl') # 重新加载为Polars DataFrame df_loaded_pl = pl.read_pickle('pickled_df.pkl') print(df_loaded_pl)
nlp(x).vector返回numpy数组,Polars会自动识别为List[f64]类型,完全兼容Arrow格式。- 直接使用
pl.DataFrame.write_pickle比转Pandas再存储更高效,也避免了中间环节的类型转换问题。
方案2:序列化Doc对象(不推荐)
如果必须保存完整的Doc对象,需要先将其序列化为字节串,加载时再反序列化:
from io import StringIO import polars as pl import spacy import pickle nlp = spacy.load("de_core_news_sm") json_str = '[{"foo":"Hello","bar":6},{"foo":"What a lovely day","bar":7},{"foo":"Nice to meet you","bar":8}]' # 初始化DataFrame并序列化Doc对象 df = pl.read_json(StringIO(json_str)) df = df.with_columns(pl.col("foo").map_elements(lambda x: pickle.dumps(nlp(x))).alias("encoding")) # 保存和加载 df.write_pickle('pickled_df.pkl') df_loaded_pl = pl.read_pickle('pickled_df.pkl') # 反序列化恢复Doc对象 df_loaded_pl = df_loaded_pl.with_columns(pl.col("encoding").map_elements(lambda x: pickle.loads(x)).alias("encoding"))
- 该方式会占用更多存储空间,且后续处理
Doc对象时仍需注意类型兼容性,仅在必须保留完整Doc实例时使用。
内容的提问来源于stack exchange,提问作者HappyHippo
相关产品推荐
相关产品推荐

