如何用Polars DataFrame判断浮点值是否落在区间型分类值内
问题分析与解决方法
问题根源
你用is_in配合pl.Categorical的思路完全偏离了需求:
pl.Categorical只是把字符串转成分类枚举类型,本质还是离散的字符串值;is_in的作用是判断某个值是否存在于另一组离散集合中,根本没法处理“数值落在区间内”的逻辑,所以才会全返回False。
正确解法
要实现需求,核心是解析每个区间字符串为数值边界,再逐行判断数值是否符合区间规则。
通用版(支持多种区间格式)
如果你的区间有不同的开闭类型(比如(x,y]、[x,y)、[x,y]等),可以用下面的代码:
import polars as pl df = pl.DataFrame({ "real_value": [0.5, 2.7, 3.9], "categorical_value": ["(0,1.1]", "(1.1,2.6]", "(2.6,4.5]"] }) # 解析区间信息 df = df.with_columns( # 提取区间内的数字,转为浮点数列表 pl.col("categorical_value").str.extract_all(r"\d+\.?\d*").cast(pl.Float64).alias("bounds"), # 获取左括号类型 pl.col("categorical_value").str.slice(0, 1).alias("left_bracket"), # 获取右括号类型 pl.col("categorical_value").str.slice(-1, 1).alias("right_bracket") ).with_columns( # 拆分上下限 pl.col("bounds").list.get(0).alias("lower_bound"), pl.col("bounds").list.get(1).alias("upper_bound") ).with_columns( # 根据区间开闭规则判断 pl.when( (pl.col("left_bracket") == "(") & (pl.col("right_bracket") == "]") ).then( (pl.col("real_value") > pl.col("lower_bound")) & (pl.col("real_value") <= pl.col("upper_bound")) ).when( (pl.col("left_bracket") == "[") & (pl.col("right_bracket") == ")") ).then( (pl.col("real_value") >= pl.col("lower_bound")) & (pl.col("real_value") < pl.col("upper_bound")) ).when( (pl.col("left_bracket") == "[") & (pl.col("right_bracket") == "]") ).then( (pl.col("real_value") >= pl.col("lower_bound")) & (pl.col("real_value") <= pl.col("upper_bound")) ).when( (pl.col("left_bracket") == "(") & (pl.col("right_bracket") == ")") ).then( (pl.col("real_value") > pl.col("lower_bound")) & (pl.col("real_value") < pl.col("upper_bound")) ).alias("is_in_cat") ).drop("bounds", "left_bracket", "right_bracket", "lower_bound", "upper_bound") # 清理临时列 print(df)
简化版(仅左开右闭格式)
如果你的区间格式统一为(x,y]这种左开右闭类型,代码可以大幅简化:
import polars as pl df = pl.DataFrame({ "real_value": [0.5, 2.7, 3.9], "categorical_value": ["(0,1.1]", "(1.1,2.6]", "(2.6,4.5]"] }) df = df.with_columns( # 提取区间数字并转为浮点数列表 pl.col("categorical_value").str.extract_all(r"\d+\.?\d*").cast(pl.Float64).alias("bounds") ).with_columns( # 直接判断左开右闭条件 (pl.col("real_value") > pl.col("bounds").list.get(0)) & (pl.col("real_value") <= pl.col("bounds").list.get(1)).alias("is_in_cat") ).drop("bounds") print(df)
运行上述代码后,is_in_cat列会得到你预期的[True, False, True]结果。
内容的提问来源于stack exchange,提问作者Carlitos Overflow
相关产品推荐
相关产品推荐

