如何在Polars中基于ID列值选对应列并生成新列(避免Unpivot)
解决方案:无需unpivot实现动态列拼接
针对你的需求,这里提供两种无需使用unpivot的高效方法,既能保留所有额外列,又能根据ID值动态拼接对应前缀的Left/Right列:
方法1:动态生成向量化条件(推荐大数据量场景)
利用Polars的when/then链式条件,根据ID的唯一值自动生成匹配逻辑,全程是向量化操作,性能更优:
import polars as pl # 示例DataFrame df = pl.DataFrame({ "ID": ["A", "B", "A", "C"], "A Left": ["W1", "X1", "W2", "Y1"], "A Right": ["P1", "Q1", "P2", "R1"], "B Left": ["X2", "X3", "X4", "X5"], "B Right": ["Q2", "Q3", "Q4", "Q5"], "C Left": ["Y2", "Y3", "Y4", "Y5"], "C Right": ["R2", "R3", "R4", "R5"], "ExtraCol1": [1,2,3,4], "ExtraCol2": ["foo", "bar", "baz", "qux"] }) # 获取所有唯一ID值 unique_ids = df["ID"].unique().to_list() # 构建链式条件 value_expr = None for id_val in unique_ids: left_col = f"{id_val} Left" right_col = f"{id_val} Right" # 生成当前ID对应的拼接逻辑 current_expr = pl.when(pl.col("ID") == id_val).then( pl.col(left_col).str.cat(pl.col(right_col), separator="-") ) # 拼接条件链 if value_expr is None: value_expr = current_expr else: value_expr = value_expr.when(current_expr.condition).then(current_expr.then) # 添加value列 result_df = df.with_columns(value=value_expr)
方法2:行级动态列索引(代码更简洁)
通过pl.row的lambda函数,根据当前行的ID值直接索引对应的Left/Right列并拼接,代码更紧凑:
result_df = df.with_columns( value=pl.row(lambda row: f"{row[f'{row["ID"]} Left']}-{row[f'{row["ID"]} Right']}") )
注意事项
- 确保所有ID值对应的
{ID} Left和{ID} Right列都存在,否则会触发列不存在的错误。 - 方法1的向量化操作在处理百万级以上数据时,性能远优于方法2的行级操作;方法2适合ID取值较少、数据量不大的场景。
内容的提问来源于stack exchange,提问作者Mustafa Elec
相关产品推荐
相关产品推荐

