《Python Cookbook(第3版)中文版》——1.15 根据字段将记录分组

简介:

本节书摘来自异步社区《Python Cookbook(第3版)中文版》一书中的第1章,第1.15节,作者[美]David Beazley , Brian K.Jones,陈舸 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.15 根据字段将记录分组

1.15.1 问题

有一系列的字典或对象实例,我们想根据某个特定的字段(比如说日期)来分组迭代数据。

1.15.2 解决方案

itertools.groupby()函数在对数据进行分组时特别有用。为了说明其用途,假设有如下的字典列表:

rows = [
    {'address': '5412 N CLARK', 'date': '07/01/2012'},
    {'address': '5148 N CLARK', 'date': '07/04/2012'},
    {'address': '5800 E 58TH', 'date': '07/02/2012'},
    {'address': '2122 N CLARK', 'date': '07/03/2012'},
    {'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
    {'address': '1060 W ADDISON', 'date': '07/02/2012'},
    {'address': '4801 N BROADWAY', 'date': '07/01/2012'},
    {'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
]

现在假设想根据日期以分组的方式迭代数据。要做到这些,首先以目标字段(在这个例子中是date)来对序列排序,然后再使用itertools.groupby()。

from operator import itemgetter
from itertools import groupby

# Sort by the desired field first
rows.sort(key=itemgetter('date'))

# Iterate in groups
for date, items in groupby(rows, key=itemgetter('date')):
    print(date)
    for i in items:
        print(' ', i)

这会产生如下的输出:

07/01/2012
     {'date': '07/01/2012', 'address': '5412 N CLARK'}
     {'date': '07/01/2012', 'address': '4801 N BROADWAY'}
07/02/2012
     {'date': '07/02/2012', 'address': '5800 E 58TH'}
     {'date': '07/02/2012', 'address': '5645 N RAVENSWOOD'}
     {'date': '07/02/2012', 'address': '1060 W ADDISON'}
07/03/2012
     {'date': '07/03/2012', 'address': '2122 N CLARK'}
07/04/2012
     {'date': '07/04/2012', 'address': '5148 N CLARK'}
     {'date': '07/04/2012', 'address': '1039 W GRANVILLE'}

1.15.3 讨论

函数groupby()通过扫描序列找出拥有相同值(或是由参数key指定的函数所返回的值)的序列项,并将它们分组。groupby()创建了一个迭代器,而在每次迭代时都会返回一个值(value)和一个子迭代器(sub_iterator),这个子迭代器可以产生所有在该分组内具有该值的项。

在这里重要的是首先要根据感兴趣的字段对数据进行排序。因为groupby()只能检查连续的项,不首先排序的话,将无法按所想的方式来对记录分组。

如果只是简单地根据日期将数据分组到一起,放进一个大的数据结构中以允许进行随机访问,那么利用defaultdict()构建一个一键多值字典(multidict,见1.6节)可能会更好。例如:

from collections import defaultdict
rows_by_date = defaultdict(list)
for row in rows:
    rows_by_date[row['date']].append(row)

这使得我们可以方便地访问每个日期的记录,如下所示:

>>> for r in rows_by_date['07/01/2012']:
...      print(r)
...
{'date': '07/01/2012', 'address': '5412 N CLARK'}
{'date': '07/01/2012', 'address': '4801 N BROADWAY'}
>>>

对于后面这个例子,我们并不需要先对记录做排序。因此,如果不考虑内存方面的因素,这种方式会比先排序再用groupby()迭代要来的更快。

相关文章
|
3月前
|
存储 安全 网络协议
Python 教程之 Django(9)对模型中的字段进行验证
Python 教程之 Django(9)对模型中的字段进行验证
30 0
Python 教程之 Django(9)对模型中的字段进行验证
|
5月前
|
Python
136 python高级 - 正则表达式(匹配分组)
136 python高级 - 正则表达式(匹配分组)
27 0
|
3月前
|
C++ Java 容器
【Java每日一练】总目录(2023.3.11~5.18)共69篇
【Java每日一练】总目录(2023.3.11~5.18)共69篇
165 0
【Java每日一练】总目录(2023.3.11~5.18)共69篇
|
29天前
|
数据可视化 Python
如何使用Python的Pandas库进行数据分组和聚合操作?
【2月更文挑战第29天】【2月更文挑战第105篇】如何使用Python的Pandas库进行数据分组和聚合操作?
|
3月前
|
算法 Python C++
C/C++每日一练(20230425) 成绩分布、汇总区间、矩阵置零
C/C++每日一练(20230425) 成绩分布、汇总区间、矩阵置零
34 0
C/C++每日一练(20230425) 成绩分布、汇总区间、矩阵置零
|
3月前
|
数据采集 Serverless Python
Python代码示例:数据清洗、表合并和分组计算销售额
Python代码示例:数据清洗、表合并和分组计算销售额
29 1
|
4月前
|
存储 定位技术 数据格式
Python中ArcPy读取Excel表格数据创建矢量要素图层并生成属性表字段与内容
Python中ArcPy读取Excel表格数据创建矢量要素图层并生成属性表字段与内容
|
4月前
|
存储 数据库 Python
Python 教程之 Django(9)对模型中的字段进行验证
Python 教程之 Django(9)对模型中的字段进行验证
37 0
|
6月前
|
数据挖掘 索引 Python
【100天精通Python】Day57:Python 数据分析_Pandas数据描述性统计,分组聚合,数据透视表和相关性分析
【100天精通Python】Day57:Python 数据分析_Pandas数据描述性统计,分组聚合,数据透视表和相关性分析
51 0
|
9月前
|
Python
Python 获得对象的字段列表
Python 获得对象的字段列表
73 0

热门文章

最新文章