Pandas dataframe lambda function/applymap 将多行合并到一列中并删除重复项

Pandas dataframe lambda function/applymap to combine multiple rows in a column and remove duplicates

如何在 pandas 数据帧上执行以下操作?

  1. 将一列、多行的文本合并为一行
  2. 删除“一行”中的重复项
  3. 对多列重复 1 和 2

根据以下Stack Overflow问题和答案,我做了下面的尝试代码。最后一次尝试很接近,但我不知道如何将集合转换回字符串(即删除大括号)并将其滚动到 lambda 函数中,我可以将 applymap() 用于多列。

  1. Concatenate strings from several rows using Pandas groupby

示例数据框

id = [1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4]
colA = ['type12', 'type11', 'type11', 'type11', 'type21', 'type21', 
        'type22', 'type23', 'type23', 'type23', 'type31', 'type31', 
        'type31', 'type31', 'type41', 'type41', 'type42', 'type41', 
        'type41', 'type43'
        ]
colB = ['Set A', 'Set B', 'Set B', 'Set B', 'Set B', 'Set B', 'Set A', 
        'Set B', 'Set C', 'Set C', 'Set B', 'Set C', 'Set B', 'Set C', 
        'Set B', 'Set B', 'Set A', 'Set C', 'Set B', 'Set A'
        ]
colC = ['alpha', 'beta', 'delta', 'charlie', 'beta', 'delta', 'alpha', 
        'charlie', 'charlie', 'delta', 'delta', 'charlie', 'beta', 
        'delta', 'beta', 'charlie', 'alpha', 'charlie', 'delta', 'alpha'
        ]
df = pd.DataFrame(list(zip(id, colA, colB, colC)), columns =['id', 'colA', 'colB', 'colC'])
print(df)

    id    colA   colB     colC
0    1  type12  Set A    alpha
1    1  type11  Set B     beta
2    1  type11  Set B    delta
3    1  type11  Set B  charlie
4    2  type21  Set B     beta
5    2  type21  Set B    delta
6    2  type22  Set A    alpha
7    2  type23  Set B  charlie
8    2  type23  Set C  charlie
9    2  type23  Set C    delta
10   3  type31  Set B    delta
11   3  type31  Set C  charlie
12   3  type31  Set B     beta
13   3  type31  Set C    delta
14   4  type41  Set B     beta
15   4  type41  Set B  charlie
16   4  type42  Set A    alpha
17   4  type41  Set C  charlie
18   4  type41  Set B    delta
19   4  type43  Set A    alpha

期望输出

id  colA    colB           colC
1   type11  Set B          beta, delta, charlie
1   type12  Set A          alpha
2   type21  Set B          beta, delta
2   type22  Set A          alpha
2   type23  Set B, Set C   charlie, delta
3   type31  Set B, Set C   beta, delta, charlie
4   type41  Set B, Set C   beta, delta, charlie
4   type42  Set A          alpha
4   type43  Set A          alpha

仅尝试一列 returns 一个字符串但仍有重复项

df2 = df.groupby(['id', 'colA'])['colB'].apply(', '.join).reset_index()
print(df2)
   id    colA                        colB
0   1  type11         Set B, Set B, Set B
1   1  type12                       Set A
2   2  type21                Set B, Set B
3   2  type22                       Set A
4   2  type23         Set B, Set C, Set C
5   3  type31  Set B, Set C, Set B, Set C
6   4  type41  Set B, Set B, Set C, Set B
7   4  type42                       Set A
8   4  type43                       Set A

仅尝试删除重复的一列,但 returns 一组

df2 = df.groupby(['id', 'colA'])['colB'].apply(list).apply(set).reset_index()
print(df2)
   id    colA            colB
0   1  type11         {Set B}
1   1  type12         {Set A}
2   2  type21         {Set B}
3   2  type22         {Set A}
4   2  type23  {Set B, Set C}
5   3  type31  {Set B, Set C}
6   4  type41  {Set B, Set C}
7   4  type42         {Set A}
8   4  type43         {Set A}

您可以在 groupby 中使用 lambdadrop_duplicates 组内的Series 然后加入字符串。 agg 将适用于不是您的分组列的所有列,或指定一个子集。

df.groupby(['id', 'colA']).agg(lambda x: ', '.join(x.drop_duplicates())).reset_index()

   id    colA          colB                  colC
0   1  type11         Set B  beta, delta, charlie
1   1  type12         Set A                 alpha
2   2  type21         Set B           beta, delta
3   2  type22         Set A                 alpha
4   2  type23  Set B, Set C        charlie, delta
5   3  type31  Set B, Set C  delta, charlie, beta
6   4  type41  Set B, Set C  beta, charlie, delta
7   4  type42         Set A                 alpha
8   4  type43         Set A                 alpha

你很接近,只需进一步应用 list()join() 如下:

df2 = df.groupby(['id', 'colA']).apply(list).apply(set).apply(list).apply(', '.join).reset_index()

如果要使用 lambda 函数,请将其与 agg() 一起使用,如下所示:

df2 = df.groupby(['id', 'colA']).agg(lambda x: ', '.join(list(set(list(x))))).reset_index()



print(df2)

   id    colA          colB                  colC
0   1  type11         Set B  delta, charlie, beta
1   1  type12         Set A                 alpha
2   2  type21         Set B           delta, beta
3   2  type22         Set A                 alpha
4   2  type23  Set B, Set C        delta, charlie
5   3  type31  Set B, Set C  delta, charlie, beta
6   4  type41  Set B, Set C  delta, charlie, beta
7   4  type42         Set A                 alpha
8   4  type43         Set A                 alpha