Polars替代Pandas explode()遇十六进制值报错,求解决方案
在Polars中实现类似Pandas的apply+explode逻辑(处理zip返回的列表)
问题原因
你当前的Polars写法中,使用df.iter_rows(named=True)逐行处理后构造pl.Series,会导致Polars无法正确识别list(zip(...))返回的元组类型,错误地将其解析为bytes(表现为十六进制值),最终触发explode操作的报错。
解决方案
Polars的核心优势是向量化操作,推荐避免逐行迭代,改用以下两种方式实现需求:
方式1:向量化map_elements(推荐)
通过pl.struct将需要处理的列打包,再用map_elements执行自定义逻辑,同时明确指定返回类型,确保Polars正确识别列结构:
import polars as pl self.var1 = 'A' self.var2 = 'B' # 假设df是Polars DataFrame,A、B列为数值或数组类型 df = df.with_columns( # 打包需要处理的列 pl.struct([self.var1, self.var2]) # 执行自定义逻辑,指定返回类型为「包含元组的列表」 .map_elements( lambda row: list(zip(row[self.var1] + row[self.var2], row[self.var1] * row[self.var2])), return_dtype=pl.List(pl.Tuple([pl.Int64, pl.Int64])) # 根据实际数据类型调整 ) .alias("column1") ) # 正常执行explode exploded_df = df.explode("column1", ignore_index=True)
方式2:复用原自定义函数
如果需要保留原someFun函数的逻辑,同样可以通过map_elements实现,无需逐行迭代:
import polars as pl self.var1 = 'A' self.var2 = 'B' def someFun(row): var = self.var1 var2 = self.var2 cal1 = row[var] + row[var2] cal2 = row[var] * row[var2] return list(zip(cal1, cal2)) df = df.with_columns( pl.struct([self.var1, self.var2]) .map_elements(someFun, return_dtype=pl.List(pl.Tuple([pl.Int64, pl.Int64]))) .alias("column1") ) exploded_df = df.explode("column1", ignore_index=True)
关键说明
- 必须明确指定
return_dtype:告诉Polars返回的列是「包含元组的列表」,避免类型推断错误。 - 避免使用
iter_rows:逐行迭代会丢失Polars的向量化性能优势,且容易引发类型解析问题。
内容的提问来源于stack exchange,提问作者dhruv bothra
相关产品推荐
相关产品推荐

