218 lines
5.8 KiB
Markdown
218 lines
5.8 KiB
Markdown
---
|
|
doc_type: short
|
|
full_text: sources/05_Collections.md
|
|
---
|
|
|
|
# 05_Collections 总结
|
|
|
|
本文介绍 Python 标准库 `collections` 模块中几个常用的数据处理工具,重点包括 `Counter`、`defaultdict` 和 `deque`,展示它们如何简化计数、分组索引和保留有限历史记录等任务。相关主题可延伸为 Python标准库、[[concepts/数据计数与汇总]]、字典与映射、序列与队列。
|
|
|
|
## 核心主题
|
|
|
|
`collections` 模块提供了多种专门的数据结构,适合处理常见但用普通 `dict`、`list` 实现会显得繁琐的数据管理问题。
|
|
|
|
本文重点场景包括:
|
|
|
|
- 统计每只股票的总持仓数量
|
|
- 将一个键映射到多个值
|
|
- 保存最近 N 条历史记录
|
|
|
|
## 使用 `Counter` 进行计数与汇总
|
|
|
|
当需要统计某类对象的累计数量时,可以使用 `collections.Counter`。
|
|
|
|
示例数据中,同一只股票可能出现多次:
|
|
|
|
```python
|
|
portfolio = [
|
|
('GOOG', 100, 490.1),
|
|
('IBM', 50, 91.1),
|
|
('CAT', 150, 83.44),
|
|
('IBM', 100, 45.23),
|
|
('GOOG', 75, 572.45),
|
|
('AA', 50, 23.15)
|
|
]
|
|
```
|
|
|
|
如果希望计算每只股票的总股数,可以创建一个空的 `Counter`,然后逐项累加:
|
|
|
|
```python
|
|
from collections import Counter
|
|
|
|
total_shares = Counter()
|
|
for name, shares, price in portfolio:
|
|
total_shares[name] += shares
|
|
```
|
|
|
|
这样,重复出现的股票名会被合并到同一个计数项中。例如:
|
|
|
|
```python
|
|
total_shares['IBM']
|
|
```
|
|
|
|
结果为:
|
|
|
|
```python
|
|
150
|
|
```
|
|
|
|
这说明 `IBM` 的两条记录被汇总为总股数 150。
|
|
|
|
## `Counter` 的字典行为与排序功能
|
|
|
|
`Counter` 可以像普通字典一样通过键访问值:
|
|
|
|
```python
|
|
holdings['IBM']
|
|
holdings['MSFT']
|
|
```
|
|
|
|
同时,它还提供了计数对象常用的额外方法。例如,可以使用 `most_common()` 获取持仓数量最多的股票:
|
|
|
|
```python
|
|
holdings.most_common(3)
|
|
```
|
|
|
|
返回结果类似:
|
|
|
|
```python
|
|
[('MSFT', 250), ('IBM', 150), ('CAT', 150)]
|
|
```
|
|
|
|
这使得 `Counter` 不仅适合做统计,也适合做排名和频率分析。
|
|
|
|
## 合并多个 `Counter`
|
|
|
|
`Counter` 支持直接相加,这对合并多个数据源中的统计结果非常方便。
|
|
|
|
例如有两个投资组合:
|
|
|
|
```python
|
|
combined = holdings + holdings2
|
|
```
|
|
|
|
合并后,相同股票的股数会自动相加:
|
|
|
|
```python
|
|
Counter({'MSFT': 275, 'HPQ': 250, 'GE': 220, 'AA': 150, 'IBM': 150, 'CAT': 150})
|
|
```
|
|
|
|
这体现了 `Counter` 在数据汇总、聚合和表格化统计中的优势。
|
|
|
|
## 使用 `defaultdict` 处理一对多映射
|
|
|
|
当一个键需要关联多个值时,普通字典需要手动检查键是否存在,而 `defaultdict` 可以自动为新键创建默认值。
|
|
|
|
示例:将股票名称映射到该股票的所有交易记录:
|
|
|
|
```python
|
|
from collections import defaultdict
|
|
|
|
holdings = defaultdict(list)
|
|
for name, shares, price in portfolio:
|
|
holdings[name].append((shares, price))
|
|
```
|
|
|
|
访问 `IBM` 时会得到它对应的多条记录:
|
|
|
|
```python
|
|
holdings['IBM']
|
|
```
|
|
|
|
结果:
|
|
|
|
```python
|
|
[(50, 91.1), (100, 45.23)]
|
|
```
|
|
|
|
`defaultdict(list)` 的作用是:当访问一个不存在的键时,自动创建一个空列表作为默认值,因此可以直接调用 `.append()`。
|
|
|
|
这类模式常用于:
|
|
|
|
- 分组数据
|
|
- 建立索引
|
|
- 一对多映射
|
|
- 按类别聚合记录
|
|
|
|
相关概念可连接到 字典与映射 和 数据分组。
|
|
|
|
## 使用 `deque` 保存有限历史记录
|
|
|
|
如果需要保存最近 N 个元素,可以使用 `collections.deque`。
|
|
|
|
示例:保存文件处理中最近 N 行内容:
|
|
|
|
```python
|
|
from collections import deque
|
|
|
|
history = deque(maxlen=N)
|
|
with open(filename) as f:
|
|
for line in f:
|
|
history.append(line)
|
|
...
|
|
```
|
|
|
|
当设置 `maxlen=N` 后,`deque` 会自动维持固定长度。新元素加入时,如果超过最大长度,最旧的元素会被自动丢弃。
|
|
|
|
这适合用于:
|
|
|
|
- 最近历史记录
|
|
- 滑动窗口
|
|
- 日志尾部追踪
|
|
- 流式数据处理
|
|
|
|
相关主题可扩展为 序列与队列、滑动窗口。
|
|
|
|
## 练习 2.18:使用 `Counter` 表格化统计
|
|
|
|
练习要求在交互模式中运行 `report.py`,加载股票投资组合数据:
|
|
|
|
```bash
|
|
python3 -i report.py
|
|
```
|
|
|
|
然后使用 `read_portfolio('Data/portfolio.csv')` 读取投资组合,并通过 `Counter` 汇总每只股票的持仓总数:
|
|
|
|
```python
|
|
from collections import Counter
|
|
|
|
holdings = Counter()
|
|
for s in portfolio:
|
|
holdings[s['name']] += s['shares']
|
|
```
|
|
|
|
结果示例:
|
|
|
|
```python
|
|
Counter({'MSFT': 250, 'IBM': 150, 'CAT': 150, 'AA': 100, 'GE': 95})
|
|
```
|
|
|
|
该练习强调:当原始数据中同一股票有多条记录时,`Counter` 可以自然地将这些记录合并为单个统计项。
|
|
|
|
随后练习又读取第二个投资组合 `portfolio2.csv`,创建另一个 `Counter`,并用加法合并两个统计结果。
|
|
|
|
## 关键收获
|
|
|
|
- `collections` 是 Python 中非常实用的标准库模块,适合处理专门的数据管理问题。
|
|
- `Counter` 用于计数、汇总、排名和合并统计结果。
|
|
- `defaultdict` 用于简化默认值处理,尤其适合一对多映射和分组。
|
|
- `deque` 适合保存固定长度的历史记录或实现队列类数据结构。
|
|
- 遇到表格化统计、索引构建、分组聚合等问题时,应优先考虑 `collections` 模块。
|
|
|
|
## 延伸阅读方向
|
|
|
|
本文最后指出,`collections` 模块内容丰富,值得后续深入学习。除了本文介绍的 `Counter`、`defaultdict` 和 `deque`,该模块还包含其他有用工具,可作为 Python 数据结构和标准库学习的重要部分。
|
|
|
|
## Related Concepts
|
|
- [[concepts/队列与滑动窗口]]
|
|
- [[concepts/Python-容器]]
|
|
- [[concepts/字典与数据建模]]
|
|
- [[concepts/列表与序列]]
|
|
- [[concepts/模块与-import]]
|
|
- [[concepts/元组与解包]]
|
|
- [[concepts/Python-交互式解释器]]
|
|
- [[concepts/文件读写]]
|
|
- [[concepts/上下文管理器]]
|
|
- [[concepts/迭代协议与生成器]]
|
|
- [[concepts/CSV-数据处理]]
|