【NumPy】リスト内の整数をカウント(ただし負の数は除く)するbincount[Python]

  • URLをコピーしました!

NumPy

前回、離散データを表示するステムプロット(stem plot)を紹介しました。

今回はリスト内の整数をカウント(ただし負の数は除く)するbincountを紹介します。

それでは始めていきましょう。

bincountの使い方と特徴

まずはbincountの使い方と特徴を解説します。

bincountは「bincount(整数のリスト)」として用います。

すると0からリスト内の最大値までの整数のそれぞれの個数が返ってきます。

つまり整数のリストの中に0が何個、1が何個、2が何個、最大値が何個…というそれぞれの個数のリストが返ってきます。

import numpy as np

data = [0, 0, 0, 1, 2, 2, 3, 3, 3]

print(np.bincount(data))

実行結果
[3 1 2 3]

ちなみにリストの中に0が入っていない場合でも0から最大値までの整数のそれぞれの個数、つまり0は0個としてカウントされたリストが返ってきます。

import numpy as np

data = [1, 2, 2, 3, 3, 3]

print(np.bincount(data))

実行結果
[0 1 2 3]

また最大値までの間の整数でリスト内に無い整数は0個としてカウントされます。

import numpy as np

data = [1, 2, 2, 3, 3, 3, 5]

print(np.bincount(data))

実行結果
[0 1 2 3 0 1]

特殊な例

次に特殊な例を紹介します。

まず整数であれば文字列(str型)でも良かったりします。

import numpy as np

data = ["1", "2", "2", "3", "3", "3"]

print(np.bincount(data))

実行結果
[0 1 2 3]

どうやらbincountの処理の中で数値を「int()」として整数(int型)に変換して処理しているようです。

次にリストの値が整数ではなく、小数だった場合です。

小数の場合はbincountの処理で値は「int()」で変換されていることから、変換された結果に対してそれぞれの整数の個数が返ってきます。

import numpy as np

data = [0.1, 0.2, 0.2, 0.3, 0.5, 0.5, 1.5, 1.5]

print(np.bincount(data))

実行結果
[6 2]

この場合、「int()」の処理で「0.1」、「0.2」、「0.3」、「0.5」は全て「0」になり、「1.5」は「1」となることから、「6 2」が返ってくると言うわけです。

エラーとなる例

次にエラーとなる例を紹介します。

負の数がリストに入っている場合

1つ目は負の数がリストに入っている場合です。

import numpy as np

data = [-1, 1, 2, 2, 3, 3, 3]

print(np.bincount(data))

実行結果
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[9], line 5
      1 import numpy as np
      3 data = [-1, 1, 2, 2, 3, 3, 3]
----> 5 print(np.bincount(data))

ValueError: 'list' argument must have no negative elements

この場合、負の数を正の数に変えるか、負の数を無視したリストに変換する必要があります。

負の数を正の数に変える場合はリストをNumPyのndarrayに変換し、要素を絶対値とする「abs」を使うことで一度に変換することができます。

import numpy as np

data = [-1, 1, 2, 2, 3, 3, 3]

data_abs = abs(np.array(data))

print(np.bincount(data_abs))

実行結果
[0 2 2 3]

ただしこの場合、負の数だった要素もカウントに含まれてしまいます。

負の数を無視したリストに変換する場合はリスト内包表記を使って正の数だけのリストを作り直す方法があります。

import numpy as np

data = [-1, 1, 2, 2, 3, 3, 3]

data_new =[num for num in data if num > 0]

print(np.bincount(data_new))

実行結果
[0 1 2 3]

こちらの方法では元のリストの正の数をカウントすることができます。

リストの要素が数値でない場合

2つ目のエラーとなる場合はリストの要素が数値でない場合です。

例えば文字列(str型)の場合はエラーとなります。

import numpy as np

data = ["a", "b", "b", "c", "c", "c"]

print(np.bincount(data))

実行結果
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[4], line 5
      1 import numpy as np
      3 data = ["a", "b", "b", "c", "c", "c"]
----> 5 print(np.bincount(data))

ValueError: invalid literal for int() with base 10: 'a'

多次元リストになっている場合

リストが2次元以上の多次元リスト担っている場合もエラーとなります。

import numpy as np

data = [[1, 2], [2, 3], [3, 3]]

print(np.bincount(data))

実行結果
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[19], line 5
      1 import numpy as np
      3 data = [[1, 2], [2, 3], [3, 3]]
----> 5 print(np.bincount(data))

ValueError: object too deep for desired array

この場合、リストをNumPyのndarrayにして、flattenで一次元化することでbincountを使える様になります。

import numpy as np

data = [[1, 2], [2, 3], [3, 3]]

data_f = np.array(data).flatten()

print(np.bincount(data_f))

実行結果
[0 1 2 3]

オプション引数

bincountおオプション引数には「weight」と「minlength」があります。

weight

weightは各要素のカウントを1以外に変えることができ、それによりそれぞれの要素を重みづけすることができます。

import numpy as np

data = [1, 2, 2, 3, 3, 3]

weight = [0.1, 0.2 , 0.3, 0.4, 0.5, 0.6]

print(np.bincount(data, weights=weight))

実行結果
[0.  0.1 0.5 1.5]

例えばこの場合、3つの「3」はそれぞれ「0.4」、「0.5」、「0.6」と重みづけされています。

そのためそれらを足し算すると「1.5」となるので、返り値における「3」のカウント数は「1.5」になります。

minlength

minlengthはカウントする数の長さを調節するためのオプション引数です。

この値がリストに含まれる最大の整数よりも大きい場合、minlengthで指定した値の一つ前の値まで返り値の個数が0で埋められます。

import numpy as np

data = [1, 2, 2, 3, 3, 3]

print(np.bincount(data, minlength=10))

実行結果
[0 1 2 3 0 0 0 0 0 0]

この場合、リストに含まれる最大値は「3」なので、minlengthを指定していない場合、「0から3まで」の4つの整数に関してリスト内の要素数がカウントされます。

しかしminlengthが「10」となっていることから、「0から9」までの10個の整数においてリスト内の要素数がカウントされます。

またminlengthの長さがリスト内に含まれる最大値よりも小さい場合はリスト内の最大値が優先されます。

import numpy as np

data = [1, 2, 2, 3, 3, 3]

print(np.bincount(data, minlength=1))

実行結果
[0 1 2 3]

この場合、minlengthで「1」を指定していますが、リストの最大値が「3」であるため、リストの最大値が優先され、「0から3」までの4つの整数のカウントした値が返されます。

次回はNumPyで多次元配列をソートしてそのインデックスを返すargsortを紹介します。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする