itertools.groupby() / itertools.starmap() / itertools.accumulate()
| 対応: | groupby() / starmap() | Python 2(2000) |
|---|---|---|
| accumulate() | Python 3.2(2011) |
『itertools.groupby()』は連続する同じキーを持つ要素をグループ化します。『itertools.starmap()』は引数をアンパックしてマッピングし、『itertools.accumulate()』は累積計算を行います。groupby()はソート済みのデータに対して使うことが前提で、連続する同じキーの要素のみをグループ化します。
構文
import itertools # グループ化 itertools.groupby(iterable, key=None) # 引数をアンパックしてマッピング itertools.starmap(function, iterable) # 累積計算 itertools.accumulate(iterable, func=operator.add, initial=None)
関数一覧
| 関数 | 概要 |
|---|---|
| groupby(iterable, key) | 連続する同じキーの要素をグループ化してイテレータを返す。 |
| starmap(func, iterable) | iterableの各要素をアンパックしてfuncに渡した結果のイテレータを返す。 |
| accumulate(iterable, func) | 累積計算の結果を返す。funcを省略すると累積和になる。 |
サンプルコード
sample_itertools_groupby.py
import itertools
import operator
# groupby: グループ化(事前ソートが必要)
data = [
{'name': '桐生一馬', 'org': '堂島組'},
{'name': '真島吾朗', 'org': '堂島組'},
{'name': '秋山駿', 'org': 'スカイファイナンス'},
{'name': '錦山彰', 'org': 'スカイファイナンス'},
{'name': '冴島大河', 'org': '堂島組'}, # ← ソートしていないので別グループになる
]
# 所属でソートしてからグループ化
sorted_data = sorted(data, key=lambda x: x['org'])
for dept, members in itertools.groupby(sorted_data, key=lambda x: x['org']):
names = [m['name'] for m in members]
print(f"{dept}: {names}")
# スカイファイナンス: ['秋山駿', '錦山彰']
# 堂島組: ['桐生一馬', '真島吾朗', '冴島大河']
# groupby: 文字列の連続する同じ文字をグループ化
for char, group in itertools.groupby('AAABBCCDD'):
print(char, list(group))
# A ['A', 'A', 'A']
# B ['B', 'B']
# C ['C', 'C']
# D ['D', 'D']
# starmap: タプルのリストをアンパックして関数に渡す
pairs = [(2, 3), (4, 2), (10, 3)]
result = list(itertools.starmap(pow, pairs))
print(result) # [8, 16, 1000](2^3, 4^2, 10^3)
# accumulate: 累積和
nums = [1, 2, 3, 4, 5]
acc_sum = list(itertools.accumulate(nums))
print(acc_sum) # [1, 3, 6, 10, 15]
# accumulate: 累積積
acc_prod = list(itertools.accumulate(nums, operator.mul))
print(acc_prod) # [1, 2, 6, 24, 120](1!, 2!, 3!, 4!, 5!)
# accumulate: 累積最大値
nums2 = [3, 1, 4, 1, 5, 9, 2, 6]
acc_max = list(itertools.accumulate(nums2, max))
print(acc_max) # [3, 3, 4, 4, 5, 9, 9, 9]
python3 itertools_groupby.py スカイファイナンス: ['秋山駿', '錦山彰'] 堂島組: ['桐生一馬', '真島吾朗', '冴島大河'] A ['A', 'A', 'A'] B ['B', 'B'] C ['C', 'C'] D ['D', 'D'] [8, 16, 1000] [1, 3, 6, 10, 15] [1, 2, 6, 24, 120] [3, 3, 4, 4, 5, 9, 9, 9]
概要
『groupby()』はSQLのGROUP BYに似た機能ですが、連続する要素のみをグループ化するため、必ず事前にソートしておく必要があります。groupbyは連続する同じキーの要素をグループ化します。事前にソートしないと、同じキーが離れた位置にある場合に別グループとして扱われます。グループのイテレータは次のグループに移動すると使えなくなるため、必要であれば事前にlist()で変換しておきましょう。
『starmap()』はmap()と似ていますが、各要素がタプルの場合に関数への引数として展開(アンパック)して渡します。map(func, zip(a, b))のような記述をより簡潔に書けます。
『accumulate()』はPython 3.3以降ではfuncを指定でき、Python 3.8以降ではinitialパラメータで初期値を設定できます。累積和・累積積・ランニングmaxなど様々な集計処理に活用できます。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。