Pythonライブラリ講座

【NumPy】”where”とは?配列によるデータ操作を徹底解説!

前のページ|次のページ

5章ではNumPyの関数である『numpy.where()』と『numpy.any()』『numpy.all()』について解説します。

いずれの関数もデータ分析において非常に役に立つものです。ぜひ最後までご覧ください!

本連載講座【Python ライブラリ編】では、データサイエンスに必要なPythonライブラリやその使い方を基礎から学ぶことができます。

NumPyPandasMatplotlibScipySeabornについて、初学者の方にも分かりやすいよう丁寧に解説しています。

さらに、学習した内容を定着させられるように各章演習問題を用意しています。

・Pythonでデータ分析ができるようになりたい

・Pythonの基礎事項は一通り学んだので、さらに深く学びたい

このように考えている方はTech Teacherが運営する【Python ライブラリ編】で、Pythonによるデータサイエンスの学習をすることをお勧めします!

なお、『Pythonについて全く知らない』・『Pythonの基礎事項がまだ分かっていない』という方は、まずコチラの【Python 基礎編】で基礎を一通り学習してからライブラリ編に取り掛かりましょう!

<ライブラリ編 目次>

<ライブラリの基礎>
1章:ライブラリとは

<NumPy>
2章:NumPyの概要と配列(ndarray)
3章:統計量や次元の取得/ソート
4章:配列のインデックス
5章:numpy.whereによる条件制御
6章:配列の結合/分割
7章:乱数

<SciPy>
8章:SciPyの概要と基本操作

<Pandas>
9章:SeriesDataFrame/統計量の取得
10章:データの読み込み/書き込み
11章:データの取り出し/追加
12章:データのソート
13章:データの結合
14章:階層型インデックス
15章:groupbyによる集計
16章:マッピング処理
17章:欠損値の扱い

<Matplotlib>
18章:Matplotlibの概要
19章:pyplotインターフェース
20章:オブジェクト指向インターフェース

<Seaborn>
21章:Seabornの概要と基本操作

numpy.where()による条件制御

numpy.where()とは?

numpy.where()』関数を用いると、2つの配列から値を取り出すとき、条件によって取り出す値を選択することができます。

この関数の書式は以下のようになります。

np.where(条件の配列, 配列1, 配列2)

where()は、条件の配列がTrueのときは配列1のデータ、Falseのときは配列2のデータを取り出した新たな配列を作成します。

例えば条件の配列の3番目の値がTrueの場合、配列1の3番目の値が取り出されます。

where イメージ

条件の配列真偽値を要素とする配列(真偽値配列)で、配列に対する条件式を書くことで作成することができます。

条件式真偽値配列については以下の記事で詳しく解説していますので、分からないという方はぜひ参照してください!

使い方①:条件に基づいて値を選択

まずは2つの配列から条件によって取り出す値を選択し、新たな配列を作るという使い方を紹介します。

以下の例では、配列aの要素が10未満のとき配列xから、10以上のとき配列yから値を取り出した新たな配列を作成しています。

a = np.array([1,12,3,5,20,3,15,16]) #条件の元になる配列
x = np.array([1,2,3,4,5,6,7,8])
y = np.array([10,20,30,40,50,60,70,80])

# aの要素が10未満の位置はxから、その他はyから取り出す
print(np.where(a < 10, x, y))
[ 1 20  3  4 50  6 70 80]

aの2,5,7,8番目の要素は10以上の値なので、新たな配列の2,5,7,8番目の値はxから取り出されています。

一方その他の要素はyから取り出されていることが分かりますね。

なお、最初の引数「a < 10」は、aの要素が10未満の位置にTrue、それ以外の位置にFalseが格納された真偽値配列と等価です。

a = np.array([1,12,3,5,20,3,15,16]) #条件の元になる配列

#配列に対する条件式は真偽値配列を返す
print(a < 10)
[ True False  True  True False  True False False]

使い方②:条件に応じて要素を置換

使い方①の応用として、条件に応じて配列の要素を置換する処理を行うことができます。

np.where(条件, 値1, 値2)

とすることで、条件を満たした場合は値1、満たさない場合は値2で元の配列を置換します。

例えば以下の例では、配列aの要素が偶数の時’even’、奇数の時’odd’で値を置換した、新たな配列を取得しています。

a = np.array([1,12,3,5,20,3,15,16]) #条件の元になる配列

#偶数ならeven、奇数ならoddで置換
a_even_odd = np.where(a % 2 == 0, 'even', 'odd')
print(a_even_odd)
['odd' 'even' 'odd' 'odd' 'even' 'odd' 'odd' 'even']

この動作には、NumPy特有のブロードキャストと呼ばれる処理が用いられています。

今回の場合は、第二、第三引数がそれぞれ「[‘even’, ‘even’,…]」「[‘odd’, ‘odd’,…]」のような配列に変換されています。

その後、使い方①と同じ処理を行うことで、要素が置換されます。

ブロードキャストについては以下の記事で詳しく解説しています!

any/all関数による真偽値の判定

any()』関数や『all()』関数を用いることで、真偽値の判定を行うことができます。

numpy.any()

any()』関数を用いることで、真偽値配列にTrueが少なくとも1つ含まれるかどうかを判定できます。

np.any(真偽値配列)

とすると、真偽値配列にTrueが少なくとも1つあればTrue、すべての要素がFalseならFalseを返します。

#真偽値配列1
bool_arr_1 = np.array([False, False, True, False, True])
#真偽値配列2
bool_arr_2 = np.array([False, False, False])

print(np.any(bool_arr_1))
print(np.any(bool_arr_2))
True
False

ところで、配列に対する条件式真偽値配列を返します。

これを利用して、any()により「配列の中に条件を満たす要素が存在するか」を確かめることができます。

以下の例では、xに含まれる123が3の倍数のためTrueが返されます。

一方yには2の倍数(偶数)が1つも含まれないため、Falseが返されます。

x = np.array([2579,18509,4567,559,123,2620])
y = np.array([1,3,5,7,9])

print(np.any(x % 3 == 0)) #xに3の倍数は含まれるか
print(np.any(y % 2 == 0)) #yに偶数は含まれるか
True
False

numpy.all()

all()』関数を用いることで、真偽値配列の要素がすべてTrueかどうかを判定できます。

np.all(真偽値配列)

とすると、真偽値配列の要素がすべてTrueであればTrue、1つでもFalseならFalseを返します。

#真偽値配列3
bool_arr_3 = np.array([False, False, True, False, True])
#真偽値配列4
bool_arr_4 = np.array([True, True, True])

print(np.all(bool_arr_3))
print(np.all(bool_arr_4))
False
True

またanyと同じように、allにより「配列のすべての要素が条件を満たすか」を確かめることができます。

z = np.array([3,6,9,12,15,18])
w = np.array([1,2,3,4,5,6,7,8,9,10])

print(np.all(z % 3 == 0)) #zのすべての要素が3の倍数かどうか
print(np.all(w < 10)) #wのすべての要素が10未満かどうか
True
False

5章の練習問題

以下の練習問題を解いてみましょう。

練習問題

問1. 以下の配列a,y,zに対して、(1)~(2)を求めて出力してください。

a = np.array([1,2,3,4,5])

x = np.array([10,20,30,40,50])
y = np.array([100,200,300,400,500])

(1) aの要素が奇数ならxから、偶数ならyから取り出した値をもつ配列
(2) aの要素のうち、2以下の数を1、2より大きい数を-1で置き換えた配列

問2. 以下の配列dataに対して、(1)~(2)の問いに答えてください。

data = np.array([61829,35578,66535,96610,26073,67574,86356,87815,41316,24532])

(1) dataの中に17の倍数は存在するか
(2) dataのすべての要素が17の倍数であるか

解答

問1(クリックして解答を表示)

a = np.array([1,2,3,4,5])
x = np.array([10,20,30,40,50])
y = np.array([100,200,300,400,500])

arr1 = np.where(a % 2 == 1, x, y)
arr2 = np.where(a <= 2, 1, -1)
print('(1):', arr1)
print('(2):', arr2)
(1): [ 10 200  30 400  50]
(2): [ 1  1 -1 -1 -1]

問2(クリックして解答を表示)

data = np.array([61829,35578,66535,96610,26073,67574,86356,87815,41316,24532])

print('(1):', np.any(data % 17 == 0))
print('(2):', np.all(data % 17 == 0))
(1): True
(2): False

次のページへ

【NumPy】配列の結合・分割を完全マスター!練習問題付き 前のページ|次のページ 6章ではNumPy配列(ndarray)の結合・分割ができる『numpy.concatenate()』と...