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

如何基于字典高效填充DataFrame的指定列

更简洁的DataFrame填充方案

问题背景

现有如下DataFrame和字典:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'A': [1, 1, 1, 2, 2, 3, 3, 3, 3],
    'ignore_me': range(9),
    'fill_me': [np.nan] * 9
})

di = {
    1: ['a', 'b'],
    2: ['c', 'd'],
    3: ['e', 'f', 'g']
}

需求是:根据A列的值匹配字典di的键,用对应字典值列表填充fill_me列,每个组仅填充前N行(N为对应字典值的长度),超出部分保留NaN,预期结果如下:

A  ignore_me fill_me
0  1          0       a
1  1          1       b
2  1          2     NaN
3  2          3       c
4  2          4       d
5  3          5       e
6  3          6       f
7  3          7       g
8  3          8     NaN

原实现方式需要循环、concat且生成多个临时DataFrame:

df_list = []
for key, values in di.items():
    temp_df = df[df['A'] == key].reset_index(drop=True)
    fill_df = pd.DataFrame({'A': [key]* len(values), 'fill_me': values})
    df_list.append(temp_df.combine_first(fill_df))

final_df = pd.concat(df_list, ignore_index=True)

希望找到更简洁的实现方式,最好能直接在原DataFrame上操作。

简洁实现方案

方案一:组内序号匹配赋值(直接修改原df)

无需额外生成DataFrame,直接在原数据上操作:

# 生成每个组内的连续序号
df['group_idx'] = df.groupby('A').cumcount()

# 把字典转换成(A, 组内序号)对应值的映射表
fill_map = {
    (key, idx): val 
    for key, vals in di.items() 
    for idx, val in enumerate(vals)
}

# 匹配赋值,没匹配到的保留原NaN
df['fill_me'] = df.apply(
    lambda row: fill_map.get((row['A'], row['group_idx']), row['fill_me']),
    axis=1
)

# 清理临时列
df = df.drop('group_idx', axis=1)

方案二:构造匹配DataFrame合并填充

通过生成一个包含匹配规则的小DataFrame,和原数据合并完成填充:

# 把字典展开成带组内序号的填充DataFrame
fill_df = pd.DataFrame([
    (key, idx, val) 
    for key, vals in di.items() 
    for idx, val in enumerate(vals)
], columns=['A', 'group_idx', 'fill_me'])

# 给原df添加组内序号
df['group_idx'] = df.groupby('A').cumcount()

# 左合并保留所有行,用新值填充原NaN
df = df.merge(fill_df, on=['A', 'group_idx'], how='left', suffixes=('', '_new'))
df['fill_me'] = df['fill_me_new'].combine_first(df['fill_me'])

# 清理临时列
df = df.drop(['group_idx', 'fill_me_new'], axis=1)

方案三:向量化高效操作(推荐)

避免apply的逐行循环,用布尔索引和映射实现更高效的填充:

# 生成组内序号
df['group_idx'] = df.groupby('A').cumcount()

# 为每个A获取可填充的最大序号(字典值长度-1)
max_valid_idx = df['A'].map(lambda x: len(di[x]) - 1)

# 筛选出需要填充的行
fill_mask = df['group_idx'] <= max_valid_idx

# 对需要填充的行,直接从字典中取值
df.loc[fill_mask, 'fill_me'] = df.loc[fill_mask].apply(
    lambda x: di[x['A']][x['group_idx']],
    axis=1
)

# 清理临时列
df = df.drop('group_idx', axis=1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 18:16:37