如何在Python极坐标中汇总重复观察?

问题描述 投票:0回答:3

我有一个数据框-

df = pl.DataFrame({'last_name':['mallesh','bhavik','jagarini','mallesh','jagarini'],
                  'first_name':['yamulla','vemulla','yegurla','yamulla','yegurla'],
                  'ssn':['1234','7847','0648','4567','0648']})

在这里,我想根据last_name和first_name列找出重复项,如果发现任何重复项,则如果SSN不不同,则需要用分号(;)汇总它们各自的ssn。如果 SSN 也相同,则只需提供一个 SSN。

enter image description here

预期输出为:

enter image description here

这里,由于 mallesh yamulla 是重复的并且具有不同的 SSN,因此它们用“;”汇总

如果是 jagarini yegurla,它有一个唯一的 SSN,因此只需使用一个 SSN。

enter image description here

新增1个案例:

在给定的任何一组列上,它应该使用 ; 汇总唯一值从剩余的列中。这里的姓氏和名字,应同时在 DOB 和 SSN 上进行汇总。

df = pl.DataFrame({'last_name':['mallesh','bhavik','jagarini','mallesh','jagarini'],
                  'first_name':['yamulla','vemulla','yegurla','yamulla','yegurla'],
                  'ssn':['1234','7847','0648','4567','0648'],
                  'dob':['10/11/1990','09/16/1991','01/01/1990','10/11/1990','02/14/1983']   })

enter image description here

另一个案例为:

df = pl.DataFrame({'last_name':['mallesh','bhavik','jagarini','mallesh','jagarini'],
                  'first_name':['yamulla','vemulla','yegurla','yamulla','yegurla'],
                  'ssn':['1234','7847','0648','4567','0648'],
                  'dob':['10/11/1990','09/16/1991','01/01/1990','','02/14/1983']   })

如果字段中有空值,则应将其视为空而不是值。

“;10/11/1990”对于 mallesh yamulla 条目来说应该是“10/11/1990”。

enter image description here

python python-polars
3个回答
1
投票

使用

group_by
unique
删除重复项。 从那里,您可以在结果列表上使用
arr.join

(
    my_dt
    .groupby(['last_name', 'first_name'])
    .agg([
        pl.col('ssn').unique()
    ])
    .with_column(
        pl.col('ssn').arr.join(';')
    )
)
shape: (3, 3)
┌───────────┬────────────┬───────────┐
│ last_name ┆ first_name ┆ ssn       │
│ ---       ┆ ---        ┆ ---       │
│ str       ┆ str        ┆ str       │
╞═══════════╪════════════╪═══════════╡
│ mallesh   ┆ yamulla    ┆ 4567;1234 │
├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ bhavik    ┆ vemulla    ┆ 7847      │
├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ jagarini  ┆ yegurla    ┆ 0648      │
└───────────┴────────────┴───────────┘

编辑:如果要确保汇总列表已排序:

(
    my_dt
    .groupby(['last_name', 'first_name'])
    .agg([
        pl.col('ssn')
        .unique()
        .sort()
    ])
    .with_column(
        pl.col('ssn')
        .arr.join(';')
    )
)
shape: (3, 3)
┌───────────┬────────────┬───────────┐
│ last_name ┆ first_name ┆ ssn       │
│ ---       ┆ ---        ┆ ---       │
│ str       ┆ str        ┆ str       │
╞═══════════╪════════════╪═══════════╡
│ jagarini  ┆ yegurla    ┆ 0648      │
├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ mallesh   ┆ yamulla    ┆ 1234;4567 │
├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
│ bhavik    ┆ vemulla    ┆ 7847      │
└───────────┴────────────┴───────────┘

编辑:滚动多列

我们可以优雅地卷起多列,如下所示:

(
    my_dt
    .groupby(["last_name", "first_name"])
    .agg([
        pl.all().unique().sort().cast(pl.Utf8)
    ])
    .with_columns([
        pl.exclude(['last_name', 'first_name']).arr.join(";")
    ])
)
shape: (3, 4)
┌───────────┬────────────┬───────────┬───────────────────────┐
│ last_name ┆ first_name ┆ ssn       ┆ dob                   │
│ ---       ┆ ---        ┆ ---       ┆ ---                   │
│ str       ┆ str        ┆ str       ┆ str                   │
╞═══════════╪════════════╪═══════════╪═══════════════════════╡
│ bhavik    ┆ vemulla    ┆ 7847      ┆ 1991-09-16            │
├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ jagarini  ┆ yegurla    ┆ 0648      ┆ 1983-02-14;1990-01-01 │
├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ mallesh   ┆ yamulla    ┆ 1234;4567 ┆ 1990-10-11            │
└───────────┴────────────┴───────────┴───────────────────────┘

编辑:从汇总中消除空字符串和
null

我们可以在

arr.join
之前添加一个过滤步骤来过滤掉
null
和空字符串
""
值。

(
    my_dt.groupby(["last_name", "first_name"])
    .agg([pl.all().unique().sort().cast(pl.Utf8)])
    .with_columns(
        [
            pl.exclude(["last_name", "first_name"])
            .arr.eval(
                pl.element().filter(pl.element().is_not_null() & (pl.element() != ""))
            )
            .arr.join(";")
        ]
    )
)

0
投票

我建议使用列表来存储值:

new_df = my_dt.groupby(['last_name', 'first_name']).agg(list).reset_index()

输出:

  last_name first_name           ssn                       dob
0    bhavik    vemulla        [7847]              [09/16/1991]
1  jagarini    yegurla  [0648, 0648]  [01/01/1990, 02/14/1983]
2   mallesh    yamulla  [1234, 4567]  [10/11/1990, 10/11/1990]

您可以使用以下方法转换为串联值:

for col in new_df.set_index(['last_name', 'first_name']).columns:
    new_df[col] = new_df[col].apply(';'.join)

输出:

  last_name first_name        ssn                    dob
0    bhavik    vemulla       7847             09/16/1991
1  jagarini    yegurla  0648;0648  01/01/1990;02/14/1983
2   mallesh    yamulla  1234;4567  10/11/1990;10/11/1990

0
投票

您可以首先使用 group_by 和 agg 函数来获取结果:

df.unique().group_by('first_name', 'last_name').agg(pl.col('ssn').map_elements(';'.join))
© www.soinside.com 2019 - 2024. All rights reserved.