如何优雅地对数据进行分组?

简介: 如何优雅地对数据进行分组?

假设我们有这样一种数据:

data = [
    ("apple", 30), ("apple", 35),
    ("apple", 32), ("pear", 60),
    ("pear", 32), ("pear", 60),
    ("banana", 102), ("banana", 104)
]
# 我们希望变成如下格式
"""
[('apple', [30, 35, 32]), 
 ('pear', [60, 32, 60]), 
 ('banana', [102, 104])]
"""

如果是你的话,你会怎么做呢?很容易想到的一种解决方案是构造一个字典:

data = [
    ("apple", 30), ("apple", 35),
    ("apple", 32), ("pear", 60),
    ("pear", 32), ("pear", 60),
    ("banana", 102), ("banana", 104)
]
data_dict = {}
for name, count in data:
    if name not in data_dict:
        data_dict[name] = []
    data_dict[name].append(count)
print(data_dict)
"""
{'apple': [30, 35, 32], 
 'pear': [60, 32, 60], 
 'banana': [102, 104]}
"""
print(list(data_dict.items()))
"""
[('apple', [30, 35, 32]), 
 ('pear', [60, 32, 60]), 
 ('banana', [102, 104])]
"""

这种方案完全没有问题,不过我们还可以写的更优雅一些,也就是使用字典的 setdefault 方法:

data = [
    ("apple", 30), ("apple", 35),
    ("apple", 32), ("pear", 60),
    ("pear", 32), ("pear", 60),
    ("banana", 102), ("banana", 104)
]
data_dict = {}
for name, count in data:
    # setdefault(k, v) 含义如下
    # 当 k 不存在时,将 k: v 设置在字典中,并返回 v
    # 当 k 存在时,直接返回 k 对应值
    data_dict.setdefault(name, []).append(count)
print(list(data_dict.items()))
"""
[('apple', [30, 35, 32]), 
 ('pear', [60, 32, 60]), 
 ('banana', [102, 104])]
"""

setdefault 是一个非常方便的方法,但是使用频率却不怎么高,或者说该方法不太让人喜欢。主要是每次调用都要给一个初始值,比如代码中的空列表 []。另外这里的初始值可以任意,如果你希望添加的时候还能实现去重效果,那么就将空列表换成空集合即可。


或者我们还可以使用 defaultdict,它位于 collections 模块中。

from collections import defaultdict
data = [
    ("apple", 30), ("apple", 35),
    ("apple", 32), ("pear", 60),
    ("pear", 32), ("pear", 60),
    ("banana", 102), ("banana", 104)
]
# 里面接收一个 callable
# 当访问的 k 不存在时,返回 callable 调用之后的值
data_dict1 = defaultdict(list)
for name, count in data:
    data_dict1[name].append(count)
print(list(data_dict1.items()))
"""
[('apple', [30, 35, 32]), 
 ('pear', [60, 32, 60]), 
 ('banana', [102, 104])]
"""
# 也可以指定为 set
data_dict2 = defaultdict(set)
for name, count in data:
    data_dict2[name].add(count)
print(list(data_dict2.items()))
"""
[('apple', {32, 35, 30}), 
 ('pear', {32, 60}), 
 ('banana', {104, 102})]
"""

总的来说,defaultdict 和字典的 setdefault 方法非常类似,我们使用 setdefault 即可。


当然啦,关于分组,还有一种特殊情况,就是词频统计。假设我们想统计可迭代对象中,每个元素出现的次数该怎么做呢?

data = ["apple", "apple", "apple",
        "pear", "pear", "pear",
        "banana", "banana"]
data_dict = {}
for item in data:
    # 此处不能使用 setdefault,因为它是函数
    # .setdefault(item, 0) += 1 是不符合语法规则的
    if item not in data_dict:
        data_dict[item] = 0
    data_dict[item] += 1
print(data_dict)
"""
{'apple': 3, 'pear': 3, 'banana': 2}
"""
# 或者使用 defaultdict
from collections import defaultdict
data_dict = defaultdict(int)
for item in data:
    data_dict[item] += 1
print(data_dict)
"""
defaultdict(<class 'int'>, 
            {'apple': 3, 'pear': 3, 'banana': 2})
"""

然而说到词频统计,我们还可以使用 collections 下的 Counter 类。

from collections import Counter
data = ["apple", "apple", "apple",
        "pear", "pear", "pear",
        "banana", "banana"]
data_dict = Counter(data)
# 直接搞定,Counter 已经包含了我们之前的逻辑
print(data_dict)
"""
Counter({'apple': 3, 'pear': 3, 'banana': 2})
"""
# Counter 继承 dict,除了支持字典操作之外
# 还提供了很多其它操作,其中一个就是 most_common
# 用于选择出现频率最高的几个元素
print(data_dict.most_common(2))
"""
[('apple', 3), ('pear', 3)]
"""

还是很简单的。

目录
打赏
0
0
0
0
75
分享
相关文章
分组元素
分组元素。
71 3
分组和聚合DataFrame信息案例解析
该文介绍了如何使用pandas对DataFrame进行分组和聚合操作。首先,通过创建字典并转换为DataFrame,展示了基础数据结构。接着,利用`groupby()`方法按城市字段进行数据分组,然后应用`mean()`函数计算各城市平均年龄,显示了聚合功能。此外,文中指出还可使用`sum()`、`count()`等其他聚合函数处理分组数据。
106 0
详解如何优雅实现先分组再组内排序取数据解决方案
本文介绍了在数据库查询中常见的业务需求:先对数据进行分组,然后在每组内按规则排序并取出特定记录。使用MySQL和Elasticsearch实现这一操作,并对比了不同方法的性能。具体包括: **MySQL实现**:通过窗口函数`ROW_NUMBER()`、子查询和JOIN关联查询三种方式实现分组排序取数据,并探讨了索引优化的效果。 **Elasticsearch实现**:利用`terms`聚合和`top_hits`聚合实现分组排序,适用于大规模数据场景。 推荐优先使用窗口函数,结合索引优化提升查询性能。对于小规模查询,可在应用层处理。 通过实例和性能对比,帮助读者选择最适合的实现方案。
104 16
详解如何优雅实现先分组再组内排序取数据解决方案
|
11月前
|
BI
【Databend】分组集:教你如何快速分组汇总
【Databend】分组集:教你如何快速分组汇总
76 2
45jqGrid 分组 - 数组数据的简单分组
45jqGrid 分组 - 数组数据的简单分组
60 0
分组
GROUP BY 语句根据一个或多个列对结果集进行分组。
分组分类的查询与保存
分组分类的查询与保存
182 0
分组分类的查询与保存
数据的分组与计算
对数据集进行分组并对各组应用一个函数(无论是聚合还是转换),通常是数据分析工作中的重要环节。在数据集准备好之后,通常就是计算分组统计或生成透视表。pandas 提供了一个灵活高效的 groupby 功能,使我们可以高效地对数据集进行操作。 关系型数据库和 SQL 能够如此流行的原因之一就是其能够方便地对数据进行连接、过滤、转换和聚合。但是,像 SQL 这样的查询语言所能执行的分组运算的种类很有限,而由于 pandas 强大的表达能力,我们可以执行复杂得多的分组运算。
176 0
按照A列进行分组并计算出B列每个分组的平均值,然后对B列内的每个元素减去分组平均值
按照A列进行分组并计算出B列每个分组的平均值,然后对B列内的每个元素减去分组平均值
246 0
按照A列进行分组并计算出B列每个分组的平均值,然后对B列内的每个元素减去分组平均值

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等