如何按字典键匹配对DataFrame列做除法,无匹配时保持原值?
DataFrame按字典映射修改delta列的多种实现方案
需求描述
有一个包含delta和integer_id列的DataFrame df,以及一个将integer_id映射为浮点值的字典d。需要将df中每行的delta除以d里对应integer_id的值;如果该行的integer_id不在字典中,就保持delta不变。
示例数据
import pandas as pd df = pd.DataFrame({ "integer_id": [1, 2, 3], "delta": [10, 20, 30] }) d = {1: 0.5, 3: 0.25}
预期结果
# 处理后的df integer_id delta 0 1 20.0 1 2 20.0 2 3 120.0
可行方案
方案1:map+fillna生成除数列
先通过map获取字典中的对应值,再用fillna把缺失值(不在字典中的id)填充为1,最后做除法:
divisors = df['integer_id'].map(d).fillna(1) df['delta'] /= divisors
这个方法和你用lambda x: d.get(x,1)的思路本质一致,但用fillna更直观,代码可读性更强。
方案2:条件筛选+loc赋值
先筛选出integer_id存在于字典中的行,只对这些行的delta做除法操作,其余行保持原样:
# 生成筛选掩码:哪些行的integer_id在字典里 mask = df['integer_id'].isin(d.keys()) # 仅对符合条件的行执行除法 df.loc[mask, 'delta'] /= df.loc[mask, 'integer_id'].map(d)
这种方法不需要处理全量数据,只修改需要调整的行,在数据集较大时效率更高。
方案3:apply逐行判断
用apply逐行检查integer_id是否在字典中,再决定是否修改delta:
df['delta'] = df.apply( lambda row: row['delta'] / d[row['integer_id']] if row['integer_id'] in d else row['delta'], axis=1 )
注意:apply是逐行处理,数据量很大时速度会比前两种慢,适合小数据集使用。
方案4:replace结合条件替换
先通过replace把字典中的id替换为对应值,再把未替换的id(不在字典里的)替换为1,最后做除法:
# 先替换字典中的id为对应值,未匹配的保留原id divisors = df['integer_id'].replace(d) # 把未匹配的id替换为1 divisors = divisors.where(df['integer_id'].isin(d.keys()), 1) df['delta'] /= divisors
这个方法稍显繁琐,但也是一种可行思路,适合需要对替换过程做更多自定义的场景。
内容的提问来源于stack exchange,提问作者roulette01
相关产品推荐
相关产品推荐

