0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python】ブールマスクの使い方解説 : numpy と list の使い分けと要素番号の取得方法

Last updated at Posted at 2024-12-17

はじめに

Pythonでデータ処理をしていると「条件を満たす要素の抽出」や「要素番号(インデックス)の取得」が必要になることがあります。このような操作では ブールマスク が非常に便利です。

本記事では、numpy と標準 list における ブールマスクの用法、および 要素番号の取得方法 について解説します。

よくある間違いやすい点 np.where を使う場合は、条件を満たす配列の要素番号が取得できるが、pixel==3 のようにブールマスクを使う場合は、True/False の numpy.array が返ってくるので、要素数は前者はカット後の要素数となり、後者は要素数は変わらないことに注意が必要。ただし、pixel[(pixel==3)] のようにブールカットをかけたらカット後の要素数になる。

1. ブールマスクとは?

ブールマスクは、条件に合う要素を True、それ以外を False とする ブール型配列 です。データ処理のフィルタリングや要素抽出に使います。

2. numpy におけるブールマスク

2.1 ブールマスクで要素を抽出する

numpy 配列では、ブールマスクを使って条件に合う要素を直接抽出できます。

import numpy as np

# サンプルデータ
data = np.array([0, 1, 2, 1, 3, 1, 4])

# 条件: 値が1に等しい要素を抽出
mask = (data == 1)  # ブールマスクの生成
filtered_data = data[mask]  # マスクを使って抽出

print("Boolean Mask:", mask)
print("Filtered Data:", filtered_data)

出力:

Boolean Mask: [False  True False  True False  True False]
Filtered Data: [1 1 1]

2.2 True の要素番号(インデックス)を取得する

np.nonzero() または np.where() を使います。

# True の要素番号を取得
indices = np.nonzero(mask)[0]
# または np.where を使う
indices_alt = np.where(mask)[0]

print("True Indices (nonzero):", indices)
print("True Indices (where):", indices_alt)

出力:

True Indices (nonzero): [1 3 5]
True Indices (where): [1 3 5]

2.3 多次元配列でのブールマスク

numpy では多次元配列にもブールマスクを適用できます。

data = np.array([[0, 1], [1, 0]])

# 条件: 値が1の要素
mask = (data == 1)

# True の位置を取得
indices = np.nonzero(mask)

print("True Indices (Row):", indices[0])  # 行インデックス
print("True Indices (Col):", indices[1])  # 列インデックス

出力:

True Indices (Row): [0 1]
True Indices (Col): [1 0]

3. Pythonリストにおけるブールマスクの用法

3.1 ブールマスクを使った要素抽出

Python標準 list では、numpy のようにブールマスクを直接適用することは できません

data = [0, 1, 2, 1, 3, 1, 4]
mask = [False, True, False, True, False, True, False]

# これを実行するとエラーになる
# filtered_data = data[mask]  # TypeError

3.2 リスト内包表記を使った抽出

リストとブールマスクの要素を対応させるには、zip やリスト内包表記を使います。

# zip を使って条件に合う要素を抽出
filtered_data = [value for value, flag in zip(data, mask) if flag]

print("Filtered Data:", filtered_data)

出力:

Filtered Data: [1, 1, 1]

3.3 True の要素番号(インデックス)を取得する

リストでは enumerate() を使ってインデックスを取得します。

# True の要素番号を取得
indices = [i for i, flag in enumerate(mask) if flag]

print("True Indices:", indices)

出力:

True Indices: [1, 3, 5]

4. itertools.compress を使った簡潔なリスト処理

Python標準ライブラリの itertools.compress を使うと、ブールマスクをリストに適用できます。

from itertools import compress

data = [0, 1, 2, 1, 3, 1, 4]
mask = [False, True, False, True, False, True, False]

# compress を使って抽出
filtered_data = list(compress(data, mask))

print("Filtered Data:", filtered_data)

出力:

Filtered Data: [1, 1, 1]

5. 要素数の取得

pixel == 1 でブールマスクを作成した場合、np.sum(pixel == 1) で要素数が求められます。その理由は、ブール値 (True / False) が数値として扱われる ためです。


ブール値と数値の関係

Pythonでは、TrueFalse整数 として扱われることがあります:

  • True1 として扱われる
  • False0 として扱われる

したがって、numpy 配列のブールマスクに対して np.sum() を適用すると、True の数を合計する動作になります。

具体例

以下の例で確認してみましょう:

import numpy as np

# サンプルデータ
pixel = np.array([0, 1, 2, 1, 3, 1, 4])

# ブールマスクの生成 (True: pixel == 1, False: otherwise)
mask = (pixel == 1)

print("Boolean Mask:", mask)

# True の要素数を計算
count = np.sum(mask)

print("Number of True Elements:", count)

出力:

Boolean Mask: [False  True False  True False  True False]
Number of True Elements: 3

動作の仕組み

  1. pixel == 1
    各要素に対して条件を評価し、True または False のブール型配列 (mask) を生成します。

    [False, True, False, True, False, True, False]
    
  2. np.sum(mask)
    True1False0 として数値扱いされるため、np.sum()True の個数を合計します。

    0 + 1 + 0 + 1 + 0 + 1 + 0 = 3
    

この性質を利用すれば、条件を満たす要素数を簡単に求めることができます。

6. numpylist の比較まとめ

機能 numpy Python list
ブールマスク適用 data[mask] zip or compress
True の要素番号取得 np.nonzero(mask) / np.where(mask) enumerate() を使う
多次元配列の対応 可能 非対応
処理速度 ベクトル化で高速 ループベースのため遅い(?)

まとめ

  • numpy ではブールマスクを直接使って要素の 抽出インデックス取得 が簡単にできます。
  • Pythonの標準 list ではブールマスクが直接適用できないため、zipenumerate を活用する必要があります。
  • 多次元配列 の場合は numpy 一択です。

データ処理の規模や用途に応じて、numpylist を使い分けましょう!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?