如何在Polars中转置包含List类型元素的DataFrame?
如何在Polars中转置包含List类型元素的DataFrame?
看起来你遇到的核心问题是:Polars的转置、透视类操作不支持直接处理list[str]类型的列,而且你尝试用arr.join转换时,因为列选择的方式不对导致了报错。我来一步步帮你解决:
1. 先把List类型列转成字符串(解决arr.join的报错)
你之前的代码用了pl.all().exclude("cs_rule_data_check").arr.join(","),这个报错的原因是可能你排除的列名不准确,或者不小心包含了非List类型的列。更稳妥的方式是直接选择所有List类型的列来处理,避免误操作其他列:
# 将所有list[str]类型的列转为逗号分隔的字符串 df_processed = df.with_columns( pl.col(pl.List).arr.join(",") )
这样就不会再出现expected FixedSizeList, got list[str]的错误了,因为我们明确只对List类型的列应用arr.join方法。
2. 用Unpivot + Pivot实现转置效果
Polars原生的transpose方法对包含复杂类型的DataFrame支持有限,所以我们可以用「宽表转长表(unpivot)」再「长表转宽表(pivot)」的组合来实现你要的“规则变列、原列变行”的效果:
拿你提供的示例代码来演示:
# 你的示例DataFrame df = pl.DataFrame({ "rule": "cs_rule_data_check", "647833": [["Info","Ok"]], "647201": [["Critical"]] }) # 第一步:转换List为字符串 df_processed = df.with_columns(pl.col(pl.List).arr.join(",")) # 第二步:宽表转长表,把原列名转为行数据 unpivoted = df_processed.unpivot( index="rule", variable_name="original_column", # 原列名的存储列名 value_name="check_result" # 原单元格值的存储列名 ) # 第三步:长表转宽表,实现转置效果 transposed_df = unpivoted.pivot( index="original_column", # 用原列名作为新的行索引 columns="rule", # 用原规则列作为新的列名 values="check_result" # 用转换后的字符串作为值 ) print(transposed_df)
运行后会得到你想要的转置结果:
shape: (2, 2) ┌────────────────┬──────────────────────────┐ │ original_column ┆ cs_rule_data_check │ │ --- ┆ --- │ │ str ┆ str │ ╞════════════════╪══════════════════════════╡ │ 647833 ┆ Info,Ok │ │ 647201 ┆ Critical │ └────────────────┴──────────────────────────┘
3.(可选)把字符串转回List类型
如果后续你需要将字符串恢复为list[str]类型,只需要用str.split方法即可:
transposed_df = transposed_df.with_columns( pl.col(pl.Utf8).str.split(",") )
为什么直接用transpose/unpivot会报错?
Polars的transpose和unpivot操作要求值列的类型是可统一转换的,而list[str]类型无法直接被自动转换为字符串类型(也就是你遇到的cannot cast List type (inner: 'String', to: 'String')错误),所以必须先将List转为字符串,完成转置后再按需转回。
备注:内容来源于stack exchange,提问作者Glenn Pierce
相关产品推荐
相关产品推荐

