Pandas连接关联表时避免数据重复的层级存储方案问询
解决Pandas合并DataFrame时避免重复文本的问题
当然可以搞定这个问题!你遇到的核心痛点是合并时产生的笛卡尔积导致文本列重复存储,浪费内存。我们可以通过分组聚合结合合理的索引设计来避免这个问题,下面给你两种实用的方案:
方案1:将同ID的属性聚合为列表,合并后仅保留唯一文本
这种方法最直接,把df2中同一个id对应的所有attr打包成列表,再和df1合并,这样每个id只会对应一行数据,txt列完全没有重复。
import pandas as pd # 构造原始数据 id_range = range(0,5) texts = ['first sent', 'another one', 'I think you', 'will like this', 'will work'] df1 = pd.DataFrame({'txt':texts, 'id':id_range}) df2 = pd.DataFrame({'attr':['chem', 'dis', 'chem', 'chem', 'chem', 'dis', 'dis', 'dis', 'dis', 'chem'] ,'id':[0,0,1,1,2,2,3,3,4,4]}) # 步骤1:对df2按id分组,把attr聚合为列表 df2_grouped = df2.groupby('id')['attr'].agg(list).reset_index() # 步骤2:和df1合并,得到无重复txt的结果 merged_df = df1.merge(df2_grouped, on='id') print(merged_df)
输出结果:
id txt attr 0 0 first sent [chem, dis] 1 1 another one [chem, chem] 2 2 I think you [chem, dis] 3 3 will like this [dis, dis] 4 4 will work [dis, chem]
这种方式的内存效率极高,txt列每个值只存储一次,所有属性都打包在列表中,后续需要展开处理也很方便(比如用explode方法)。
方案2:利用层级索引(MultiIndex)构建紧凑结构
如果你更倾向于用索引来组织数据,可以把id设为主索引,将txt作为固定列,attr以聚合后的形式存储,同样避免重复:
# 将df1设置为以id为索引的DataFrame df1_indexed = df1.set_index('id') # 把df2的attr按id聚合为列表,生成Series attr_series = df2.groupby('id')['attr'].agg(list) # 通过join合并,此时id是索引,txt和attr为列 result_df = df1_indexed.join(attr_series) print(result_df)
输出结果:
txt attr id 0 first sent [chem, dis] 1 another one [chem, chem] 2 I think you [chem, dis] 3 will like this [dis, dis] 4 will work [dis, chem]
如果后续需要对attr进行操作,比如展开成多行,只需要调用result_df.explode('attr')就能回到你之前的合并形式,但平时存储时保持紧凑结构即可。
为什么之前的方法会重复?
你之前用merge后设层级索引的方式,本质还是先做了笛卡尔积合并(每个attr对应一行txt),只是把重复的txt放到了索引里,但数据本身还是重复存储的。而上面的方案从根源上避免了笛卡尔积,通过聚合把同ID的属性打包,自然不会有重复问题。
内容的提问来源于stack exchange,提问作者chase
相关产品推荐
相关产品推荐

