如何像操作pandas DataFrame一样操作defaultdict实现数据筛选
问题描述
现有一个pandas DataFrame,首先需要将其转换为以id列为键、其余列内容为值的defaultdict,再对生成的defaultdict按id分组,筛选出组内description和amount字段完全相同的重复记录,最终输出符合条件的defaultdict。
基础实现(生成初始defaultdict)
import pandas as pd from collections import defaultdict d = { 'id': [1,1,1,1,2,2,3,3,3,4,4,4,4], 'label':['A','A','B','G','A','BB','C','C','A','BB','B','AA','AA'], 'amount':[2,-12,12,-12,5,-5,2,3,5,3,3,10,10] } df = pd.DataFrame(d) dd = defaultdict(list) # 将df转换为按'id'分组的字典 for index,row in df.iterrows(): dd[row["id"]].append( { "description": row["label"], 'amount':row['amount'] } )
生成的初始dd结构如下:
defaultdict(list, {1:[{'id':1, 'description': 'A', 'amount': 2}, {'id': 1, 'description': 'A', 'amount':-12}, {'id': 1, 'description': 'B', 'amount': 12}, {'id': 1, 'description': 'G', 'amount':-12}], 2:[{'id': 2, 'description': 'A', 'amount': 5}, { 'id': 2, 'description': 'BB', 'amount':-5}], 3:[{'id': 3, 'description': 'C', 'amount': 2}, {'id': 3, 'description': 'C', 'amount': 3}, {'id': 3, 'description': 'A', 'amount': 5}], 4:[{'id': 4, 'description': 'BB', 'amount': 3}, {'id': 4, 'description': 'B', 'amount': 3}, {'id': 4, 'description': 'AA', 'amount': 10}, {'id': 4, 'description': 'AA', 'amount':10}]})
预期输出
defaultdict(list,{4: [{'id': 4, 'description': 'AA', 'amount': 10}, {'id': 4, 'description': 'AA', 'amount': 10}]})
实现方案
方案1:直接操作defaultdict(无需转回pandas)
借助collections.Counter统计每个id分组下description和amount组合的出现次数,筛选出出现次数≥2的所有记录:
from collections import defaultdict, Counter result = defaultdict(list) for id_val, records in dd.items(): # 统计当前id下所有(description, amount)组合的出现次数 pair_count = Counter((rec['description'], rec['amount']) for rec in records) # 保留出现次数≥2的组合对应的全部记录 dup_records = [rec for rec in records if pair_count[(rec['description'], rec['amount'])] >= 2] # 仅保留存在重复记录的id if dup_records: result[id_val] = dup_records
方案2:转回pandas处理(适合熟悉pandas语法的场景)
如果习惯用pandas的重复值判断逻辑,可以先把defaultdict转回DataFrame,筛选完再转回目标结构:
import pandas as pd # 将defaultdict转换为DataFrame df_dup = pd.DataFrame([ {'id': id_val, **rec} for id_val, records in dd.items() for rec in records ]) # 保留id、description、amount三个字段同时重复的所有行 df_dup = df_dup[df_dup.duplicated(subset=['id', 'description', 'amount'], keep=False)] # 转换回目标defaultdict结构 result = defaultdict(list) for _, row in df_dup.iterrows(): result[row['id']].append({ 'description': row['description'], 'amount': row['amount'] })
两种方案最终输出的result都和预期效果一致。
内容的提问来源于stack exchange,提问作者hippocampus
相关产品推荐
相关产品推荐

