美文网首页
2020-08-09--Pandas-10--转换拼接

2020-08-09--Pandas-10--转换拼接

作者: program_white | 来源:发表于2020-08-09 14:05 被阅读0次

    1.拼接

    有两个DataFrame,都存储了用户的一些信息,现在要拼接起来,组成一个DataFrame,如何实现呢?

    import pandas as pd
    import numpy as np
    
    data1 = {
        "name": ["Tom", "Bob"],
        "age": [18, 30],
        "city": ["Bei Jing ", "Shang Hai "]
    }
    
    df1 = pd.DataFrame(data=data1)
    print(df1)
    #   name  age        city
    # 0  Tom   18   Bei Jing
    # 1  Bob   30  Shang Hai
    
    data2 = {
        "name": ["Mary", "James"],
        "age": [35, 18],
        "city": ["Guang Zhou", "Shen Zhen"]
    }
    
    df2 = pd.DataFrame(data=data2)
    print(df2)
    #     name  age        city
    # 0   Mary   35  Guang Zhou
    # 1  James   18   Shen Zhen
    

    append

    append 是最简单的拼接两个DataFrame的方法。

    拼接后的索引默认还是原有的索引,如果想要重新生成索引的话,设置参数 ignore_index=True 即可。

    df = df1.append(df2)
    print(df)
    #     name  age        city
    # 0    Tom   18   Bei Jing
    # 1    Bob   30  Shang Hai
    # 0   Mary   35  Guang Zhou
    # 1  James   18   Shen Zhen
    df = df1.append(df2,ignore_index=True)
    print(df)
    #     name  age        city
    # 0    Tom   18   Bei Jing 
    # 1    Bob   30  Shang Hai 
    # 2   Mary   35  Guang Zhou
    # 3  James   18   Shen Zhen
    

    concat

    除了 append 这种方式之外,还有 concat 这种方式可以实现相同的功能。

    concat可以实现多个对象的拼接

    df = pd.concat([df1,df2],ignore_index=True)
    print(df)
    #     name  age        city
    # 0    Tom   18   Bei Jing
    # 1    Bob   30  Shang Hai
    # 2   Mary   35  Guang Zhou
    # 3  James   18   Shen Zhen
    

    如果想要区分出不同的DataFrame的数据,可以通过设置参数 keys,当然得设置参数 ignore_index=False。

    df = pd.concat([df1,df2], ignore_index=False, keys=["df1", "df2"])
    print(df)
    #         name  age        city
    # df1 0    Tom   18   Bei Jing
    #     1    Bob   30  Shang Hai
    # df2 0   Mary   35  Guang Zhou
    #     1  James   18   Shen Zhen
    

    2.关联

    有两个DataFrame,分别存储了用户的部分信息,现在需要将用户的这些信息关联起来,如何实现呢?

    import pandas as pd
    import numpy as np
    
    data1 = {
        "name": ["Tom", "Bob", "Mary", "James"],
        "age": [18, 30, 35, 18],
        "city": ["Bei Jing ", "Shang Hai ", "Guang Zhou", "Shen Zhen"]
    }
    
    df1 = pd.DataFrame(data=data1)
    print(df1)
    #     name  age        city
    # 0    Tom   18   Bei Jing
    # 1    Bob   30  Shang Hai
    # 2   Mary   35  Guang Zhou
    # 3  James   18   Shen Zhen
    
    data2 = {"name": ["Bob", "Mary", "James", "Andy"],
            "sex": ["male", "female", "male", np.nan],
             "income": [8000, 8000, 4000, 6000]
    }
    
    df2 = pd.DataFrame(data=data2)
    print(df2)
    #     name     sex  income
    # 0    Bob    male    8000
    # 1   Mary  female    8000
    # 2  James    male    4000
    # 3   Andy     NaN    6000
    

    1.merge

    通过 pd.merge 可以关联两个DataFrame,这里我们设置参数 on="name",表示依据 name来作为关联键。

    默认使用内连接

    c = pd.merge(df1,df2,on='name')
    print(c)
    #     name  age        city     sex  income
    # 0    Bob   30  Shang Hai     male    8000
    # 1   Mary   35  Guang Zhou  female    8000
    # 2  James   18   Shen Zhen    male    4000
    

    关联后发现数据变少了,只有 3 行数据,这是因为默认关联的方式是 inner,如果不想丢失任何数据,可以设
    置参数 how="outer"。

    外连接:

    c = pd.merge(df1,df2,on='name',how='outer')
    print(c)
    #     name   age        city     sex  income
    # 0    Tom  18.0   Bei Jing      NaN     NaN
    # 1    Bob  30.0  Shang Hai     male  8000.0
    # 2   Mary  35.0  Guang Zhou  female  8000.0
    # 3  James  18.0   Shen Zhen    male  4000.0
    # 4   Andy   NaN         NaN     NaN  6000.0
    

    可以看到,设置参数 how="outer" 后,确实不会丢失任何数据,他会在不存在的地方填为缺失值。

    如果我们想保留左边所有的数据,可以设置参数 how="left";反之,如果想保留右边的所有数据,可以设置参数 how="right"

    c = pd.merge(df1,df2,on='name',how='left')
    print(c)
    #     name  age        city     sex  income
    # 0    Tom   18   Bei Jing      NaN     NaN
    # 1    Bob   30  Shang Hai     male  8000.0
    # 2   Mary   35  Guang Zhou  female  8000.0
    # 3  James   18   Shen Zhen    male  4000.0
    
    • 内连接:左右两个数据集中取交集的数据为结果。连接不上的数据全部舍弃。
    • 左连接:以左边的数据为主,左边数据的每一项都必须在结果中出现,对于左连接来说,左数据中数据项与右表中连接不上,则设为NaN,右表中连接不上的数据直接舍去。
    • 右连接:与左连接相反。
    • 全连接:所有数据都要在结果中出现,有数据缺失时,以NaN填充。
    主键名

    使用pd.merge时,连接时是根据on参数值进行来连接的,那么要保证连接的两个对象中的列名相同,所以有时需要设置左右对象的列名进行连接。

    1.首先修改两个对象的name列的列名

    df1.rename(columns={'name':'name1'},inplace=True)
    print(df1)
    #    name1  age        city
    # 0    Tom   18   Bei Jing
    # 1    Bob   30  Shang Hai
    # 2   Mary   35  Guang Zhou
    # 3  James   18   Shen Zhen
    df2.rename(columns={'name':'name2'},inplace=True)
    print(df2)
    #    name2     sex  income
    # 0    Bob    male    8000
    # 1   Mary  female    8000
    # 2  James    male    4000
    # 3   Andy     NaN    6000
    

    到这里这两个DataFrame对象的name列的列明就不一样了---nam1和name2

    2.连接

    在pd.merge()可以通过参数: left_on 和 right_on 来分别设置。

    df = pd.merge(df1,df2,left_on='name1',right_on='name2',how='outer')
    print(df)
    #    name1   age        city  name2     sex  income
    # 0    Tom  18.0   Bei Jing     NaN     NaN     NaN
    # 1    Bob  30.0  Shang Hai     Bob    male  8000.0
    # 2   Mary  35.0  Guang Zhou   Mary  female  8000.0
    # 3  James  18.0   Shen Zhen  James    male  4000.0
    # 4    NaN   NaN         NaN   Andy     NaN  6000.0
    
    相同名称字段处理

    有时候,两个DataFrame中都包含相同名称的字段,如何处理呢?
    例如:

    print(df1)
    #     name  age        city
    # 0    Tom   18   Bei Jing
    # 1    Bob   30  Shang Hai
    # 2   Mary   35  Guang Zhou
    # 3  James   18   Shen Zhen
    print(df2)
    #     name     sex  income
    # 0    Bob    male    8000
    # 1   Mary  female    8000
    # 2  James    male    4000
    # 3   Andy     NaN    6000
    
    df1['sex'] = 'male'
    print(df1)
    #    name1  age        city   sex
    # 0    Tom   18   Bei Jing   male
    # 1    Bob   30  Shang Hai   male
    # 2   Mary   35  Guang Zhou  male
    # 3  James   18   Shen Zhen  male
    

    这是df1和df2有一个相同的字段名sex,如果关联的话会不会冲突呢?

    我们可以设置参数 suffixes,默认 suffixes=('_x', '_y') 表示将相同名称的左边的DataFrame的字段名加上后缀 _x,右边加上后缀 _y。也就是说就算不写该参数,遇到相同字段关联时,也会区分开来。

    df = pd.merge(df1, df2, left_on="name1", right_on="name2")
    print(df)
    #    name1  age        city sex_x  name2   sex_y  income
    # 0    Bob   30  Shang Hai   male    Bob    male    8000
    # 1   Mary   35  Guang Zhou  male   Mary  female    8000
    # 2  James   18   Shen Zhen  male  James    male    4000
    
    df = pd.merge(df1, df2, left_on="name1", right_on="name2", suffixes=("_left", "_right"))
    print(df)
    #    name1  age        city sex_left  name2 sex_right  income
    # 0    Bob   30  Shang Hai      male    Bob      male    8000
    # 1   Mary   35  Guang Zhou     male   Mary    female    8000
    # 2  James   18   Shen Zhen     male  James      male    4000
    

    我们还可以重写该参数值,设置为自己可以区分的字符串---suffixes=("_left", "_right")。

    2.join

    除了 merge 这种方式外,还可以通过 join 这种方式实现关联。

    相比 merge,join 这种方式有以下几个不同:

    • 默认参数on=None,表示关联时使用左边和右边的索引作为键。
    • 设置参数on可以指定的是关联时左边的所用到的键名。
    • 左边和右边字段名称重复时,通过设置参数 lsuffix 和 rsuffix 来解决。

    实例:

    print(df1)
    #    name1  age        city   sex
    # 0    Tom   18   Bei Jing   male
    # 1    Bob   30  Shang Hai   male
    # 2   Mary   35  Guang Zhou  male
    # 3  James   18   Shen Zhen  male
    
    print(df2)
    #    name2     sex  income
    # 0    Bob    male    8000
    # 1   Mary  female    8000
    # 2  James    male    4000
    # 3   Andy     NaN    6000
    df2.set_index('name2',inplace=True)
    print(df2)
    #           sex  income
    # name2
    # Bob      male    8000
    # Mary   female    8000
    # James    male    4000
    # Andy      NaN    6000
    
    df = df1.join(df2,on='name1',lsuffix='_left',rsuffix='_right')
    print(df)
    #    name1  age        city sex_left sex_right  income
    # 0    Tom   18   Bei Jing      male       NaN     NaN
    # 1    Bob   30  Shang Hai      male      male  8000.0
    # 2   Mary   35  Guang Zhou     male    female  8000.0
    # 3  James   18   Shen Zhen     male      male  4000.0
    
    • df1.join():默认为df1为主数据集,类似于左连接。
    • 参数中df2为右数据集,on参数指定df1中的连接主键,与df2中的索引列进行连接。
    • lsuffix='_left',rsuffix='_right':指定遇到相同字段关联后数据列的名称。

    相关文章

      网友评论

          本文标题:2020-08-09--Pandas-10--转换拼接

          本文链接:https://www.haomeiwen.com/subject/yasldktx.html