Pandas连接多个数据帧

1. 需求

将多个数据帧连接,这几个数据帧可能有不一样的长度,并且数据的排列顺序不固定。

2. 遇到的问题

  1. 因为数据的顺序和长度是不固定的,只能通过表连接方式进行合并,即np.merge()方法。
  2. np.merge()方法一次只能处理两个数据帧。
  3. 如何处理同名的列。

3 实现

1. 生成模拟数据

import pandas as pd 
import numpy as np
from typing import *
df1 = pd.DataFrame([["Alice", 23,2500],
                    ["Bob", 26,3000],
                    ["Carol",27,3000]]
                   , columns=["name","age","salary"])

df2=pd.DataFrame([["Alice",2000],
                  ["Bob",3000],
                  ["Dave",3500]],
                 columns=["name","salary"])


df3=pd.DataFrame([["Alice",2000],
                  ["Carol",3000],
                  ["Dave",3500]],
                 columns=["name","salary"])


df1,df2,df3

2.代码实现

from collections import Counter
from functools import reduce,partial

def merge_dataframes(*dataframes:List[pd.DataFrame],how:str="outer" ,  on: str|List[str] = ...,suffixes:List[str]=...):
    

    #如果传入suffixes参数,判断是否和表格数量相等    
    if  isinstance(suffixes,Iterable) and not isinstance(suffixes,str):
        assert(len(dataframes)==len(suffixes))
        
    #没有传入suffixes参数就直接合并
    else:     
        #使用reduce方法将表格依次合并
        return reduce( lambda A,B: pd.merge(A,B,how=how,on=on) 
                    ,dataframes)

    
    # 下面的代码是根据用户定义的suffix修改重复的列名
    
    # 将单个对象或者可迭代对象转化为列表
    tolist=lambda x:list(x) if isinstance(x,(Tuple,List,pd.Index)) else [x]
    
    #列出所有列名,并计算出现的频次
    all_labels=[col for df in  dataframes for col in df.columns]

    label_counter= Counter(all_labels)

    # 定义列名转换规则,如果一个列名出现多次,那么就在后面加上后缀
    def label_map(label,suffix):
        if label in tolist(on) or label_counter[label]==1:
            return label
        else:
            return str(label)+str(suffix)
    
    # 生成一系列临时的数据帧,改名方式利用了偏函数
    temp_dataframes=[ df.rename(columns=partial(label_map,suffix=suffix))   for df,suffix in zip(dataframes,suffixes)]
    
    
    #使用reduce方法将表格依次合并
    return reduce( lambda A,B: pd.merge(A,B,how=how,on=on) 
                    ,temp_dataframes)
        

3. 测试:

merge_dataframes(df1,df2,df3,on="name",suffixes=["_1","_2","_3"])

输出:

   name   age  salary_1  salary_2  salary_3
0  Alice  23.0    2500.0    2000.0    2000.0
1    Bob  26.0    3000.0    3000.0       NaN
2  Carol  27.0    3000.0       NaN    3000.0
3   Dave   NaN       NaN    3500.0    3500.0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高堂明镜悲白发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值