美文网首页
Python polars学习-09 数据框关联与拼接

Python polars学习-09 数据框关联与拼接

作者: 数据人阿多 | 来源:发表于2024-07-22 15:03 被阅读0次

    背景

    polars学习系列文章,第9篇 数据框关联与拼接(Join 、Concat)

    该系列文章会分享到github,大家可以去下载jupyter文件,进行参考学习
    仓库地址:https://github.com/DataShare-duo/polars_learn

    小编运行环境

    import sys
    
    print('python 版本:',sys.version.split('|')[0])
    #python 版本: 3.11.9
    
    import polars as pl
    
    print("polars 版本:",pl.__version__)
    #polars 版本: 1.2.1
    

    数据框关联 Join

    polars 通过指定参数 how,支持以下方式的关联:

    • inner:类似sql中的 inner join,取2个数据框共同的部分
    • left:类似sql中的 left join,取左边数据框所有数据,匹配右边数据框数据,能匹配到的进行匹配,匹配不到的用 null 填充
    • full:类似sql中的 full outer join,返回2个数据框的全量数据,匹配不到的用 null 填充
    • cross:2个数据框的笛卡尔积,数据行数为,len(A) × len(B)
    • semi:用的相对比较少,左边数据框中关联字段同时存在右边数据框中,只返回左边数据框的行,有点类似 inner join,但是不全完一样,即使右边数据框有多行的,左边返回的还是单行,也就是遇到关联字段存在于右边数据框,就返回
    • anti:用的相对比较少,返回左边数据框中关联字段不存在右边数据框中的行,与 semi 相反

    数据准备

    df_customers = pl.DataFrame(
        {
            "customer_id": [1, 2, 3],
            "name": ["Alice", "Bob", "Charlie"],
        }
    )
    
    print(df_customers)
    #shape: (3, 2)
    ┌─────────────┬─────────┐
    │ customer_id ┆ name    │
    │ ---         ┆ ---     │
    │ i64         ┆ str     │
    ╞═════════════╪═════════╡
    │ 1           ┆ Alice   │
    │ 2           ┆ Bob     │
    │ 3           ┆ Charlie │
    └─────────────┴─────────┘
    
    df_orders = pl.DataFrame(
        {
            "order_id": ["a", "b", "c"],
            "customer_id": [1, 2, 2],
            "amount": [100, 200, 300],
        }
    )
    
    print(df_orders)
    #shape: (3, 3)
    ┌──────────┬─────────────┬────────┐
    │ order_id ┆ customer_id ┆ amount │
    │ ---      ┆ ---         ┆ ---    │
    │ str      ┆ i64         ┆ i64    │
    ╞══════════╪═════════════╪════════╡
    │ a        ┆ 1           ┆ 100    │
    │ b        ┆ 2           ┆ 200    │
    │ c        ┆ 2           ┆ 300    │
    └──────────┴─────────────┴────────┘
    

    Inner join

    df_inner_customer_join = df_customers.join(df_orders, 
                                               on="customer_id", 
                                               how="inner")
    
    print(df_inner_customer_join)
    #shape: (3, 4)
    ┌─────────────┬───────┬──────────┬────────┐
    │ customer_id ┆ name  ┆ order_id ┆ amount │
    │ ---         ┆ ---   ┆ ---      ┆ ---    │
    │ i64         ┆ str   ┆ str      ┆ i64    │
    ╞═════════════╪═══════╪══════════╪════════╡
    │ 1           ┆ Alice ┆ a        ┆ 100    │
    │ 2           ┆ Bob   ┆ b        ┆ 200    │
    │ 2           ┆ Bob   ┆ c        ┆ 300    │
    └─────────────┴───────┴──────────┴────────┘
    

    Left join

    df_left_join = df_customers.join(df_orders, 
                                     on="customer_id", 
                                     how="left")
    
    print(df_left_join)
    #shape: (4, 4)
    ┌─────────────┬─────────┬──────────┬────────┐
    │ customer_id ┆ name    ┆ order_id ┆ amount │
    │ ---         ┆ ---     ┆ ---      ┆ ---    │
    │ i64         ┆ str     ┆ str      ┆ i64    │
    ╞═════════════╪═════════╪══════════╪════════╡
    │ 1           ┆ Alice   ┆ a        ┆ 100    │
    │ 2           ┆ Bob     ┆ b        ┆ 200    │
    │ 2           ┆ Bob     ┆ c        ┆ 300    │
    │ 3           ┆ Charlie ┆ null     ┆ null   │
    └─────────────┴─────────┴──────────┴────────┘
    

    Outer join

    df_outer_join = df_customers.join(df_orders, 
                                      on="customer_id", 
                                      how="full")
    
    print(df_outer_join)
    #shape: (4, 5)
    ┌─────────────┬─────────┬──────────┬───────────────────┬────────┐
    │ customer_id ┆ name    ┆ order_id ┆ customer_id_right ┆ amount │
    │ ---         ┆ ---     ┆ ---      ┆ ---               ┆ ---    │
    │ i64         ┆ str     ┆ str      ┆ i64               ┆ i64    │
    ╞═════════════╪═════════╪══════════╪═══════════════════╪════════╡
    │ 1           ┆ Alice   ┆ a        ┆ 1                 ┆ 100    │
    │ 2           ┆ Bob     ┆ b        ┆ 2                 ┆ 200    │
    │ 2           ┆ Bob     ┆ c        ┆ 2                 ┆ 300    │
    │ 3           ┆ Charlie ┆ null     ┆ null              ┆ null   │
    └─────────────┴─────────┴──────────┴───────────────────┴────────┘
    

    Cross join

    df_colors = pl.DataFrame(
        {
            "color": ["red", "blue", "green"],
        }
    )
    print(df_colors)
    #shape: (3, 1)
    ┌───────┐
    │ color │
    │ ---   │
    │ str   │
    ╞═══════╡
    │ red   │
    │ blue  │
    │ green │
    └───────┘
    
    df_sizes = pl.DataFrame(
        {
            "size": ["S", "M", "L"],
        }
    )
    #print(df_sizes)
    
    df_cross_join = df_colors.join(df_sizes, 
                                   how="cross")
    
    print(df_cross_join)
    #shape: (9, 2)
    ┌───────┬──────┐
    │ color ┆ size │
    │ ---   ┆ ---  │
    │ str   ┆ str  │
    ╞═══════╪══════╡
    │ red   ┆ S    │
    │ red   ┆ M    │
    │ red   ┆ L    │
    │ blue  ┆ S    │
    │ blue  ┆ M    │
    │ blue  ┆ L    │
    │ green ┆ S    │
    │ green ┆ M    │
    │ green ┆ L    │
    └───────┴──────┘
    

    Semi join

    df_cars = pl.DataFrame(
        {
            "id": ["a", "b", "c"],
            "make": ["ford", "toyota", "bmw"],
        }
    )
    print(df_cars)
    shape: (3, 2)
    ┌─────┬────────┐
    │ id  ┆ make   │
    │ --- ┆ ---    │
    │ str ┆ str    │
    ╞═════╪════════╡
    │ a   ┆ ford   │
    │ b   ┆ toyota │
    │ c   ┆ bmw    │
    └─────┴────────┘
    
    df_repairs = pl.DataFrame(
        {
            "id": ["c", "c"],
            "cost": [100, 200],
        }
    )
    print(df_repairs)
    #shape: (2, 2)
    ┌─────┬──────┐
    │ id  ┆ cost │
    │ --- ┆ ---  │
    │ str ┆ i64  │
    ╞═════╪══════╡
    │ c   ┆ 100  │
    │ c   ┆ 200  │
    └─────┴──────┘
    
    df_semi_join = df_cars.join(df_repairs, 
                                on="id", 
                                how="semi")
    print(df_semi_join)
    #shape: (1, 2)
    ┌─────┬──────┐
    │ id  ┆ make │
    │ --- ┆ ---  │
    │ str ┆ str  │
    ╞═════╪══════╡
    │ c   ┆ bmw  │
    └─────┴──────┘
    

    Anti join

    df_anti_join = df_cars.join(df_repairs, 
                                on="id", 
                                how="anti")
    
    print(df_anti_join)
    #shape: (2, 2)
    ┌─────┬────────┐
    │ id  ┆ make   │
    │ --- ┆ ---    │
    │ str ┆ str    │
    ╞═════╪════════╡
    │ a   ┆ ford   │
    │ b   ┆ toyota │
    └─────┴────────┘
    

    数据框拼接 Concat

    有以下3种方式的数据框拼接:

    • 纵向拼接/垂直拼接:2个数据框有相同的字段,拼接后产生更长的数据框
    • 横向拼接/水平拼接:2个数据框没有重叠的字段,拼接后产生更宽的数据框
    • 对角拼接:2个数据框有不同的行与列,既有重叠的字段,也有非重叠的字段,拼接后产生即长又宽的数据框

    纵向拼接/垂直拼接 Vertical concatenation

    当没有相同的列字段时,纵向拼接会失败

    df_v1 = pl.DataFrame(
        {
            "a": [1],
            "b": [3],
        }
    )
    df_v2 = pl.DataFrame(
        {
            "a": [2],
            "b": [4],
        }
    )
    df_vertical_concat = pl.concat(
        [
            df_v1,
            df_v2,
        ],
        how="vertical",
    )
    print(df_vertical_concat)
    #shape: (2, 2)
    ┌─────┬─────┐
    │ a   ┆ b   │
    │ --- ┆ --- │
    │ i64 ┆ i64 │
    ╞═════╪═════╡
    │ 1   ┆ 3   │
    │ 2   ┆ 4   │
    └─────┴─────┘
    

    横向拼接/水平拼接 Horizontal concatenation

    当2个数据框有不同的行数时,拼接后短的行会用 null 进行填充

    df_h1 = pl.DataFrame(
        {
            "l1": [1, 2],
            "l2": [3, 4],
        }
    )
    df_h2 = pl.DataFrame(
        {
            "r1": [5, 6],
            "r2": [7, 8],
            "r3": [9, 10],
        }
    )
    df_horizontal_concat = pl.concat(
        [
            df_h1,
            df_h2,
        ],
        how="horizontal",
    )
    print(df_horizontal_concat)
    #shape: (2, 5)
    ┌─────┬─────┬─────┬─────┬─────┐
    │ l1  ┆ l2  ┆ r1  ┆ r2  ┆ r3  │
    │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
    │ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 │
    ╞═════╪═════╪═════╪═════╪═════╡
    │ 1   ┆ 3   ┆ 5   ┆ 7   ┆ 9   │
    │ 2   ┆ 4   ┆ 6   ┆ 8   ┆ 10  │
    └─────┴─────┴─────┴─────┴─────┘
    

    对角拼接 Diagonal concatenation

    df_d1 = pl.DataFrame(
        {
            "a": [1],
            "b": [3],
        }
    )
    df_d2 = pl.DataFrame(
        {
            "a": [2],
            "d": [4],
        }
    )
    
    df_diagonal_concat = pl.concat(
        [
            df_d1,
            df_d2,
        ],
        how="diagonal",
    )
    print(df_diagonal_concat)
    #shape: (2, 3)
    ┌─────┬──────┬──────┐
    │ a   ┆ b    ┆ d    │
    │ --- ┆ ---  ┆ ---  │
    │ i64 ┆ i64  ┆ i64  │
    ╞═════╪══════╪══════╡
    │ 1   ┆ 3    ┆ null │
    │ 2   ┆ null ┆ 4    │
    └─────┴──────┴──────┘
    

    历史相关文章


    以上是自己实践中遇到的一些问题,分享出来供大家参考学习,欢迎关注微信公众号:DataShare ,不定期分享干货

    相关文章

      网友评论

          本文标题:Python polars学习-09 数据框关联与拼接

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