Python:如何不用for循环将字典列表按日期分组求和?
问题
我有如下字典列表:
[ {'instrument_name': 'BTC-24FEB23-24000-C', 'index_price': 23822.86, 'direction': 'sell', 'amount': 0.5}, { 'instrument_name': 'BTC-30JUN23-40000-C', 'index_price': 23813.52, 'direction': 'sell', 'amount': 0.1}, { 'instrument_name': 'BTC-24FEB23-24000-C', 'index_price': 23812.99, 'direction': 'sell', 'amount': 6.0}, { 'instrument_name': 'BTC-26MAY23-18000-P', 'index_price': 23817.83, 'direction': 'buy', 'amount': 0.3} ]
希望按instrument_name拆分出的日期(通过instrument_date = instrument_name.split('-')[1]获取)分组,对amount字段求和,得到如下格式的结果:
{'24FEB23': 6.5, '30JUN23': 0.1, '26MAY23': 0.3}
请问除了使用for循环之外,是否有更优的实现方式?
更优实现方式
1. 用collections.defaultdict简化分组求和
这是Python标准库提供的高效工具,代码简洁且避免了手动判断键是否存在的冗余操作:
from collections import defaultdict data = [ {'instrument_name': 'BTC-24FEB23-24000-C', 'index_price': 23822.86, 'direction': 'sell', 'amount': 0.5}, {'instrument_name': 'BTC-30JUN23-40000-C', 'index_price': 23813.52, 'direction': 'sell', 'amount': 0.1}, {'instrument_name': 'BTC-24FEB23-24000-C', 'index_price': 23812.99, 'direction': 'sell', 'amount': 6.0}, {'instrument_name': 'BTC-26MAY23-18000-P', 'index_price': 23817.83, 'direction': 'buy', 'amount': 0.3} ] sum_by_date = defaultdict(float) for item in data: date = item['instrument_name'].split('-')[1] sum_by_date[date] += item['amount'] # 按需转换为普通字典 sum_by_date = dict(sum_by_date) print(sum_by_date)
虽然这里仍用到循环,但属于Python内置的优化实现,比手动维护普通字典的逻辑更高效易读。
2. 用itertools.groupby分组(需先排序)
如果可以接受先排序的开销,groupby能实现声明式的分组求和:
from itertools import groupby # groupby要求分组前数据按分组键连续排列,因此先排序 sorted_data = sorted(data, key=lambda x: x['instrument_name'].split('-')[1]) sum_by_date = {} for date, group in groupby(sorted_data, key=lambda x: x['instrument_name'].split('-')[1]): sum_by_date[date] = sum(item['amount'] for item in group) print(sum_by_date)
注意:排序会带来O(n log n)的时间复杂度,数据量较大时不如defaultdict高效。
3. 用pandas处理大规模数据
如果是处理大数据集,pandas的向量化操作性能远超纯Python实现,代码也更简洁:
import pandas as pd df = pd.DataFrame(data) # 提取日期字段 df['date'] = df['instrument_name'].str.split('-').str[1] # 分组求和并转为字典 sum_by_date = df.groupby('date')['amount'].sum().to_dict() print(sum_by_date)
pandas内部基于优化的C扩展实现,处理十万级以上数据时优势明显。
内容的提问来源于stack exchange,提问作者Madan
相关产品推荐
相关产品推荐

