データ分析実践
初級問題チェック
問題 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)

