如何按object_id分组后扩展DataFrame补全item_id完整范围
更优实现方案
针对你需要按object_id扩展分组结果、填充缺失条目为0的需求,这里提供两种更符合Pandas惯用风格的实现方式,效率和可读性均优于手动构建列表的朴素方法:
方法一:利用MultiIndex重新索引(推荐,效率最高)
这种方法通过构建完整的多级索引,再对分组结果重新索引来填充缺失值,全程采用Pandas矢量化操作,适合大数据集:
import pandas as pd # 原数据 df = pd.DataFrame( { "object_id": [1, 1, 1, 1, 1, 2, 2, 2], "item_id": [1, 2, 4, 4, 5, 1, 1, 2], "item_count": [6, 6, 6, 6, 6, 3, 3, 3], } ) # 按object_id和item_id分组统计数量 df_group = df.groupby(["object_id", "item_id"], as_index=False).size() # 获取每个object_id对应的item_count映射(去重后提取) object_item_map = df[["object_id", "item_count"]].drop_duplicates().set_index("object_id")["item_count"].to_dict() # 构建包含所有需要条目的完整MultiIndex full_multi_index = pd.MultiIndex.from_tuples( [(obj, item) for obj, cnt in object_item_map.items() for item in range(1, cnt + 1)], names=["object_id", "item_id"] ) # 重新索引并填充缺失值,最后重置索引 df_full = df_group.set_index(["object_id", "item_id"]).reindex(full_multi_index, fill_value=0).reset_index() print(df_full)
输出结果:
object_id item_id size 0 1 1 1 1 1 2 1 2 1 3 0 3 1 4 2 4 1 5 1 5 1 6 0 6 2 1 2 7 2 2 1 8 2 3 0
方法二:分组后逐组扩展(逻辑更直观)
通过groupby.apply对每个object_id组单独生成完整的item序列,再合并统计结果,逻辑清晰易读:
import pandas as pd df = pd.DataFrame( { "object_id": [1, 1, 1, 1, 1, 2, 2, 2], "item_id": [1, 2, 4, 4, 5, 1, 1, 2], "item_count": [6, 6, 6, 6, 6, 3, 3, 3], } ) def expand_single_group(group): # 获取当前组的最大item_id范围 max_item = group["item_count"].iloc[0] # 生成1到max_item的完整item_id序列 full_items = pd.DataFrame({"item_id": range(1, max_item + 1)}) # 统计当前组内各item的数量 item_counts = group.groupby("item_id").size().reset_index(name="size") # 合并并填充缺失值 return full_items.merge(item_counts, on="item_id", how="left")\ .fillna(0).astype({"size": int})\ .assign(object_id=group["object_id"].iloc[0]) # 分组处理后合并结果 df_full = df.groupby("object_id").apply(expand_single_group).reset_index(drop=True) print(df_full)
输出结果与方法一完全一致。
内容的提问来源于stack exchange,提问作者BBQuercus
相关产品推荐
相关产品推荐

