pandas相当于使用STRING_AGG分组的几个列

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

那么是否有一种方法可以对一个DataFrame对象进行groupBy,然后对于其余的列,将所有条目放入一个集合(或带有过滤的唯一值的列表)。所以这样的事情

   Name        Date  Amount   purchase
0  Jack  2016-01-31      10    'apple'
1  Jack  2016-02-29       5        25
2  Jack  2016-02-29       8       'B+'
3  Jill  2016-01-31      10       'D2'
4  Jill  2016-02-29       5         E
4  Jill  2016-02-29       5         E

在前两列分组后输出。

    Name        Date  Amount     purchase
 0  Jack  2016-01-31     [10]     [apple]
 1  Jack  2016-02-29    [5,8]   [25,'B+']
 3  Jill  2016-01-31     [10]      ['D2']
 4  Jill  2016-02-29      [5]       ['E']

所以我可以用df_data = df.groupby(['Name', 'Date'])['Amount'].apply(set)为每一列做这个,然后将它们连接起来,但是如果列表很长,那么是否有更短的更优雅的解决方案?

python pandas aggregate apply group-concat
2个回答
1
投票

您可以使用groupby的聚合函数。此外,您还必须重置索引。

df_data = df.groupby(['Name', 'Date']).aggregate(lambda x: list(x)).reset_index()

0
投票

Don't do this

Pandas从未被设计为以系列/列的形式保存列表。您可以编制昂贵的解决方法,但不建议这样做。

建议不要使用串联保持列表的主要原因是丢失了矢量化功能,这与使用连续内存块中保存的NumPy数组有关。你的系列将是object dtype,它代表一系列指针,很像list

当然,object dtype对于混合类型是不可避免的。但是,在这里,嵌套指针结构使效果更加复杂。您将失去内存和性能方面的优势,以及访问优化的Pandas方法。


A slightly better alternative

您可以聚合到字符串,这样您只有一个指针级别:

res = df.groupby(['Name', 'Date'], as_index=False)[['Amount', 'purchase']]\
        .agg(lambda x: ', '.join(map(str, set(x))))

print(res)

   Name        Date Amount  purchase
0  Jack  2016-01-31     10   'apple'
1  Jack  2016-02-29   8, 5  'B+', 25
2  Jill  2016-01-31     10      'D2'
3  Jill  2016-02-29      5         E
© www.soinside.com 2019 - 2024. All rights reserved.