如何将包含列表值的列的多个DataFrame行合并为一个?

3

我有一个类似这样的 DataFrame:

| cat0  | cat1 | cat2 | col_list  | Quantity |
| ----- | ---- | ---- | ----------| -------- |
| alpha | x    | a    | [a,b,c,d] | 4        |
| alpha | y    | a    | [e]       | 1        |
| beta  | z    | a    | [f,g]     | 2        |
| gamma | p    | b    | [h]       | 1        |
| gamma | q    | b    | [I,j,k,l] | 4        |
| phi   | r    | c    | [r,s]     | 2        |
| eita  | s    | c    | [m,n]     | 2        |

我希望根据cat2列来进行转换。如果它们有相同的值,则将这些行合并为1行,并将行合并如下:
| cat0       | cat1  | cat2 | col_list        | Quantity |
| ---------- | ----- | ---- | ----------------| -------- |
| alpha,beta | x,y,z | a    | [a,b,c,d,e,f,g] | 7        |
| gamma      | p,q   | b    | [h,I,j,k,l]     | 5        |
| phi,eita   | r,s   | c    | [r,s,m,n]       | 4        |

如果列具有字符串值(列:cat0,cat1),请使用逗号将它们连接并分隔。如果它具有列表值(列“col_list”),则将这些元素添加到单个列表中。如果它是一个整数值(列:Quantity),那么只需将它们相加即可。

2个回答

2

您可以使用 groupby.agg 方法,结合 list/','.joinsumitertools.chain 实现:

from itertools import chain

(df
 .groupby('cat2', as_index=False)
 .agg({'cat0': ','.join, 'cat1': ','.join,
       'col_list': lambda x: list(chain.from_iterable(x)),
       'Quantity': 'sum'
       })
 [df.columns] # reindex like original
)

NB.在place或chain中,您也可以使用:lambda x: [v for l in x for x in l]

输出:

               cat0   cat1 cat2               col_list  Quantity
0  alpha,alpha,beta  x,y,z    a  [a, b, c, d, e, f, g]         7
1       gamma,gamma    p,q    b        [h, I, j, k, l]         5
2          phi,eita    r,s    c           [r, s, m, n]         4

谢谢@mozway。我一直在使用groupby.agg,但是无法得到正确的规则集。我需要学习更好地使用它。非常方便。唯一的问题是 - 我是否可以避免cat0和cat1成为列表?只需将它们作为逗号分隔的字符串即可。 - trojan horse
我尝试使用 str 替代 list,但是对于一些整数值(这些值是行的索引),我会获得额外的 \n。 - trojan horse
当然,你可以使用 ','.join 替代 list - mozway

2
你可以在使用 pandas.groupby 后使用 agg,并使用 functools.reduce 将多个列表合并,','.join 用于将字符串用逗号分隔合并。
>>> from functools import reduce
>>> df.groupby('cat2').agg({'cat0': ','.join, 
                        'cat1': ','.join,
                        'col_list' : lambda x: reduce(lambda y,z : y+z, x),
                        'Quantity' : 'sum'})


cat0          cat1    cat2    col_list         Quantity 
alpha,beta    x,y,z   a       [a,b,c,d,e,f,g]  7
gamma         p,q     b       [h,I,j,k,l]      5
phi,eita      r,s     c       [r,s,m,n]        4

解释:(如何减少合并多个列表的次数?)

>>> reduce(lambda y,z : y+z, [['a','b','c','d'], ['e'], ['f','g']])
# y <- (['a','b','c','d'] + ['e'])
# y + ['f','g']
['a', 'b', 'c', 'd', 'e', 'f', 'g']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接