今回は NumPy で正方行列を扱うとき、上三角行列とか下三角行列を取り出す方法について。 三角行列というのは、正方行列において対角要素より上の成分が全て 0 だったり、下の成分が全て 0 だったりする行列のこと。 ちなみに、最初この呼び方を知らなくて「行列 斜め 上」とかでたくさんぐぐった。
使った環境は次の通り。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.12.6 BuildVersion: 16G1036 $ python --version Python 3.6.3
インストール
ひとまず、何はともあれ NumPy はインストールしておく。
$ pip install numpy
サンプル用の正方行列を用意する
まずは、加工する前の正方行列を用意する。 今回は 1 ~ 25 の数字を入れた配列を 5 x 5 の正方行列にして使おう。
>>> import numpy as np >>> array = np.arange(1, 5 * 5 + 1).reshape(5, 5)
中身はこんな感じ。
>>> array array([[ 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]])
上三角行列 (対角要素あり)
まず、一番簡単なのは対角要素のある上三角行列かな。
これは単純に numpy.triu()
関数に正方行列を渡すだけで得られる。
>>> np.triu(array) array([[ 1, 2, 3, 4, 5], [ 0, 7, 8, 9, 10], [ 0, 0, 13, 14, 15], [ 0, 0, 0, 19, 20], [ 0, 0, 0, 0, 25]])
簡単だね。
上三角行列 (対角要素なし)
続いて対角要素のない上三角行列を。
これは numpy.triu()
関数の k
オプションに 1
を渡してやれば良い。
>>> np.triu(array, k=1) array([[ 0, 2, 3, 4, 5], [ 0, 0, 8, 9, 10], [ 0, 0, 0, 14, 15], [ 0, 0, 0, 0, 20], [ 0, 0, 0, 0, 0]])
ちなみに k
オプションの値は増やしたり減らすことで削る領域を調整できる。
>>> np.triu(array, k=2) array([[ 0, 0, 3, 4, 5], [ 0, 0, 0, 9, 10], [ 0, 0, 0, 0, 15], [ 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0]]) >>> np.triu(array, k=-1) array([[ 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10], [ 0, 12, 13, 14, 15], [ 0, 0, 18, 19, 20], [ 0, 0, 0, 24, 25]])
下三角行列 (対角要素あり)
(2017/12/06 追記)
下三角行列の効率的な加工方法を教えて頂きました。 転置行列を使うことで、短く書けるみたいです。 本文も、このやり方を使ったものに変更しました。 大変勉強になりました。この場を借りてお礼を申し上げます。
下三角行列はnp.triu(array.T).Tではだめなのでしょうか?
— Ken Kuroki (@enuroi) 2017年12月6日
続いては下三角行列を見ていく。 下三角行列には、転置行列を使うことで効率的に加工できるようだ。
まず NumPy では行列の T
アトリビュートから転置行列が得られる。
転置行列では、上三角と下三角が反転した状態になる。
>>> array.T array([[ 1, 6, 11, 16, 21], [ 2, 7, 12, 17, 22], [ 3, 8, 13, 18, 23], [ 4, 9, 14, 19, 24], [ 5, 10, 15, 20, 25]])
そこで NumPy.triu()
関数を使うと上三角だけが残る。
転置する前においては下三角だった要素たちだ。
>>> np.triu(array.T) array([[ 1, 6, 11, 16, 21], [ 0, 7, 12, 17, 22], [ 0, 0, 13, 18, 23], [ 0, 0, 0, 19, 24], [ 0, 0, 0, 0, 25]])
あとは、この状態から、さらに転置行列を取得することで元々の下三角行列が得られる。
>>> np.triu(array.T).T array([[ 1, 0, 0, 0, 0], [ 6, 7, 0, 0, 0], [11, 12, 13, 0, 0], [16, 17, 18, 19, 0], [21, 22, 23, 24, 25]])
下三角行列 (対角要素なし)
対角要素なしの下三角行列の取り出しは、これまでの考え方の組み合わせでいける。
先ほどの考え方はそのままに、上三角行列を取り出すタイミングで k
オプションを指定すれば良いだけ。
>>> np.triu(array.T, k=1).T array([[ 0, 0, 0, 0, 0], [ 6, 0, 0, 0, 0], [11, 12, 0, 0, 0], [16, 17, 18, 0, 0], [21, 22, 23, 24, 0]])
めでたしめでたし。
スマートPythonプログラミング: Pythonのより良い書き方を学ぶ
- 作者: もみじあめ
- 発売日: 2016/03/12
- メディア: Kindle版
- この商品を含むブログ (1件) を見る