Polars中如何基于其他DataFrame的ID更新指定列或保留原始列
解决方案
一、用processed更新original的m_g/m_s(保留原始quantity)
核心逻辑是通过分组键做关联匹配,完全不依赖行顺序,从根源避免数据错位问题。直接提取processed中需要更新的字段,和original做左关联后替换对应列即可。
示例代码:
import polars as pl # 从processed中提取关联键和需要更新的字段,重命名避免冲突 processed_updates = processed.select( pl.col(['partition', 'class', 'side', 'trade_price_normalized', 'type']), pl.col('m_g').alias('updated_m_g'), pl.col('m_s').alias('updated_m_s') ) # 左关联原始表和更新表,仅替换匹配到的m_g/m_s值 final_df = original.join( processed_updates, on=['partition', 'class', 'side', 'trade_price_normalized', 'type'], how='left' ).with_columns( # 有更新值则替换,无匹配的保留原始值 pl.col('m_g').fill_null(pl.col('updated_m_g')), pl.col('m_s').fill_null(pl.col('updated_m_s')) ).drop(['updated_m_g', 'updated_m_s']) # 清理临时列
二、聚合时同时保留原始quantity和聚合值
分两种场景处理:
场景1:分组后保留组内所有原始quantity,同时生成聚合总和
直接在聚合操作中对quantity同时做列表收集和求和:
processed_with_original_qty = dataframe_original.group_by( ['partition', 'class', 'side', 'trade_price_normalized', 'type'] ).agg( pl.col('quantity').alias('original_quantities'), # 保留组内所有原始quantity pl.col('quantity').sum().alias('agg_quantity'), pl.col('m_g').last().alias('m_g'), # 按实际更新逻辑取m_g/m_s,比如last/first pl.col('m_s').last().alias('m_s') ) # 如需拆回与原表行数一致的结构,用explode展开原始quantity列表 expanded_df = processed_with_original_qty.explode('original_quantities')
场景2:原表每行保留自身原始quantity,同时新增所在组的聚合值
用over窗口函数实现,无需分组后再拼接:
dataframe_original = dataframe_original.with_columns( pl.col('quantity').sum().over([ 'partition', 'class', 'side', 'trade_price_normalized', 'type' ]).alias('agg_quantity') )
关键注意点
- 拒绝依赖行顺序匹配数据,所有关联操作必须用明确的业务键(即分组字段),从根源避免排序错位问题。
- 避开Polars标记为不稳定的
update方法,用join+with_columns的组合逻辑更稳定、可读性更强。
内容的提问来源于stack exchange,提问作者barrelquentin997
相关产品推荐
相关产品推荐

