ブール演算と高度なインデックス作成

1. 学習内容



2. ストーリー

アリスは10万件の温度測定値を持っており、40°Cを超えるすべての測定値を見つけ出す必要があります。彼女はtemps[temps > 40]と記述すると、即座に結果が得られました。 ボブは驚いてこう言いました。「if文を使ったPythonのループなら少なくとも5行はかかるだろうに、NumPyなら1行で済む。100倍近く速い!」これこそが、NumPyの高度なインデックス機能の真骨頂――簡潔な式で複雑なデータフィルタリングを実現する力です。



3. ブールマスク

(1) ブールマスクとは何か

ブールマスクとは、元の配列と同じ形状を持つ真偽値の配列のことです。NumPyの比較演算子は要素ごとに演算を行い、ブール配列を返します。

PYTHON
import numpy as np

arr = np.array([3, -1, 4, -2, 5])
mask = arr > 0
print(mask)   # [ True False  True False  True]
print(arr[mask])  # [3 4 5]
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

(2) 比較演算子

演算子 意味 対応する関数
> より大きい np.greater
>= 以上 np.greater_equal
< 未満 np.less
<= 以下 np.less_equal
== 等しい np.equal
!= 異なる np.not_equal

(3) 論理積

論理演算子を使用して複数の条件を組み合わせます。&(and)、|(or)、~(not)を使用してください。Pythonのand/or/not ではなく、論理演算子を使用してください。各条件は括弧で囲む必要があります。

PYTHON
arr = np.array([1, 5, 8, 3, 9, 2])
mask = (arr > 3) & (arr < 8)   # 3 < arr < 8
print(arr[mask])  # [5]
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
論理演算 意味 同等の関数
& 論理AND np.logical_and
| 論理OR np.logical_or
~ 論理NOT np.logical_not


4. np.where と条件付き選択

(1) 3引数形式:np.where(condition, x, y)

条件が True の場合は x から、False の場合は y から要素を返します。

PYTHON
import numpy as np

arr = np.array([-3, 5, -1, 8, -2, 7])
result = np.where(arr > 0, arr, 0)
print(result)  # [0 5 0 8 0 7]
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

(2) 単引数形:np.where(condition)

条件が True となるインデックスを返します。

PYTHON
indices = np.where(arr > 0)
print(indices)  # (array([1, 3, 5]),)
print(arr[indices])  # [5 8 7]
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.


5. 高度なインデックス作成

ファンシーインデックスは、整数配列を使用して、任意の順序で要素を選択します。

PYTHON
import numpy as np

a = np.arange(10)  # [0 1 2 3 4 5 6 7 8 9]

# Select specific indices
print(a[[0, 3, 7]])      # [0 3 7]

# Select in any order, with repeats
print(a[[5, 5, 1, 9]])   # [5 5 1 9]

# 2D fancy indexing
b = np.arange(12).reshape(3, 4)
print(b[[0, 2]])          # rows 0 and 2
print(b[:, [0, 2, 3]])    # columns 0, 2, 3 for all rows
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ 注意: 以下のコードは、ローカルの Python 環境で実行する必要があります。


(1) ▶ サンプル

TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: ブールマスクによるフィルタリング (難易度 ⭐)

PYTHON
import numpy as np

scores = np.array([55, 82, 91, 47, 73, 100, 68])

passing = scores[scores >= 60]
print("Passing:", passing)  # [82 91 73 100 68]

excellent = scores[scores >= 90]
print("Excellent:", excellent)  # [91 100]

# Multiple conditions
mid = scores[(scores >= 60) & (scores < 90)]
print("Mid-range:", mid)  # [82 73 68]
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ 注意: 以下のコードは、ローカルの Python 環境で実行する必要があります。

(2) ▶ サンプル

TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: 条件付き置換のための np.where (難易度 ⭐⭐)

PYTHON
import numpy as np

# Clip to range: replace values outside [0, 100]
data = np.array([-5, 120, 30, -20, 80, 200])
clipped = np.where(data < 0, 0, np.where(data > 100, 100, data))
print("Clipped:", clipped)  # [  0 100  30   0  80 100]

# Categorize
grades = np.array([45, 72, 88, 55, 91])
letter = np.where(grades >= 85, 'A',
          np.where(grades >= 70, 'B',
          np.where(grades >= 60, 'C', 'D')))
print("Grades:", letter)  # ['D' 'B' 'A' 'D' 'A']
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ 注意: 以下のコードは、ローカルの Python 環境で実行する必要があります。



6. 比較表

(1) 索引付けの方法

メソッド 構文 戻り値 コピーを行うか? 使用例
基本スライス a[1:3] 表示 いいえ サブ配列、連続した範囲
整数インデックス a[2] スカラー 該当なし 単一要素
ブールマスク a[mask] 1次元配列 はい 条件付きフィルタリング
高度なインデックス機能 a[[1,3,5]] 配列 はい 任意の順序での選択
np.where np.where(cond, x, y) 配列 はい 三項選択

(2) ブール式と凝った式

機能 ブールマスク 高度なインデックス作成
構文 arr[arr > 0] arr[[1, 3, 5]]
選択ロジック 条件ベース 位置ベース
結果の形状 1次元(平坦化) インデックス配列と同じ形状
処理速度 大きなマスクの場合に高速 疎な選択の場合に高速

(1) ▶ サンプル:np.ix_ を使った 2 次元ファンシーインデックス(難易度 ⭐⭐)

PYTHON
import numpy as np

arr = np.arange(20).reshape(4, 5)
print("Original:\n", arr)

# Select specific rows and columns
rows = [0, 2, 3]
cols = [1, 3]
result = arr[np.ix_(rows, cols)]
print("Rows [0,2,3], Cols [1,3]:\n", result)

# Modify selected elements
arr[np.ix_([0, 1], [0, 4])] = -1
print("After modification:\n", arr)

出力:

TEXT
原文:
 [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
行 [0,2,3]、列 [1,3]:
 [[ 1  3]
 [11 13]
 [16 18]]
修正後:
 [[-1  1  2  3 -1]
 [-1  6  7  8 -1]
 [10 11 12 13 14]
 [15 16 17 18 19]]


❓ よくある質問

Q ブール値のマスクを使って値を修正することはできますか?
A はい!arr[arr > 0] = 0は、すべての正の値を0に設定します。これはインプレース変更です。np.where(arr > 0, 0, arr)は、代わりに新しい配列を返します。
Q arr[mask] と np.where(mask) の違いは何ですか?
A arr[mask] は、mask が True となる要素の値を返します。 np.where(mask) は、mask が True である場所の値を返します。arr[mask] は値を取得する場合に、np.where(mask) は位置情報を取得する場合に使用します。
Q 2次元配列で高度なインデックス指定はできますか?
A はい。arr[[0,2], [1,3]] は (0,1) および (2,3) の要素を選択します。行と列を個別に選択するには、arr[np.ix_([0,2], [1,3])] を使用してください。
Q ブールマスクは常に1次元配列を返しますか?
A 2次元以上の配列の場合、そうです。マスクは結果を1次元配列に平坦化します。np.where(mask) を使用すると、元の形状のインデックスを取得できます。

📖 まとめ



📝 練習問題

  1. 初心者向け(難易度 ⭐):-10 から 10 までの範囲のランダムな整数 20 個からなる配列を作成してください。ブール値のマスクを使用して、すべての正の値を抽出してください。また、np.where を使用して、すべての負の値を 0 に置き換えてください。

  2. 中級(難易度 ⭐⭐):0~100のランダムな整数からなる5×5の配列を作成してください。 ブール値のマスクを使用して、(a) 50より大きい値を数え、(b) 20より小さい値を20に置き換え、(c) np.where を使用して、80より大きいすべての値の行インデックスと列インデックスを抽出してください。

  3. 上級(難易度 ⭐⭐⭐):生徒の得点を格納する10×4の配列を作成してください(生徒10人、科目4つ)。 高度なインデックス操作を用いて、次のことを行いなさい:(a) すべての科目について、位置 [0,3,7] にいる生徒を選択する、(b) すべての生徒について、位置 [1,3] にある科目を選択する、(c) 総合得点の上位3名の生徒の平均を計算する。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%