配列にデータ列を1カラムしたいことがあったが、スマートに書けずに詰まってしまった。色々と触ってみたらnumpyの行列の概念について気づきがあったのでまとめておく。
背景
X: n*m行列(n:データ数、m:特徴量次元)の標本データと、正解ラベルy:n個 ( np.array([])
で定義。後述の通り、行・列の両方として機能)があるとき、配列Xのm+1列目に正解ラベルyを追加して、データ一覧と正解ラベルを並べて見たいことがあった。
具体的には下記のようなことである。
X = np.array([[1,2],[3,4],[5,6]])
y = np.array('a','b','c')
上のようなデータがあるとき、次のように標本データに正解ラベルのカラムを1列追加したい
-> array([[1,2,'a'],
[3,4,'b'],
[5,6,'c']])
やりかた
vstackを使う方法
Xを転置させ、正解ラベルyを末尾に1行連結する。最後に全体を転置して完成。
np.vstack((X.T, y)).T
appendを使う方法
yを明示的にn行1列の配列としてリサイズする。axis=1とすることでXにyを列方向に連結する。
np.append(X, y.reshape(len(y), 1), axis=1)
変則的な別解
あらかじめ正解ラベルをy = np.array([['a','b','c']])
として[]
を二重にして、1行3列の配列として生成させる。ここで、y.Tとすると下記のように3行1列となる。
array([
['a'],
['b'],
['c']
])
よって、この場合は下記のコマンドでうまくいく。
np.append(X, y.T, axis=1)
わかったこと
・1行3列を明示的に表現するには np.array([[1,2,3]])
・np.array([1,2,3])
と表記すると1行3列の配列になると思い込んでいたが、shapeを確認すると(3,)と出力された。np.array([1,2,3).T
としても同様。
・すなわち、np.array([1,2,3])と表記しただけでは行や列の概念がないと解釈できる。(というより、臨機応変に「行」や「列」として動作しているようだ)