Python中合并DataFrame后按EID_STAVBA合并行的实现方法
问题:合并DataFrame后将同一EID_STAVBA的多行数据合并为一行?
我原本合并两个DataFrame的代码是:
GES1 = pd.merge(db1, db2, on = 'KO-STA', how = 'left')
其中db1、db2的数据结构如下:
db1数据:
,EID_STAVBA,ST_STAVBE,PLIN,LETO_IZGRA,LETO_OBNOV,LETO_OBNO0,BRUTO_TLOR,EID_OBCINA,SIFKO,EID_DEL_STAVBE,VRSTA_DEJANSKE_RABE_DEL_ST_ID,LETO_OBNOVE_INSTALACIJ,LETO_OBNOVE_OKEN,POVRSINA,ST_DELA_STAVBE,VRSTA_STANOVANJA_ID,UPORABNA_POVRSINA,KO-STA,EID_PARCEL,KO_ID,ST_PARCELE,KO-PAR 0,100200000250868938,4645,0.0,1980.0,,,,110200000110277170,1722,100200000250868958,1,,,37.8,1,,37.8,1722-4645,100100000210682339,1722,903,1722-903
db2数据:
,KO-STA,STA-PAR,KO-PAR,Ukrep_Opis,Ukrep_Kolicina,Ukrep_Enota,UkrepES_Fasada,UkrepES_Streha,UkrepES_Okna,UkrepES_TC,UkrepES_TC_tip,UkrepES_Biomasa,UkrepES_Biomasa_tip,UkrepES_Prezracevanje,UkrepES_PV,UkrepES_SSE 0,1722-4645,0.0,1722-903,Zamenjava oken,0.0,0.0,0.0,0.0,2022.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 1,1722-4645,0.0,1722-903,TI fasade,0.0,0.0,2022.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 2,1722-4645,0.0,1722-903,SSE,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2022.0 3,1722-4645,0.0,1722-903,PV,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2022.0,0.0
合并后的输出为:
EID_STAVBA ST_STAVBE ... UkrepES_PV UkrepES_SSE 0 100200000250868938 4645 ... 0.0 0.0 1 100200000250868938 4645 ... 0.0 2022.0 2 100200000250868938 4645 ... 0.0 0.0 3 100200000250868938 4645 ... 2022.0 0.0
其中同一EID_STAVBA对应多行数据,我希望将同一EID_STAVBA的所有数据合并到一行,示例如下:
,EID_STAVBA,ST_STAVBE,PLIN,LETO_IZGRA,LETO_OBNOV,LETO_OBNO0,BRUTO_TLOR,EID_OBCINA,SIFKO,EID_DEL_STAVBE,VRSTA_DEJANSKE_RABE_DEL_ST_ID,LETO_OBNOVE_INSTALACIJ,LETO_OBNOVE_OKEN,POVRSINA,ST_DELA_STAVBE,VRSTA_STANOVANJA_ID,UPORABNA_POVRSINA,KO-STA,EID_PARCEL,KO_ID,ST_PARCELE,index,STA-PAR,KO-PAR,Ukrep_Opis,Ukrep_Kolicina,Ukrep_Enota,UkrepES_Fasada,UkrepES_Streha,UkrepES_Okna,UkrepES_TC,UkrepES_TC_tip,UkrepES_Biomasa,UkrepES_Biomasa_tip,UkrepES_Prezracevanje,UkrepES_PV,UkrepES_SSE 0,100200000250868938,4645,0.0,1980.0,,,,110200000110277170,1722,100200000250868958,1,,,37.8,1,,37.8,1722-4645,100100000210682339,1722,903,0,0.0,1722-903,Zamenjava oken,0.0,0.0,0.0,0.0,2022.0,0.0,2022.0,0.0,0.0,0.0,2022.0,2022.0
请问应如何修改代码实现该需求?是否需要使用groupby方法?
解答
需要使用groupby方法实现,核心逻辑是先完成合并,再按EID_STAVBA分组,针对不同类型的列设置聚合规则:
- 原
db1中的基础列(如EID_STAVBA、ST_STAVBE等),同一EID_STAVBA下值完全一致,直接取唯一值即可; db2中的数值型列(如UkrepES_Fasada、UkrepES_Okna等),需要保留分散在各行的有效年份(非0值),用max聚合就能自动提取有效数值;- 文本列
Ukrep_Opis,可以用字符串拼接的方式合并所有操作描述。
具体代码如下:
# 执行原合并操作 GES1 = pd.merge(db1, db2, on='KO-STA', how='left') # 定义各列的聚合规则 agg_rules = {} for col in GES1.columns: if col in db1.columns: # 原db1的列取第一个值(同一分组下值相同) agg_rules[col] = 'first' elif col == 'Ukrep_Opis': # 拼接所有操作描述 agg_rules[col] = lambda x: ','.join(x.astype(str)) else: # 数值列取最大值,保留有效年份 agg_rules[col] = 'max' # 按EID_STAVBA分组聚合,合并为单行 result = GES1.groupby('EID_STAVBA', as_index=False).agg(agg_rules)
执行后即可得到同一EID_STAVBA对应一行的结果,其中数值列会合并分散的有效年份,文本列会汇总所有操作描述。
内容的提问来源于stack exchange,提问作者energyMax
相关产品推荐
相关产品推荐

