データ分析実践
初級問題チェック

問題 35 /40

NumPyによる画像の加工に関して、誤った説明はどれか。 arr ▶︎ array([[[ 1, 2, 3], [ 4, 5, 6], [ 7, 8, 9]], [[11, 12, 13], [14, 15, 16], [17, 18, 19]], [[21, 22, 23], [24, 25, 26], [27, 28, 29]]]) arr.shape ▶︎ (3, 3, 3) 配列の形式はCHW(色x高さx幅)で、色の順番はRGBとする。

選択 1

x = arr[:, 0, 0] arr[:, 2, 2] = x ▶︎ 切り取って、貼り付けている。

選択 2

x, y, z = np.split(arr, 3, axis=1) ▶︎ 3分割している。

選択 3

np.rot90(arr, k=3) ▶︎ 時計回りに3回転させている。

選択 4

np.flip(arr, axis=1) ▶︎ 反転させている。

解説

選択肢3が正解です。 画像の拡大・縮小はNumPyだけで対応するのは難しいですが、切り取り/貼り付け、分割、回転、反転、複製などはNumPyで対応できます。 問題文のデータです。 arr = np.array( [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[11, 12, 13], [14, 15, 16], [17, 18, 19]], [[21, 22, 23], [24, 25, 26], [27, 28, 29]]]) arr.shape ▶︎ (3, 3, 3) 配列の形式はCHW(色x高さx幅)で、色の順番はRGBとします。
【選択肢1】 x = arr[:, 0, 0] arr[:, 2, 2] = x ▶︎ 切り取って、貼り付けている。 正しい説明です。 ndarrayの一部を指定して切り取り、元のndarrayの一部を置き換えています。 x = arr[:, 0, 0] x ▶︎ array([ 1, 11, 21]) arr[:, 0, 0]は、arr[axis=0, axis=1, axis=2]の順に指定しています。 axis=0が「:」でRGBの全ての色を指定、axis=1がインデックス番号0で一番上の行を指定、axis=2がインデックス番号0で一番左の列を指定しています。その結果、左上のピクセルを取得しています。 arr[:, 2, 2] = x arr ▶︎ array([[[ 1, 2, 3], [ 4, 5, 6], [ 7, 8, 1]], [[11, 12, 13], [14, 15, 16], [17, 18, 11]], [[21, 22, 23], [24, 25, 26], [27, 28, 21]]]) 右下のピクセルが、左上の「1、11、21」に置き換わっています。 【選択肢2】 x, y, z = np.split(arr, 3, axis=1) ▶︎ 3分割している。 正しい説明です。 split関数は第一引数で対象のndarray、第二引数で分割数を指定します。分割前と分割後で、要素数を合わせる必要あります。例えば3行のndarrayを4分割しようとするとエラーになります。 w, x, y, z = np.split(arr, 4, axis=1) ▶︎ ValueError: array split does not result in an equal division 問題文のndarrayの場合、配列の形式がCHW(色x高さx幅)のため、axis=1で縦方向(行)、axis=2で縦方向(列)に分割します。 x, y, z = np.split(arr, 3, axis=1) x ▶︎ array([[[ 1, 2, 3]], [[11, 12, 13]], [[21, 22, 23]]]) y ▶︎ array([[[ 4, 5, 6]], [[14, 15, 16]], [[24, 25, 26]]]) z ▶︎ array([[[ 7, 8, 9]], [[17, 18, 19]], [[27, 28, 29]]]) axisの指定は配列の形式によって変わります。PillowやOpenCVのHWC(高さx幅x色)であれば、axis=0で縦方向、axis=1で横方向に分割されます。 CHW(色x高さx幅)の配列は、ディープラーニングのライブラリPyTorchで採用されています。軸は「奥行き、縦、横」の順番です。 PillowやOpenCVの軸の順番は「縦、横、奥行き」になり、次のイメージです。
問題文の配列をHWCの順番に変換すると、次の配列になります。 np.transpose(arr, (1, 2, 0)) ▶︎ array([[[ 1, 11, 21], [ 2, 12, 22], [ 3, 13, 23]], [[ 4, 14, 24], [ 5, 15, 25], [ 6, 16, 26]], [[ 7, 17, 27], [ 8, 18, 28], [ 9, 19, 29]]]) RGBが横に並び、奥に高さ、縦に幅が配置されるため、直感的ではありません。そのため、問題文はCHWの配列にしています。 【選択肢3】 np.rot90(arr, k=3) ▶︎ 時計回りに3回転させている。 誤った説明です。 rot90は時計周りではなく反時計回りに回転させます。rot90は90度単位で回転させる関数で、引数kで回転数を指定します。 np.rot90(arr, k=3) ▶︎ array([[[21, 22, 23], [11, 12, 13], [ 1, 2, 3]], [[24, 25, 26], [14, 15, 16], [ 4, 5, 6]], [[27, 28, 29], [17, 18, 19], [ 7, 8, 9]]]) 【選択肢4】 np.flip(arr, axis=1) ▶︎ 反転させている。 正しい説明です。 問題文のndarrayの場合、配列の形式がCHW(色x高さx幅)のため、axis=1で上下方向に反転します。 np.flip(arr, axis=1) ▶︎ array([[[ 7, 8, 9], [ 4, 5, 6], [ 1, 2, 3]], [[17, 18, 19], [14, 15, 16], [11, 12, 13]], [[27, 28, 29], [24, 25, 26], [21, 22, 23]]]) axis=2で左右方向に反転します。 np.flip(arr, axis=2) ▶︎ array([[[ 3, 2, 1], [ 6, 5, 4], [ 9, 8, 7]], [[13, 12, 11], [16, 15, 14], [19, 18, 17]], [[23, 22, 21], [26, 25, 24], [29, 28, 27]]]) axis=(1, 2)とすると、上下左右に反転します。 np.flip(arr, axis=(1, 2)) ▶︎ array([[[ 9, 8, 7], [ 6, 5, 4], [ 3, 2, 1]], [[19, 18, 17], [16, 15, 14], [13, 12, 11]], [[29, 28, 27], [26, 25, 24], [23, 22, 21]]]) HWCの配列の場合、axis=0で上下方向、axis=1で左右方向の反転になります。 (公式書籍 p.257-260)