基于条件在Pandas DataFrame中复制行并修改指定列的值
问题描述
我有一个包含多列的Pandas dataframe,为简化示例,假设格式如下:
Item Interval Specs Chocolate 0 0.001 Chocolate 3 0.002 Chocolate 5 0.007 Milk 0 0.004 Milk 2 0.008 ....
我需要实现的需求是:针对原dataframe中Interval值为0的每一行,复制该行并仅修改Interval字段的取值为对应Item下除0以外的其他Interval值,Specs字段保持原值不变。例如原数据中Item为Chocolate的记录对应Interval值有0、3、5三个,我需要复制Interval为0的行2次,分别将Interval修改为3和5,生成2条新记录;同理Item为Milk的记录需要复制1次Interval为0的行,将Interval修改为2(需生成的重复行数直接取决于每个Item对应的唯一Interval值数量)。
预期输出的dataframe如下:
Item Interval Specs Chocolate 0 0.001 Chocolate 3 0.002 Chocolate 5 0.007 Chocolate 3 0.001 --新增重复行,Interval值已修改 Chocolate 5 0.001 --新增重复行,Interval值已修改 Milk 0 0.004 Milk 2 0.008 Milk 2 0.004 --新增重复行,Interval值已修改
实现方案
基础循环写法(易理解,适合小数据量)
import pandas as pd # 构造示例数据,替换为你自己的DataFrame即可 df = pd.DataFrame({ 'Item': ['Chocolate', 'Chocolate', 'Chocolate', 'Milk', 'Milk'], 'Interval': [0, 3, 5, 0, 2], 'Specs': [0.001, 0.002, 0.007, 0.004, 0.008] }) # 1. 统计每个Item对应的所有非0Interval值 item_non_zero_intervals = df[df['Interval'] != 0].groupby('Item')['Interval'].unique().to_dict() # 2. 筛选所有Interval=0的行,批量生成新行 zero_rows = df[df['Interval'] == 0] new_rows = [] for _, row in zero_rows.iterrows(): cur_item = row['Item'] for target_interval in item_non_zero_intervals.get(cur_item, []): new_row = row.copy() new_row['Interval'] = target_interval new_rows.append(new_row) # 3. 拼接原数据和新生成的行 result = pd.concat([df, pd.DataFrame(new_rows)], ignore_index=True) print(result)
向量化写法(性能更高,适合大数据量)
用Pandas原生的explode方法避免循环,处理十万级以上数据效率提升明显:
# 1. 生成每个Item对应的非0Interval列表 non_zero_map = df[df['Interval'] != 0].groupby('Item')['Interval'].unique().reset_index(name='target_interval') # 2. 关联0值行,炸开列表得到所有新增行 new_rows = df[df['Interval'] == 0].merge(non_zero_map, on='Item')\ .explode('target_interval')\ .drop('Interval', axis=1)\ .rename(columns={'target_interval': 'Interval'}) # 3. 拼接得到最终结果 result = pd.concat([df, new_rows], ignore_index=True)
内容的提问来源于stack exchange,提问作者JChat
相关产品推荐
相关产品推荐

