2022年5月15日日曜日

【pandas】value_countによる出現頻度の算出

 データ分析用ライブラリpandasの1次元のデータ構造Seriesと2次元のデータ構造Dataframeについて、要素の出現回数を算出するにはvalue_countを用いる。

 ライブラリpandasを使うにはインポートが必要。通常次のようにpdと略されてインポートされる。

import pandas as pd



1. value_countによるSeriesの並べ替え

 Series.value_count()の書式は以下の通り。

Series.value_counts(normalize=False, 
                    sort=True, 
                    ascending=False, 
                    bins=None, 
                    dropna=True)

引数 意味
normalize 頻度を正規化(合計1に)するか。デフォルトはFalse
sort 頻度順に並べるか。デフォルトはTrue
ascending 昇順に並べるか。デフォルトはFalse
bins 区画幅の指定。デフォルトはFalse
dropna NaNを含めない。デフォルトはTrue


 引数を指定しない場合。各要素が頻度の多い順に並べられ出現回数がカウントされる。ser.value_counts()Series型。

import pandas as pd

ser = pd.Series([7, 5, 8, 2, 4, 7, 8, 8, 2, 2, 3, 8])
print(ser.value_counts())

 実行結果

8    4
2    3
7    2
5    1
4    1
3    1
dtype: int64


 normalize=Trueの場合。頻度が正規化される。

import pandas as pd

ser = pd.Series([7, 5, 8, 2, 4, 7, 8, 8, 2, 2, 3, 8])
print(ser.value_counts(normalize=True))

 実行結果

8    0.333333
2    0.250000
7    0.166667
5    0.083333
4    0.083333
3    0.083333
dtype: float64


 sort=Falseの場合。出現回数順にソートされない。

import pandas as pd

ser = pd.Series([7, 5, 8, 2, 4, 7, 8, 8, 2, 2, 3, 8])
print(ser.value_counts(sort=False))

 実行結果

7    2
5    1
8    4
2    3
4    1
3    1
dtype: int64


 ascending=Trueの場合。頻度の昇順(少ない順)に並べられる。

import pandas as pd

ser = pd.Series([7, 5, 8, 2, 4, 7, 8, 8, 2, 2, 3, 8])
print(ser.value_counts(ascending=True))

 実行結果

5    1
4    1
3    1
7    2
2    3
8    4
dtype: int64


 binsを指定する場合。要素が数字の場合に指定した区間数にグループ化され、グループ毎の出現回数が求まる。
bins=3を指定する例。3区間に分けられる。

import pandas as pd

ser = pd.Series([7, 5, 8, 2, 4, 7, 8, 8, 2, 2, 3, 8])
print(ser.value_counts(bins=3))

 実行結果

(6.0, 8.0]      6
(1.993, 4.0]    5
(4.0, 6.0]      1
dtype: int64


2. value_countによるDataframeの並べ替え

 Dataframeで要素の出現回数を求める場合もvalue_countsを用いる。

Dataframe.value_count()の書式は以下の通り。

Dataframe.value_counts(subset=None,
                       normalize=False, 
                       sort=True, 
                       ascending=False, 
                       dropna=True)

引数 意味
subset カウントするColumnsの指定。デフォルトはNone
normalize 頻度を正規化(合計1に)するか。デフォルトはFalse
sort 頻度順に並べるか。デフォルトはTrue
ascending 昇順に並べるか。デフォルトはFalse
dropna NaNを含めない。デフォルトはTrue


 引数を指定しない場合。2つのColumnsの組み合わせの出現回数が求められる。

df = pd.DataFrame(
    data = [['赤', '野菜'], 
            ['緑', '野菜'],
            ['赤', '果物'],
            ['黄', '果物'],
            ['緑', '野菜']],
    columns = ['色', '種類'],
    index = ['トマト', 'きゅうり', 'イチゴ', 'バナナ', 'キャベツ']
    )

print(df.value_counts())

 実行結果

色  種類
緑  野菜    2
赤  果物    1
   野菜    1
黄  果物    1
dtype: int64


 Columnsを指定する場合。指定した列の要素の出現回数が求まる。

df = pd.DataFrame(
    data = [['赤', '野菜'], 
            ['緑', '野菜'],
            ['赤', '果物'],
            ['黄', '果物'],
            ['緑', '野菜']],
    columns = ['色', '種類'],
    index = ['トマト', 'きゅうり', 'イチゴ', 'バナナ', 'キャベツ']
    )

print(df.value_counts(subset='種類'))

 実行結果

種類
野菜    3
果物    2
dtype: int64


3. リファレンス

pandas > pandas.Series.value_counts
pandas > pandas.DataFrame.value_counts

使用したバージョン:Python 3.8.12/pandas 1.4.0

2022年5月8日日曜日

【OpenCV】画像の生成

 画像処理ライブラリOpenCVの画像はNumpyndarray形式なので、画像を新規に生成する場合ndarrayを作成すればよい


OpenCV、Numpyを使うにはインポートが必要。
OpenCV

import cv2

Numpyは、しばしば次のようにnpと略されてインポートされる。

import numpy as np



1. グレースケール画像の生成

 グレースケール画像は0-255の256画素値の1チャンネル画像。全要素の値が0のndarrayを生成するnumpy.zeros、全要素の値が1のndarrayを生成するnumpy.ones、全要素が任意の値となるndarrayを生成するnumpy.fill等により生成する。

 numpy.zerosで幅400ピクセル高さ250ピクセルの黒い画像(画素値0)を生成する例。OpenCVの画像フォーマットは(高さのピクセル数、幅のピクセル数、チャンネル数)でグレースケール画像はチャンネル数が1なので引数に(250, 400, 3)を指定する。またdata-typeとして符号なし8ビット整数のデータ型を指定する引数、numpy.uint8を指定する。

import numpy as np
import cv2

img = np.zeros((250, 400, 1), np.uint8)

cv2.imwrite('img.jpg', img)

実行結果





 numpy.zerosで生成した全要素の値が0のndarrayに100を加算し、全要素が100のndarrayとして灰色の画像を作成する例

import numpy as np
import cv2

img = np.zeros((250, 400, 1), np.uint8)+100

cv2.imwrite('img.jpg', img)

実行結果





 全要素の値が1のndarrayを生成するnumpy.onesを使用する例。

import numpy as np
import cv2

img = np.ones((250, 400, 1), np.uint8)*200

cv2.imwrite('200.jpg', img)

実行結果





 全要素が任意の値を持つndarrayを生成するnumpy.fullを使用する例。引数にはndarrayの形状の他、要素の値(ここでは150)を指定する。

import numpy as np
import cv2

img = np.full((250, 400, 1), 150, np.uint8)

cv2.imwrite('img.jpg', img)

実行結果





2. カラー画像の生成

 カラー画像ではチャンネル数がB(青)、G(緑)、R(赤)の3チャンネルとなるため、(高さのピクセル数、幅のピクセル数、チャンネル数3)ndarrayを生成すればよい。また、チャンネル別の値はインデクシングで設定できる。
幅400高さ250ピクセルの3チャンネルの画像を生成しBチャンネルの画素値を100、Gチャンネルの画素値を250、Rチャンネルの画素値を30とする例。

import numpy as np
import cv2

img = np.zeros((250, 400, 3), np.uint8)

img[:, :, 0] = 100  # Bチャンネルの値を100
img[:, :, 1] = 250  # Gチャンネルの値を250
img[:, :, 2] = 30  # Rチャンネルの値を30

cv2.imwrite('img.jpg', img) 

実行結果





3. リファレンス

Numpy > numpy.zeros
Numpy > numpy.ones
Numpy > numpy.full

使用したバージョン:Python 3.10.4 / OpenCV 4.5.5

2022年5月7日土曜日

【組み込み関数】reversed、スライシングによるイテラブルオブジェクトの反転

 組み込み関数reversedはリストやタプルなどのイテラブルオブジェクトの要素の順番を逆にしたイテレーターを生成する。生成したイテレーターをイテラブルオブジェクトに変換することでイテラブルオブジェクトが反転する。また、スライシングでstepを-1とすることで後ろから要素が取得され、イテラブルオブジェクトの反転ができる。




1. reversedによるリスト、タプルの反転

 reversedはイテラブルオブジェクトの要素の順番を逆にしたイテレータを生成する。

a = [1, 2, 3]

print(reversed(a))

 実行結果

<list_reverseiterator object at 0x000001883EDBDF00>

 逆順のリストやタプルにする場合はlisttuple関数でイテラブルオブジェクトに変換する。

a = [1, 2, 3]

print(list(reversed(a)))

 実行結果

[3, 2, 1]


a = (1, 2, 3)

print(tuple(reversed(a)))

 実行結果

(3, 2, 1)


 元のリストやタプルは維持される。

a = [1, 2, 3]

print(list(reversed(a)))
print(a)

 実行結果

[3, 2, 1]
[1, 2, 3]


2. reversedによる文字列の反転

 文字列を反転させる場合、reversedで反転したイテレーターをリスト化する。

a = '123'

print(list(reversed(a)))

 実行結果

['3', '2', '1']


 このリストを文字列化するにはjoinを使う。

a = '123'

print(''.join(list(reversed(a))))

 実行結果

321


3. スライシングによるイテラブルオブジェクトの反転

 スライシングでstepに-1を指定すると「後ろから順に」イテラブルオブジェクトの要素を取得できる。これによりリスト、タプル、文字列を反転できる。

a = [1, 2, 3]

print(a[::-1])

 実行結果

['3', '2', '1']


a = (1, 2, 3)

print(a[::-1])

 実行結果

(3, 2, 1)


a = '123'

print(a[::-1])

 実行結果

321


4. リファレンス

Python 標準ライブラリ > 組み込み関数 > reversed(seq)

使用したバージョン:Python 3.10.4

2022年5月6日金曜日

【OpenCV】画像のアルファブレンド

 アルファブレンドは2つ(以上)の画像を係数を用いて合成する方法。画像処理ライブラリOpenCVaddWeightedによるアルファブレンドおよびndarrayの和によるアルファブレンドについて説明する。


OpenCVを使うには次のようにインポートが必要。
import cv2

例に用いる画像'buiding.jpg', 'girl.jpg'(幅450x高さ300ピクセル)は以下を使用(フリー写真素材ぱくたそより)

'buiding.jpg'



'girl.jpg'





1. addWeightedによるアルファブレンド

 addWeightedは2つの画像を係数をかけて合成する。合成する画像のサイズは同じでないといけない。
書式は以下。

cv.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]] ) -> dst

src1src2が合成する2つの画像。下式のようにalphasrc1に対する係数、betasrc2に対する係数、gammaはオフセットとなる。

dst = src1*alpha + src2*beta + gamma

 カラー画像のように複数のチャンネルがある場合は、各チャンネルごとに合成される。また、画素値の上限255を超えた場合は255となり飽和(白飛び)する。


alpha:0.5beta:0.5gamma:0として画像を合成する例

import cv2

src1 = cv2.imread('building.jpg')
src2 = cv2.imread('girl.jpg')

blend = cv2.addWeighted(src1, 0.5, src2, 0.5, 0)	

cv2.imwrite('blend.jpg', blend)



alpha:0.2beta:0.2gamma:150として画像を合成する例

import cv2

src1 = cv2.imread('building.jpg')
src2 = cv2.imread('girl.jpg')

blend = cv2.addWeighted(src1, 0.25, src2, 0.25, 150)	

cv2.imwrite('blend.jpg', blend)



2. ndarrayの和によるアルファブレンド

 OpenCVの画像はnumpy.ndarrayなので演算による合成が可能。addWeightedalpha:0.2beta:0.2gamma:150と同じ処理をする例。addWeightedと同じ結果が得られる。

import cv2

src1 = cv2.imread('building.jpg')
src2 = cv2.imread('girl.jpg')

blend = src1*0.25 + src2*0.25 + 150	

cv2.imwrite('blend.jpg', blend)



 addWeightedで合成できるのは2つの画像だがnumpy.ndarrayの演算では合成する画像の数に制限はない。
さらに3つ目の画像'mountain.jpg'を合成する例。

'mountain.jpg' (幅450x高さ300ピクセル)は以下を使用(フリー写真素材ぱくたそより)



import cv2

src1 = cv2.imread('building.jpg')
src2 = cv2.imread('girl.jpg')
src3 = cv2.imread('mountain.jpg')

blend = src1*0.3 + src2*0.3 + src3*0.3	

cv2.imwrite('blend3.jpg', blend)




3. リファレンス

OpenCV > Operations on arrays > addWeighted()

使用したバージョン:Python 3.10.4 / OpenCV 4.5.5

【組み込み関数】all, anyによるイテラブルオブジェクト全要素の判定

 組み込み関数allはイテラブルオブジェクトの全要素がTrueの場合にTrueを返す。また組み込み関数anyはイテラブルオブジェクトにTrueが含まれている場合にTrueを返す。




1. all関数

 allはイテラブルオブジェクトの要素が全てTrueの場合にTrueを返す。要素が空の場合にはTrueを返す。

x = [True, True, True]

print(all(x))

実行結果

True

 イテラブルオブジェクトの要素にFalseが含まれる場合Falseを返す。

x = [True, True, False]

print(all(x))

実行結果

False

 要素が空の場合Trueを返す。

x = []

print(all(x))

実行結果

True

 要素が条件式の場合

a = 4
x = [a>2, a<7, a==4]

print(all(x))

実行結果

True

 if文で使用する場合

x = [True, True, False]

if all(x):
    print('OK')
else:
    print('NG')    

実行結果

NG


2. any関数

 anyはイテラブルオブジェクトの要素にTrueが含まれる場合にTrueを返す。要素が空の場合にはFalseを返す。

x = [True, False, False]

print(any(x))

実行結果

True

 イテラブルオブジェクトの要素が全てFalseならFalseを返す。

x = [False, False, False]

print(any(x))

実行結果

False

 要素が空の場合Falseを返す。

x = []

print(any(x))

実行結果

False

 要素が条件式の場合

a = 4
x = [a>2, a<7, a==5]

print(any(x))

実行結果

True

 if文で使用する場合

x = [True, True, False]

if any(x):
    print('OK')
else:
    print('NG')    

実行結果

OK


3. リファレンス

Python 標準ライブラリ > 組み込み関数 > all(iterable)
Python 標準ライブラリ > 組み込み関数 > any(iterable)

使用したバージョン:Python 3.10.4

【Numpy】whereによる条件に合う要素に対する演算

 Pythonの数値計算ライブラリNumPyの配列型データ構造であるndarrayの要素に対して、条件に合うもののみ演算を行う場合whereを用いる。

Numpyを使う際にはimportが必要。しばしば次のようにnpと略されてインポートされる。

import numpy as np



1. whereの書式

 whereの書式は以下。conditionに条件式を書き、条件が適合する要素に対して処理xが実行され、それ以外に対しては処理yが実行される。condition, x, yいずれも必須の引数。

numpy.where(condition, [x, y, ]/)


2. whereの例

 一次元ndarrayの要素が5以上の場合、値を10倍する例。

import numpy as np

a = np.arange(10)
b = np.where(a < 5, a, 10*a)

print(b)

実行結果

[ 0  1  2  3  4 50 60 70 80 90]


 二次元ndarrayの場合。conditionTrueの場合、xFalseの場合、yの値が用いられる。

import numpy as np

a = np.array([[True, False], [True, True]])
print(np.where(a, 
               [[1, 2], [3, 4]],
               [[9, 8], [7, 6]]))

実行結果

[[1 8]
 [3 4]]


3. リファレンス

NumPy > numpy.where

使用バージョン:Python 3.10.4/numpy 1.22.3

【OpenCV】cvtColorによるBGRからグレースケール, HSVへの色空間変換

 画像処理ライブラリOpenCVcvtColorにより色空間の変換ができる。頻繁に行われるBGR色空間からグレースケールへの変換、BGR色空間からHSV色空間への変換を説明する。

OpenCVを使うには次のようにインポートが必要。

import cv2

 使用する画像 'iwojima.jpg'(幅400ピクセルx高さ300ピクセル)は以下(フリー写真素材ぱくたそより)





1. BGR色空間からグレースケールへの変換

 cvtColorの書式は以下。dstが変換前の画像、srcが変換後の画像、codeが変換方法を示すコードとなる。

dst = cvtColor(src, code)

BGR色空間→グレースケール変換の場合、codecv2.COLOR_BGR2GRAYを用いる。

dst = cvtColor(src, cv2.COLOR_BGR2GRAY)

BGR色空間→グレースケール変換し変換後の画像をファイルに保存する例

import cv2
from cv2 import imwrite

img = cv2.imread('iwojima.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

cv2.imwrite('gray.jpg', gray)



2. BGR色空間からHSV色空間への変換

 HSV色空間はH(Hue:色相)、S(Saturation:彩度)、V(Value:明度)3チャンネルからなる色空間で、OpenCVではH[0,179], S[0,255],V[0,255]の範囲の値をとる。OpenCVのカラー画像はBGR色空間だが、HSV色空間に変換することで色相、彩度、明度を独立して調整することが可能になる。

 BGR色空間→HSV色空間の変換の場合、codecv2.COLOR_BGR2HSVを用いる。

dst = cvtColor(src, cv2.COLOR_BGR2HSV)

HSV色空間→BGR色空間の変換の場合、codecv2.COLOR_HSV2BGRを用いる。

dst = cvtColor(src, cv2.COLOR_HSV2BGR)

HSV色空間の画像はimwriteによるファイル保存等ができないため、BGR色空間に変換する必要がある。

色相Hの値を90°変更する例。h値が90より小さい画素に90加算、h値が90より大きい画素は90引いている。

import cv2
import numpy as np
from cv2 import imwrite

img = cv2.imread('iwojima.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

hsv[:, :, 0] = np.where(hsv[:, :, 0]<90,
                        hsv[:, :, 0]+90,
                        hsv[:, :, 0]-90)
bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

cv2.imwrite('h90.jpg', bgr)



彩度Sの値を0.5倍する例。

import cv2
from cv2 import imwrite

img = cv2.imread('iwojima.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

hsv[:, :, 1] = hsv[:, :, 1]*0.5
bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

cv2.imwrite('s05.jpg', bgr)



明度Vの値に+30加算する例。加算後に255を越えた画素は255としている。

import cv2
import numpy as np
from cv2 import imwrite

img = cv2.imread('iwojima.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

hsv[:, :, 2] = np.where(hsv[:, :, 2]<226, 
                        hsv[:, :, 2]+30,
                        255)
bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

cv2.imwrite('v30.jpg', bgr)



3. リファレンス

OpenCV > Color Space Conversions > cvtColor()
OpenCV > Color conversions

使用したバージョン:Python 3.10.4 / OpenCV 4.5.5