はじめに
collections モジュールは、データ処理に便利なオブジェクトを多数提供しています。このセクションでは、その一部の機能について簡単に紹介します。
例:物の数え上げ
各銘柄の総株数を集計したいとしましょう。
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)
]
このリストには、IBM のエントリが 2 つ、GOOG のエントリが 2 つあります。株数を何らかの方法で合算する必要があります。
カウンター
解決策:Counter を使用します。
from collections import Counter
total_shares = Counter()
for name, shares, price in portfolio:
total_shares[name] += shares
total_shares['IBM'] ## 150
例:1 対多のマッピング
問題:キーを複数の値にマッピングしたい。
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)
]
前の例と同様に、キー IBM は代わりに 2 つの異なるタプルを持つはずである。
解決策:defaultdict を使用する。
from collections import defaultdict
holdings = defaultdict(list)
for name, shares, price in portfolio:
holdings[name].append((shares, price))
holdings['IBM'] ## [ (50, 91.1), (100, 45.23) ]
defaultdict は、キーにアクセスするたびにデフォルト値を取得できるようにします。
例:履歴の保持
問題:最後の N 件の履歴を保持したい。解決策:deque を使用する。
from collections import deque
history = deque(maxlen=N)
with open(filename) as f:
for line in f:
history.append(line)
...
collections モジュールは、集計やインデックス付けなどの特殊な目的のデータ処理問題を扱う際に最も便利なライブラリモジュールの 1 つかもしれません。
この演習では、いくつかの簡単な例を見てみましょう。まず、report.py プログラムを実行して、対話型モードで株式のポートフォリオを読み込んでください。
$ python3 -i report.py
演習 2.18:カウンターを使った集計
各銘柄の株式の総数を集計したいとしましょう。Counter オブジェクトを使うとこれは簡単です。試してみましょう:
>>> portfolio = read_portfolio('portfolio.csv')
>>> from collections import Counter
>>> holdings = Counter()
>>> for s in portfolio:
holdings[s['name']] += s['shares']
>>> holdings
Counter({'MSFT': 250, 'IBM': 150, 'CAT': 150, 'AA': 100, 'GE': 95})
>>>
portfolio にある MSFT と IBM の複数のエントリがここで単一のエントリにどのように結合されるかを注意深く観察してください。
個々の値を取得するためには、辞書と同じように Counter を使うことができます:
>>> holdings['IBM']
150
>>> holdings['MSFT']
250
>>>
値をランキング付けしたい場合は、次のようにします:
>>> ## 保有株数が最も多い銘柄トップ 3 を取得
>>> holdings.most_common(3)
[('MSFT', 250), ('IBM', 150), ('CAT', 150)]
>>>
別の株式のポートフォリオを取得して新しい Counter を作成しましょう:
>>> portfolio2 = read_portfolio('portfolio2.csv')
>>> holdings2 = Counter()
>>> for s in portfolio2:
holdings2[s['name']] += s['shares']
>>> holdings2
Counter({'HPQ': 250, 'GE': 125, 'AA': 50, 'MSFT': 25})
>>>
最後に、すべての保有株を 1 つの簡単な操作で結合しましょう:
>>> holdings
Counter({'MSFT': 250, 'IBM': 150, 'CAT': 150, 'AA': 100, 'GE': 95})
>>> holdings2
Counter({'HPQ': 250, 'GE': 125, 'AA': 50, 'MSFT': 25})
>>> combined = holdings + holdings2
>>> combined
Counter({'MSFT': 275, 'HPQ': 250, 'GE': 220, 'AA': 150, 'IBM': 150, 'CAT': 150})
>>>
これは Counter が提供する機能の一部にすぎません。ただし、値を集計する必要がある場合、Counter を使うことを検討する必要があります。
解説:collections モジュール
collections モジュールは、Python 全体で最も便利なライブラリモジュールの 1 つです。実際、それだけに関する拡張チュートリアルを行うこともできます。しかし、今そうすることはまた、注意力を分散させることにもなります。今のところ、collections を後で寝る前の読書リストに入れておきましょう。
まとめ
おめでとうございます!あなたはコレクションモジュールの実験を完了しました。あなたのスキルを向上させるために、LabEx でさらに実験を行って練習することができます。