Pandas高效实现:基于df_2的zop_id计算df_1均值并填充df_2
Pandas高效实现跨DataFrame匹配均值填充
问题背景
现有两个Pandas DataFrame:df_1和df_2,定义及数据如下:
import pandas as pd data = [[1, 5, 6.2], [3, 2, 3.2], [4, 5, 9.1], [1, 4,8.2], [5, 3, 2.4] ] data_id = [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0] ] df_1 = pd.DataFrame(data, columns=['foo', 'baz', "result"]) df_2 = pd.DataFrame(data_id, columns=['zop_id', 'baz'])
需求:针对df_2中zop_id列的每个值,计算df_1中foo、baz任意一列包含该值的所有行的result列均值,并用该均值覆盖df_2对应的baz列。例如zop_id=2时,df_1仅第二行的baz列是2,因此对应填充值为3.2。
高效实现方案
无需循环,利用Pandas的宽表转长表和分组聚合操作即可完成,全程矢量化处理,性能远优于循环:
步骤1:将df_1的foo、baz列转成统一长格式
把foo和baz列的所有值整合到同一列,保留对应的result值,方便后续按值分组计算均值:
# 宽转长,提取foo和baz的所有值,对应到result melted_df = df_1.melt(id_vars='result', value_vars=['foo', 'baz'], value_name='id_val')
步骤2:按id_val分组计算result的均值
# 分组计算每个id对应的result均值 mean_map = melted_df.groupby('id_val')['result'].mean()
步骤3:用zop_id匹配均值,填充df_2的baz列
直接用map方法将zop_id对应到均值,替换原有的baz列值:
df_2['baz'] = df_2['zop_id'].map(mean_map)
完整代码及验证
import pandas as pd # 初始化数据 data = [[1, 5, 6.2], [3, 2, 3.2], [4, 5, 9.1], [1, 4,8.2], [5, 3, 2.4] ] data_id = [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0] ] df_1 = pd.DataFrame(data, columns=['foo', 'baz', "result"]) df_2 = pd.DataFrame(data_id, columns=['zop_id', 'baz']) # 核心操作 melted_df = df_1.melt(id_vars='result', value_vars=['foo', 'baz'], value_name='id_val') mean_map = melted_df.groupby('id_val')['result'].mean() df_2['baz'] = df_2['zop_id'].map(mean_map) # 查看结果 print(df_2)
运行后输出的df_2如下:
zop_id baz 0 1 7.20 1 2 3.20 2 3 2.80 3 4 8.20 4 5 7.75
验证关键值:
- zop_id=1:df_1中第1、4行的foo为1,result均值为
(6.2+8.2)/2=7.2,正确。 - zop_id=5:df_1中第1、3行的baz为5,第5行的foo为5,result均值为
(6.2+9.1+2.4)/3=7.75,正确。
方案优势
全程使用Pandas内置的矢量化操作,避免了Python循环的低效问题,在数据量较大时性能提升尤为明显,代码也更简洁易维护。
内容的提问来源于stack exchange,提问作者user37292
相关产品推荐
相关产品推荐

