numpy.dstackは、配列を奥行き方向に重ねていく関数です。dstack「d」は「depth(奥行き)」の頭文字です。「stack」は「重ねる」なので、「奥行きを重ねる」ということです。
それでは、実際のコードを見て確認していきましょう。
1. numpy.dstackの使い方
まずは、基本的な書き方を確認しましょう。
書き方:
np.dstack(tup)
パラメーター:
引数 | 型 | 解説 |
tup | sequence of ndarrays | ここで指定した配列同士を横に重ねます。3つ目の軸(axis=2)を除いて配列同士のshapeが合致している必要があります。ただし1次元配列同士と2次元配列同士の場合は、shapeが完全に一致している必要があります。 |
戻り値:
要素を重ねた新しいndarray |
一緒に確認したい関数:
- stack: 配列同士を新しい軸にそって重ねる。
- vstack: 配列同士を垂直に重ねる。
- hstack: 配列同士を水平に重ねる。
- concatenate: 配列同士を既に存在する軸にそって連結する。
- dsplit:
3次元配列以上を重ねる場合、np.dstack()は、「axis=2」でnumpy.concatenateで連結するのと同じです。3次元配列同士を重ねる場合は、「axis=2」、つまり列以外のshapeが一致している必要があります。
1次元配列同士の場合は、3次元配列に変換してから重ねられます。
例えば、shape(N, )の1次元配列同士を重ねる場合は、まず、shape(1, N, 1)の3次元配列を生成します。そして1次元配列同士を2つ重ねるとshape(1, N, 2)が、3つ重ねるとshape(1, N, 3)の3次元配列が生成されます。
なお、1次元配列同士を重ねる場合は、shapeが完全に一致している必要があります。
2次元配列同士を重ねる場合は、まず、shape(N, M)の2次元配列を、shape(N, M, 1)の3次元配列に変換してから重ねます。そして2次元配列を2つ重ねるとshape(N, M, 2)、3つ重ねると(N, M, 3)の3次元配列が生成されます。
また、2次元配列同士を重ねる場合も、shapeが完全に一致している必要があります。
numpy.dstackは、主に3次元までの配列を扱う際に用いられます。例えば、「高さ・幅・r/g/b」をもつピクセルデータのようなデータを扱うような場合です。
それでは、実際のコードで、使い方を確認していきましょう。
1.1. 1次元配列の場合は3次元配列にして列を重ねる
まずは1次元配列同士の場合を見ていきましょう。
1次元配列は、shape(N, )の1次元配列を、shape(1, N, 1)の3次元配列に変換してから列を重ねていきます。例えば、以下のコードでは、shape(3,)の1次元配列を重ねているので、shape(1, 3, 2)の3次元配列が生成されています。
import numpy as np
''' 1次元配列同士では奥行き1×行数n×列数2の3次元配列を生成します。 '''
# 元の配列①を生成
arr1 = np.arange(3)
# 元の配列②を生成
arr2 = np.arange(3, 6)
# ①と②を重ねた新しい配列を生成
arr3 = np.dstack((arr1, arr2))
print('arr1: 元の配列①\n', arr1, '\n')
print('arr2: 元の配列②\n', arr2, '\n')
print('arr3: 新しい配列\n', arr3, '\n')
print('arr3のshape\n', arr3.shape, '\n')
print('arr3の次元数\n', arr3.ndim)
配列は好きなだけ重ねることができます。
以下のコードではshape(3,)の1次元配列を3つ重ねているので、shape(1, 3, 3)の3次元配列が生成されます。
''' 重ねた配列の数だけ列数が増えていきます。 '''
# 元の配列③を生成
arr4 = np.arange(6, 9)
# ①と②と③を重ねた新しい配列を生成
arr5 = np.dstack((arr1, arr2, arr4))
print('arr5: 新しい配列\n', arr5, '\n')
print('arr5のshape\n', arr5.shape, '\n')
print('arr5の次元数\n', arr5.ndim)
なお、1次元配列同士の場合はshape(列数)が異なるとエラーになります。
''' 列数が異なる1次元配列同士だとエラーになります。 '''
# 4列(要素数4)の1次元配列④を生成
arr6 = np.arange(4)
print('arr1: 元の配列①\n', arr1, '\n')
print('arr6: 元の配列④\n', arr6, '\n')
print('新しい配列\n', np.dstack((arr1, arr6)))
1.2. 2次元配列の場合は3次元配列に変換して列を重ねる
続いて2次元配列同士の場合です。
2次元配列は、例えば、shape(N, M)の2次元配列は、shapeが(N, M, 1)の3次元配列に変換されてから、列が重ねられます。
以下のコードでは、shape(2, 3)の2次元配列を重ねているので、shape(2, 3, 2)の3次元配列が生成されています。
''' 2次元配列同士では、奥行き2×行数n×列数2の三次元配列を生成します。 '''
# 元の2次元配列①を生成
arr7 = np.arange(6).reshape(2, 3)
# 元の2次元配列②を生成
arr8 = np.arange(6, 12).reshape(2, 3)
# ①と②を重ねた新しい配列を生成
arr9 = np.dstack((arr7, arr8))
print('arr7: 元の2次元配列①\n', arr7, '\n')
print('arr8: 元の2次元配列②\n', arr8, '\n')
print('arr9: 新しい配列\n', arr9, '\n')
print('arr9のshape\n', arr9.shape, '\n')
print('arr9の次元数\n', arr9.ndim)
重ねた2次元配列の数だけ列数が増えていきます。
以下のコードでは、shape(2, 3)の2次元配列を3つ重ねているので、shape(2, 3, 3)の3次元配列が生成されます。
''' 重ねた配列の数だけ列数が増えていきます。 '''
# 元の2次元配列③を生成
arr10 = np.arange(12, 18).reshape(2, 3)
# ①と②と③を重ねた3次元配列を生成
arr11 = np.dstack((arr7, arr8, arr10))
print('arr11: 新しい配列\n', arr11, '\n')
print('arr11のshape\n', arr11.shape, '\n')
print('arr11の次元数\n', arr11.ndim)
なお、2次元配列同士の場合は、shapeが異なるとエラーになります。
''' 行数、列数のどちらか一方でも違うとエラーになります。 '''
# 2次元配列④を生成
arr12 = np.arange(6, 8).reshape(2, 1)
print('arr7: 元の2次元配列①\n', arr7, '\n')
print('arr12: 元の2次元配列④\n', arr12, '\n')
# 配列のshapeが異なるのでエラー
np.dstack((arr7, arr12))
1.3. 3次元配列同士の場合は列を重ねる
最後に3次元配列同士の場合です。
この場合は、「axis=2」でnumpy.concatenateで連結するのと同じで、列が重ねられていきます。例えば、shape(N, M, 1)の3次元配列を2つ重ねると、shape(N, M, 2)の3次元配列になります。
以下のコードでは、shape(2, 2, 3)の配列を重ねているので、shape(2, 2, 6)の3次元配列が生成されています。
''' 3次元配列以上では奥行き数と行数は同じで列を重ねる。 '''
# 3次元配列①を生成
arr13 = np.arange(12).reshape(2, 2, 3)
# 3次元配列②を生成
arr14 = np.arange(12, 24).reshape(2, 2, 3)
# ①と②の行を重ねる
arr15 = np.dstack((arr13, arr14))
print('arr13: 元の3次元配列①\n', arr13, '\n')
print('arr14: 元の3次元配列②\n', arr14, '\n')
print('arr15: 新しい配列\n', arr15, '\n')
print('arr15のshape\n', arr15.shape, '\n')
print('arr15の次元数\n', arr15.ndim)
重ねただけ列数が増えていきます。
以下のコードでは、shape(2, 2, 3)の配列を3つ重ねているので、shape(2, 2, 9)の3次元配列が生成されています。
''' 3次元配列の場合は重ねた分だけ列数が増えていきます。 '''
# 3次元配列③を生成
arr16 = np.arange(24, 36).reshape(2, 2, 3)
# 3次元配列①と②と③を重ねる
arr17 = np.dstack((arr13, arr14, arr16))
print('arr13: 元の3次元配列①\n', arr13, '\n')
print('arr16: 元の3次元配列②\n', arr16, '\n')
print('arr17: 新しい配列\n', arr17, '\n')
print('arr17のshape\n', arr17.shape, '\n')
print('arr17の次元数\n', arr17.ndim)
奥行きと行数が揃っていれば、列数が異なる3次元配列同士を重ねることができます。
以下のコードではshape(2, 2, 3)とshape(2, 2, 4)同士を重ねて、shape(2, 2, 7)の3次元配列を生成しています。
''' 奥行きと行数が揃っていれば、列数が異なっても重ねることが可能です。 '''
# 3次元配列④を生成
arr18 = np.arange(12, 28).reshape(2, 2, 4)
# 配列①と④は奥行きと行数が揃っているので重ねることが可能
arr19 = np.dstack((arr13, arr18))
print('arr13: 元の3次元配列①\n', arr13, '\n')
print('arr18: 元の3次元配列④\n', arr18, '\n')
print('arr19: 新しい配列\n', arr19, '\n')
print('arr19のshape\n', arr19.shape, '\n')
print('arr19の次元数\n', arr19.ndim)
しかし、奥行きと行数のどちらか一方でも揃っていなければエラーになります。
''' 奥行きと行数が一方でも揃っていなければエラーになります。 '''
# 3次元配列⑤を生成
arr20 = np.arange(12, 18).reshape(2, 1, 3)
print('arr13: 元の3次元配列①\n', arr13, '\n')
print('arr20: 元の3次元配列⑤\n', arr20, '\n')
# 配列①と⑤は行数が揃っていないのでエラー
np.dstack((arr13, arr20))
2. まとめ
以上が、numpy.dstackの使い方です。同じような関数として、以下も確認しておくと良いでしょう。
- numpy.concatenate: 配列を連結
- numpy.stack: 配列を連結して次元数が1つ上の配列を生成
- numpy.hstack: 配列を水平に連結
- numpy.vstack: 配列を垂直に連結
コメント