如何用Python结合条件语句实现循环?Pandas数据计算与重构求助
问题描述
我正在Jupyter Notebook中使用Pandas处理包含product列重复项的数据集,数据集结构如下:
| name | val_id | val_amt | our_val_amt | val_against | product | NEW FIELD |
|---|---|---|---|---|---|---|
| compx | xx1 | 530 | 424 | 418 | XL | 290 |
| compx | xx1 | 530 | 424 | 134 | CL | 134 |
| compx | xx2 | 590 | 472 | 600 | XL | 369 |
| compx | xx2 | 590 | 472 | 103 | CL | 103 |
需要按name分组(实际数据包含多个name),执行以下条件计算生成NEW FIELD:
- 若
product为'CL'且val_against小于our_val_amt,将val_against填入NEW FIELD - 若
product为'XL'且与CL行同属一个val_id,用our_val_amt减去对应CL行的NEW FIELD值,结果填入XL行的NEW FIELD - 对每个
val_id重复上述计算
最终需将数据重构为如下格式:
val id --------------- | xx1 | xx2 | | our_val_amt | --------------------------------------- | product |val_against | 424 | 472 | ---------------------------------------- | XL | 418 | 290 | | | CL | 134 | 134 | | | XL | 600 | | 369 | | CL | 103 | | 103 |
我尝试过按变量分组并以product为列,生成了6000+列;也尝试过循环但未成功,求技术解决方案。
解决方案
步骤1:计算NEW FIELD
用Pandas的分组和向量化操作替代循环,高效完成计算:
import pandas as pd # 假设数据集存储在df中 # 1. 初始化NEW FIELD为缺失值 df['NEW FIELD'] = pd.NA # 2. 处理CL行:符合条件时赋值val_against cl_mask = (df['product'] == 'CL') & (df['val_against'] < df['our_val_amt']) df.loc[cl_mask, 'NEW FIELD'] = df.loc[cl_mask, 'val_against'] # 3. 处理XL行:按name+val_id分组,获取对应CL行的NEW FIELD值并计算 def calculate_xl_row(group): cl_value = group.loc[group['product'] == 'CL', 'NEW FIELD'].iloc[0] group.loc[group['product'] == 'XL', 'NEW FIELD'] = group['our_val_amt'] - cl_value return group df = df.groupby(['name', 'val_id'], group_keys=False).apply(calculate_xl_row)
步骤2:重构为目标格式
通过透视表构建复合表头结构:
# 1. 生成基础透视表:行是product+val_against,列是val_id,值是NEW FIELD pivot_df = df.pivot_table( index=['product', 'val_against'], columns='val_id', values='NEW FIELD', aggfunc='first' ) # 2. 构建复合表头:每个val_id列上方添加对应的our_val_amt val_id_amt_map = df.drop_duplicates('val_id').set_index('val_id')['our_val_amt'] pivot_df.columns = pd.MultiIndex.from_tuples( [(vid, val_id_amt_map[vid]) for vid in pivot_df.columns], names=['val id', 'our_val_amt'] ) # 重置索引,让product和val_against作为普通列显示 final_df = pivot_df.reset_index()
执行后用display(final_df)在Jupyter中即可查看和目标格式一致的表格。
关键说明
- 全程用Pandas内置的分组、向量化操作,避免循环,处理大数据集效率更高
- 透视表仅保留实际存在的val_id列,不会生成冗余列
- 按
name+val_id分组,确保多name场景下各分组计算独立,互不干扰
内容的提问来源于stack exchange,提问作者svenvuko
相关产品推荐
相关产品推荐

