脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - 一文详解Python如何优雅地对数据进行分组

一文详解Python如何优雅地对数据进行分组

2022-07-14 13:32Python技术大本营 Python

这篇文章主要和大家详细介绍一下Python是如何优雅地对数据进行分组的,文中通过示例进行了详细的讲解,感兴趣的小伙伴可以跟随小编一起学习一下

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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])]
"""

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 模块中。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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 即可。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 类。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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)]
"""

还是很简单的。

到此这篇关于一文详解Python如何优雅地对数据进行分组的文章就介绍到这了,更多相关Python数据分组内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://segmentfault.com/a/1190000042098698

延伸 · 阅读

精彩推荐
  • PythonPython list列表中删除多个重复元素操作示例

    Python list列表中删除多个重复元素操作示例

    这篇文章主要介绍了Python list列表中删除多个重复元素操作,结合实例形式分析了Python删除list列表重复元素的相关操作技巧与注意事项,需要的朋友可以参考...

    tomato_guo7522021-06-03
  • PythonPython中用max()方法求最大值的介绍

    Python中用max()方法求最大值的介绍

    这篇文章主要介绍了Python中用max()方法求最大值的介绍,是Python入门中的基础知识,需要的朋友可以参考下...

    Python教程网16882020-06-28
  • PythonPython中的二维数组实例(list与numpy.array)

    Python中的二维数组实例(list与numpy.array)

    下面小编就为大家分享一篇Python中的二维数组实例(list与numpy.array),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    Feng某人13612021-01-31
  • Pythonpython3 kmp 字符串匹配的方法

    python3 kmp 字符串匹配的方法

    这篇文章主要介绍了python3 kmp 字符串匹配的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    7749ha11302021-03-14
  • Python使用python获取(宜宾市地震信息)地震信息

    使用python获取(宜宾市地震信息)地震信息

    今天这个项目用到了Python的爬虫知识,没有用大家讨厌的正则表达式,而是用一种新的方式解析库,实现对HTML的解析和提取信息,最后又用到前面项目用过...

    stormwen5582021-07-16
  • PythonPython 多线程之threading 模块的使用

    Python 多线程之threading 模块的使用

    这篇文章主要介绍了Python 多线程之threading 模块的使用,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...

    HLee3802021-10-09
  • Pythonpython代码过长的换行方法

    python代码过长的换行方法

    今天小编就为大家分享一篇python代码过长的换行方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    codechelle17072021-03-19
  • Pythonnumpy的sum函数的axis和keepdim参数详解

    numpy的sum函数的axis和keepdim参数详解

    这篇文章主要介绍了numpy的sum函数的axis和keepdim参数详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友...

    油炸冰淇凌11762021-09-19