Polars 对于 大数据量(几千万行)划分价格区间(价格段) 有非常高效的原生方法,推荐使用:
✅ 方法一:使用 pl.when().then().otherwise()
分段(推荐)
适合自定义的非等距价格区间,如:
- 0--999 元
- 1000--1999 元
- 2000--4999 元
- 5000 元及以上
less
df = df.with_columns([
pl.when(pl.col("price") < 1000).then("0-999")
.when(pl.col("price") < 2000).then("1000-1999")
.when(pl.col("price") < 5000).then("2000-4999")
.otherwise("5000+")
.alias("price_range")
])
这是 纯表达式向量化处理,速度极快,适合千万行数据。
✅ 方法二:用 cut
类似 Pandas 的 pd.cut
(等距或自定义区间)
虽然 Polars 本身没有内置 cut
函数,但你可以手动实现类似功能:
less
# 假设你想把价格分为每 1000 元一个区间
step = 1000
df = df.with_columns([
((pl.col("price") // step) * step).cast(pl.Int32).alias("price_floor"),
(((pl.col("price") // step) + 1) * step - 1).cast(pl.Int32).alias("price_ceiling")
])
df = df.with_columns([
(pl.col("price_floor").cast(pl.Utf8) + "-" + pl.col("price_ceiling").cast(pl.Utf8)).alias("price_range")
])
例如价格为 2789,则落入区间 2000-2999
。
✅ 方法三:提前准备好价格段字典 + broadcast join(适合维护复杂区间)
ini
# 区间定义 DataFrame
price_bins = pl.DataFrame({
"price_range": ["0-999", "1000-1999", "2000-4999", "5000+"],
"min_price": [0, 1000, 2000, 5000],
"max_price": [999, 1999, 4999, float("inf")]
})
# 扩展 df 加入 price_range 列(条件 join)
df = df.join(price_bins, how="inner",
left_on=pl.col("price"),
right_on=(pl.col("min_price") <= pl.col("price")) & (pl.col("price") <= pl.col("max_price")))
注意这种做法适合精细化分段,并且你能维护段表。
性能建议(千万级数据):
技术点 | 建议 |
---|---|
⚡ 用 .with_columns([...]) 替代 .apply() |
速度数量级提升 |
⚡ 使用 LazyFrame + .collect() |
推迟执行 + 自动优化 |
⚡ 使用 .parquet 等列式文件格式 |
节省内存+加快读取 |
⚡ 多线程默认开启 | 无需手动并行 |