0Pricing
Pandas & NumPy Academy · レッスン

ブールマスキングとFancy Indexing

ブール条件で配列をフィルタリングし、整数インデックス配列を使って任意の要素を選択します。

「ブールマスキングとFancy Indexing」はCoddyKit上の無料Pandas & NumPy Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPandas & NumPy Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

マスクとしてのブール配列

ブールマスクとは、TrueまたはFalseの値を持つ配列です。インデックスとして使うと、Trueと指定された要素だけを残せます。これは基本的なフィルタリング方法です。

import numpy as np

a = np.array([5, 3, 8, 1, 9, 2, 7])
mask = a > 4
print(mask)       # [ True False  True False  True False  True]
print(a[mask])    # [5 8 9 7]

複合ブール条件

&(and)、|(or)、~(not)を使って複合的なフィルターを作成できます。各条件は必ず括弧で囲んでください。そうしないと演算子の優先順位で意図しない結果になります。

import numpy as np

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

# Elements between 4 and 8 inclusive
result = a[(a >= 4) & (a <= 8)]
print(result)   # [7 6 4 8]

# Elements less than 3 or greater than 7
result2 = a[(a < 3) | (a > 7)]
print(result2)  # [2 9 1 8]

ブールインデックスで値を変更する

ブール選択の結果に直接代入すると、一致する要素だけをその場で変更できます。外れ値を上限値に置き換えたり、欠損値を埋めたりするのに最も高速な方法です。

import numpy as np

a = np.array([5, -3, 8, -1, 2, -7])
a[a < 0] = 0    # zero out negatives in-place
print(a)        # [5 0 8 0 2 0]

# Cap values above 6
a[a > 6] = 6
print(a)        # [5 0 6 0 2 0]

2次元配列のブールマスク

2次元配列にブールマスクを適用すると、常にフラットな1次元の結果が返されます。行全体を選択するには、1つの列から1次元マスクを作り、axis 0に沿ってインデックスを指定します。

import numpy as np

m = np.array([[1, 5], [3, 2], [8, 4], [6, 7]])
# Select rows where first column > 4
mask = m[:, 0] > 4
print(mask)     # [False False  True  True]
print(m[mask])  # [[8 4] [6 7]]

マスクと np.where

np.where(condition, x, y)は配列の形状を維持します。条件を満たす位置ではxを、それ以外ではyを選びます。配列を平坦化せずに値を置き換えるのに最適です。

import numpy as np

a = np.array([3, -1, 5, -2, 4])
result = np.where(a >= 0, a, 0)  # keep positives, replace negatives
print(result)  # [3 0 5 0 4]

# Recode: above-average -> 'high', else -> 'low'
labels = np.where(a >= a.mean(), 'high', 'low')
print(labels)  # ['high' 'low' 'high' 'low' 'high']

ファンシーインデックスの基本

ファンシーインデックスとは、整数インデックスの配列を渡して、特定の要素を取得する方法です。順番を自由に指定でき、重複も可能です。必ずコピーが返されます。

import numpy as np

a = np.array([10, 20, 30, 40, 50])
idx = np.array([4, 1, 1, 3])
print(a[idx])   # [50 20 20 40]

# 2D index shape -> 2D output
idx2d = np.array([[0, 2], [4, 1]])
print(a[idx2d])  # [[10 30] [50 20]]

2次元配列のファンシーインデックス

2次元配列では、対応するインデックス配列の組によって散在する点を選択できます。m[rows, cols]は、各(row, col)の組にある要素を取得します。部分行列全体を取得するわけではありません。

import numpy as np

m = np.array([[1,  2,  3],
              [4,  5,  6],
              [7,  8,  9]])

# Select elements at (0,2), (1,0), (2,1)
rows = [0, 1, 2]
cols = [2, 0, 1]
print(m[rows, cols])  # [3 4 8]

行と列の格子選択のための np.ix_

np.ix_は、指定した行と列のすべての組み合わせから部分行列を選択します。単なる組み合わせではなく、多数の行と列を選びたい場合に便利です。

import numpy as np

m = np.arange(16).reshape(4, 4)
print(m)

# Select rows 0,2 and columns 1,3
ix = np.ix_([0, 2], [1, 3])
print(m[ix])
# [[ 1  3]
#  [ 9 11]]

np.nonzero() と np.argwhere()

np.nonzeroは、0ではない要素(またはTrueの要素)のインデックスを、軸ごとのタプルとして返します。np.argwhereは同じ情報を、読みやすい行形式でまとめて返します。

import numpy as np

a = np.array([0, 3, 0, 5, 0, 7])
print(np.nonzero(a))       # (array([1, 3, 5]),)
print(np.argwhere(a > 0))  # [[1] [3] [5]]

ブールインデックスとファンシーインデックスの組み合わせ

2つの方法を組み合わせることもできます。ブールマスクで行をフィルタリングし、その後ファンシーインデックスで列の順序を変更します。これにより、データの抽出と並べ替えを1つの簡潔な処理で行えます。

import numpy as np

data = np.array([[1, 2, 3],
                 [4, 5, 6],
                 [7, 8, 9]])
scores = np.array([0.9, 0.3, 0.8])

# Keep high-scoring rows, reorder columns to [2, 0, 1]
high = data[scores > 0.5]
reordered = high[:, [2, 0, 1]]
print(reordered)

パフォーマンス:ブールインデックスとファンシーインデックス

ブールインデックスもファンシーインデックスもコピーを返します。フィルタリングでは、通常ブールマスクが最も読みやすく、十分に高速です。まずはこれを使うのがおすすめです。

import numpy as np

a = np.random.rand(1_000_000)

# Boolean mask -- readable and fast
result = a[a > 0.5]
print('filtered size:', result.size)  # ~500000

# Equivalent with np.where + fancy index
idx = np.where(a > 0.5)[0]
result2 = a[idx]
print('same result:', np.array_equal(result, result2))

理解度チェック

このレッスンで学んだブールマスクとファンシーインデックスについて、理解度を確認しましょう。

レッスンのまとめ

よくできました。ブールマスクはフィルタリングしてコピーを作成し、np.whereは配列の形状を維持し、ファンシーインデックスは指定した任意の要素を取得します。次はPandas Seriesです。

よくある質問

「ブールマスキングとFancy Indexing」レッスンは無料ですか?

はい。「ブールマスキングとFancy Indexing」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Pandas & NumPy Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

「ブールマスキングとFancy Indexing」で何を学びますか?

ブール条件で配列をフィルタリングし、整数インデックス配列を使って任意の要素を選択します。 ブラウザで直接実行するハンズオンコードでPandas & NumPy Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Pandas & NumPy Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPandas & NumPy Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「ブールマスキングとFancy Indexing」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPandas & NumPy Academyレッスンでコードを書いて実行できますか?

はい。すべてのPandas & NumPy Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ユニバーサル関数(ufunc)
  2. 集約関数
  3. ブロードキャストの規則
  4. ブールマスキングとFancy Indexing
← Pandas & NumPy Academyに戻る