You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas按层级从低到高将0值替换为匹配parent_key的self_key行均值

问题解决:按层级填充DataFrame中的0值为子节点均值

需求说明

需要将DataFrame中value列的0值替换为所有parent_key匹配该行self_key的子节点的value均值,且必须按从最低层级到最高层级的顺序填充(低层级数据会向上汇总到高层级)。执行原代码时出现报错:ValueError: Grouper for '<class 'pandas.core.frame.DataFrame'>' not 1-dimensional。

输入数据

创建DataFrame的代码:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'self_key':['a','b','c','d','e','e','e','f','f','f'],
    'parent_key':[np.nan,'a','b','b','c','c','c','d','d','d'], 
    'value':[0,0,0,0,4,6,14,12,8,22],
    'level':[1,2,3,3,4,4,4,4,4,4]
})

原始数据:

self_key parent_key  value  level
0        a        NaN      0      1
1        b          a      0      2
2        c          b      0      3
3        d          b      0      3
4        e          c      4      4
5        e          c      6      4
6        e          c     14      4
7        f          d     12      4
8        f          d      8      4
9        f          d     22      4

预期输出

self_key parent_key  value  level
0        a        NaN     11      1
1        b          a     11      2
2        c          b      8      3
3        d          b     14      3
4        e          c      4      4
5        e          c      6      4
6        e          c     14      4
7        f          d     12      4
8        f          d      8      4
9        f          d     22      4

报错原因

原代码报错是因为分组时误将整个DataFrame作为分组依据,而Pandas的groupby需要一维的分组键(比如Series或列名)。

可行解决方案

核心思路:先按层级从高到低(即从最低层级到最高层级)排序,然后依次计算每个父节点的子节点均值,填充对应父节点的0值。

完整代码实现

import pandas as pd
import numpy as np

# 初始化DataFrame
df = pd.DataFrame({
    'self_key':['a','b','c','d','e','e','e','f','f','f'],
    'parent_key':[np.nan,'a','b','b','c','c','c','d','d','d'], 
    'value':[0,0,0,0,4,6,14,12,8,22],
    'level':[1,2,3,3,4,4,4,4,4,4]
})

# 获取所有层级,按从高到低排序(从最低层级到最高层级处理)
levels = sorted(df['level'].unique(), reverse=True)

# 遍历每个层级,从最高层级向下处理
for current_level in levels:
    # 跳过无0值的层级
    if df[(df['level'] == current_level) & (df['value'] == 0)].empty:
        continue
    
    # 计算每个父节点对应的子节点value均值
    child_mean = df.groupby('parent_key')['value'].mean().reset_index(name='child_mean')
    
    # 合并均值表,填充0值
    df = df.merge(child_mean, left_on='self_key', right_on='parent_key', how='left')
    df['value'] = df.apply(
        lambda row: row['child_mean'] if (row['value'] == 0 and pd.notna(row['child_mean'])) else row['value'],
        axis=1
    )
    
    # 清理临时列
    df.drop(['parent_key_y', 'child_mean'], axis=1, inplace=True)
    df.rename(columns={'parent_key_x': 'parent_key'}, inplace=True)

# 输出结果
print(df)

代码说明

  1. 层级排序:获取所有唯一层级并降序排列,确保先处理低层级,再用填充后的低层级数据计算高层级均值。
  2. 计算子节点均值:通过groupby('parent_key')['value'].mean()得到每个父节点对应的子节点value均值,作为填充依据。
  3. 填充0值:将原DataFrame与均值表合并,对value为0的行,用对应的子节点均值替换。
  4. 清理临时列:删除合并产生的临时列,恢复原始DataFrame结构。

运行结果

执行代码后,输出与预期完全一致。

内容的提问来源于stack exchange,提问作者rupi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 11:45:35