那么是否有一种方法可以对一个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)
为每一列做这个,然后将它们连接起来,但是如果列表很长,那么是否有更短的更优雅的解决方案?
您可以使用groupby的聚合函数。此外,您还必须重置索引。
df_data = df.groupby(['Name', 'Date']).aggregate(lambda x: list(x)).reset_index()
Pandas从未被设计为以系列/列的形式保存列表。您可以编制昂贵的解决方法,但不建议这样做。
建议不要使用串联保持列表的主要原因是丢失了矢量化功能,这与使用连续内存块中保存的NumPy数组有关。你的系列将是object
dtype,它代表一系列指针,很像list
。
当然,object
dtype对于混合类型是不可避免的。但是,在这里,嵌套指针结构使效果更加复杂。您将失去内存和性能方面的优势,以及访问优化的Pandas方法。
您可以聚合到字符串,这样您只有一个指针级别:
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