如何在Pandas中按条件修改DataFrame的total列数值(避免iterrows)
问题描述
我有如下示例DataFrame:
col1 | col2 | ... total ------------------------ 0,19 | 31 | .... |I need 200,02 euros 0,19 | 40 | .... |I need 10,02 euros 0 | 20 | .... |I need 150,02 euros . | .. | .... |...
需求:仅在col2的值为31时,替换total列中的数值。新数值的计算规则是:除col2=31之外所有行的(total数值 * col1数值)+ total数值的总和。
示例计算:((10.02 * 0.19)+10.02) + ((150.02 * 0)+150.02) = 161.94,最终DataFrame如下:
col1 | col2 | ... total ------------------------ 0,19 | 31 | .... |I need 161,94 euros 0,19 | 40 | .... |I need 10,02 euros 0 | 20 | .... |I need 150,02 euros . | .. | .... |...
已知df.iterrows()方法,但官方明确提示:
never modify something you are iterating over
请问该如何实现此需求?
实现方案
完全可以不用iterrows(),用pandas的矢量化操作高效完成,步骤如下:
预处理数值列
先把col1和total中的逗号替换为点,转换为数值类型:# 处理col1:替换逗号为点,转为float类型 df['col1'] = df['col1'].str.replace(',', '.').astype(float) # 提取total中的数值部分,替换逗号为点后转为float df['total_num'] = df['total'].str.extract(r'(\d+,\d+)')[0].str.replace(',', '.').astype(float)计算目标替换值
筛选出col2 != 31的行,计算每行的total_num * (col1 + 1)(等价于total_num*col1 + total_num),再求和得到目标值,最后格式化为带逗号的字符串:# 计算总和 target_value = df[df['col2'] != 31]['total_num'].mul(df[df['col2'] != 31]['col1'] + 1).sum() # 保留两位小数,将点换回逗号 target_str = f"{target_value:.2f}".replace('.', ',')替换指定行的total内容
用loc定位col2 == 31的行,替换total列的数值部分:df.loc[df['col2'] == 31, 'total'] = df.loc[df['col2'] == 31, 'total'].str.replace(r'\d+,\d+', target_str) # 可选:删除临时创建的total_num列 df = df.drop('total_num', axis=1)
全程使用矢量化操作,比iterrows()效率更高,也符合pandas官方的最佳实践。
内容的提问来源于stack exchange,提问作者franco mango
相关产品推荐
相关产品推荐

