dictionary繋がりでdictionaryとcollections.Counter()の整理(2/14:タイトル変更しました)
要素数を数える
例えば、文字”lkfjaslfkjalg;km,:hearnr”を含むtxがあり、txが含む要素の数はそれぞれ幾つか数えたい場合、dictionaryを使う事で数える事が可能。
>>> tx = "lkfjaslfkjalg;km,: h:s;klg eoj@eh1-earnr" >>> ct = {} >>> for i in tx: ... if i in ct: ... ct[i] += 1 ... else: ... ct[i] = 1 ... >>> ct {'l': 4, 'k': 4, 'f': 2, 'j': 3, 'a': 3, 's': 2, 'g': 2, ';': 2, 'm': 1, ',': 1, ':': 2, ' ': 2, 'h': 2, 'e': 3, 'o': 1, '@': 1, '1': 1, '-': 1, 'r': 2, 'n': 1}
dictionary型の空データctを作り、該当要素がctになければct[要素] = 1として数え始める。
ctに該当要素があればその要素数を+1する。
この方法は細かい設定をして集計する場合に使いやすい。例えばアルファベットだけをカウントしたい場合。
アルファベットだけを数えたい
for loopに判定するコードを追加する事で、アルファベットだけを数えられる。
>>> tx = "lkfjaslfkjalg;km,: h:s;klg eoj@eh1-earnr" >>> ct = {} >>> for i in tx: ... if str.isalpha(i) and i not in ct: ... ct[i] = 1 ... elif i in ct: ... ct[i] += 1 ... >>> ct {'l': 4, 'k': 4, 'f': 2, 'j': 3, 'a': 3, 's': 2, 'g': 2, 'm': 1, 'h': 2, 'e': 3, 'o': 1, 'r': 2, 'n': 1}
ただ全要素を数える時に使えるcollections.Counter()
ただ全要素を数える時には、collections.Counter()で同様の事ができる。
>>> tx 'lkfjaslfkjalg;km,: h:s;klg eoj@eh1-earnr' >>> from collections import Counter >>> ct = Counter(tx) >>> ct Counter({'l': 4, 'k': 4, 'j': 3, 'a': 3, 'e': 3, 'f': 2, 's': 2, 'g': 2, ';': 2, ':': 2, ' ': 2, 'h': 2, 'r': 2, 'm': 1, ',': 1, 'o': 1, '@': 1, '1': 1, '-': 1, 'n': 1})
collections.Counter()は要素をkeyに、カウントした数字をvalueにしたdictionary型のデータ。
カウント数(value)はゼロでも負でも可能。ゼロは分かるが負ってどう言う状況だろうか?分かったら追記する。
collections.Counter()型データの作成方法
# import collectionsでインポートとした場合 # 空集合 ct = collections.Counter() # dictinoary型データを直接入力 >>> ct = collections.Counter({"apple": 5, "banana": 7}) >>> ct Counter({'banana': 7, 'apple': 5}) # ct = Counter({要素: 数}) # "="を使ってデータを入力。 >>> ct = collections.Counter(banana = 6, apple=9) >>> ct Counter({'apple': 9, 'banana': 6})
collections.Counter()の機能
collections.Counter()を使うと用意された機能を使用できる。
elements() : 集計したリスト通りの数要素を出力
集計リストの順番で要素をその個数分出力します。
>>> ct Counter({'l': 4, 'k': 4, 'j': 3, 'a': 3, 'e': 3, 'f': 2, 's': 2, 'g': 2, ';': 2, ':': 2, ' ': 2, 'h': 2, 'r': 2, 'm': 1, ',': 1, 'o': 1, '@': 1, '1': 1, '-': 1, 'n': 1}) >>> ct.elements() <itertools.chain object at 0x105234220>
ただct.elements()を実行してもこのコードはiteratorを返すだけですので、何が出力されるのか、中身を見る為、list “lst”に一ずつappendしてから出力。
>>> lst = [] >>> for i in ct.elements(): ... lst.append(i) ... >>> lst ['l', 'l', 'l', 'l', 'k', 'k', 'k', 'k', 'f', 'f', 'j', 'j', 'j', 'a', 'a', 'a', 's', 's', 'g', 'g', ';', ';', 'm', ',', ':', ':', ' ', ' ', 'h', 'h', 'e', 'e', 'e', 'o', '@', '1', '-', 'r', 'r', 'n']
実際の出力順が元々のctの順番通りではありませんが、要素が数えられた個数分出力されている事は分かります。実際の運用上はこのlstをソートして使うのが使いやすい。
>>> ct Counter({'l': 4, 'k': 4, 'j': 3, 'a': 3, 'e': 3, 'f': 2, 's': 2, 'g': 2, ';': 2, ':': 2, ' ': 2, 'h': 2, 'r': 2, 'm': 1, ',': 1, 'o': 1, '@': 1, '1': 1, '-': 1, 'n': 1}) >>> sorted(ct.elements()) [' ', ' ', ',', '-', '1', ':', ':', ';', ';', '@', 'a', 'a', 'a', 'e', 'e', 'e', 'f', 'f', 'g', 'g', 'h', 'h', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l', 'l', 'l', 'm', 'n', 'o', 'r', 'r', 's', 's']
因みに、valueが0や負の数字の場合、無視される。
most_common([n]):一番多い要素を出力
一番多い要素からn個分をkey:valueペアのデータで出力。
nが省略されたりNoneの場合全データが返ってくる。
同じ数だった場合、並んだ順番で左の物が先。
>>> ct Counter({'l': 4, 'k': 4, 'j': 3, 'a': 3, 'e': 3, 'f': 2, 's': 2, 'g': 2, ';': 2, ':': 2, ' ': 2, 'h': 2, 'r': 2, 'm': 1, ',': 1, 'o': 1, '@': 1, '1': 1, '-': 1, 'n': 1}) >>> ct.most_common() # ct.most_common(None)と同じ [('l', 4), ('k', 4), ('j', 3), ('a', 3), ('e', 3), ('f', 2), ('s', 2), ('g', 2), (';', 2), (':', 2), (' ', 2), ('h', 2), ('r', 2), ('m', 1), (',', 1), ('o', 1), ('@', 1), ('1', 1), ('-', 1), ('n', 1)] >>> ct.most_common(4) [('l', 4), ('k', 4), ('j', 3), ('a', 3)]
Counterオブジェクトの使用例
sum(c.values()) # 要素の合計値を返す c.clear() # データをクリア 空データCounter()になる list(c) # 要素のリスト化 set(c) # 要素のcセット化 dict(c) # key:valueの関係そのままにdictionary型に変換 c.items() # 同様の関係のままdict_items()の型に変換 Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs c.most_common()[:-n-1:-1] # n番目までの最も少ない数の要素をkey:valueで返す +c # 数がゼロや負の要素を削除
今後随時更新します。
コメント