🍙

Pythonに入門してみているメモ

2021/04/15に公開

はじめに

そろそろ Python やらんといかんかのうと思ったとか思わなかったとか。

rangeはリスト生成からイテレータ (Py3)

forで使うrange()、これはリストを作って、イテレーションごとにリストをシフトさせているのではないかと。

どうもPython 3では違うらしいので、ここに記す。

>>> print(range(10))
range(0, 10)

リストじゃねえじゃん。

どうも、rangeはPython 2まではリストを生成していたけど、Python 3ではイテレータになったようです。

リストは次のようにすると出ます。

>>> print(list(range(0,10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

range()が出す値のシリーズについて見てみます。

引数は range([開始],終了,[ステップ]) となり、次のように、終了で指定した値は含みません。

>>> print(list(range(10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(list(range(0,10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(list(range(5,10)))
[5, 6, 7, 8, 9]

ステップを負数にしてみました。

>>> print(list(range(10,0,-1)))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

これらから、開始側は指定した値を含み、終了側は指定した値を含まないようです。開始側は境界が閉じていて、終了側は開いている、とも言えるのかも知れません。

参考: https://note.nkmk.me/python-range-usage/

numpyの定数とか若干気になること

  • 円周率はnumpy.pi
  • ネイピア数はnumpy.e
  • numpy.log()の底はnumpy.e (自然対数)
  • 常用対数は numpy.log10()
>>> import numpy as np
>>> np.pi
3.141592653589793
>>> np.e
2.718281828459045
>>> np.log(np.e)
1.0
>>> np.log10(10)
1.0

行列計算

行列はnumpy.matrixまたはnumpy.arrayを使いますが、numpy.matrixをお勧めします。

a1 = np.matrix([
  [1., 2.],
  [3., 4.]
])
a2 = np.matrix([
  [5., 6.],
  [7., 8.]
])

加減算と乗算

+-はそれぞれ加算減算を行い、単項の-もサポートしています。

>>> a1+a2
matrix([[ 6.,  8.],
        [10., 12.]])
>>> a1-a2
matrix([[-4., -4.],
        [-4., -4.]])
>>> -a1
matrix([[-1., -2.],
        [-3., -4.]])

**@は行列積を返します (numpy.matrixの場合)。

>>> a1*a2
matrix([[19., 22.],
        [43., 50.]])
>>> a1@a2
matrix([[19., 22.],
        [43., 50.]])

numpy.arrayについては、*@の演算子の振る舞いは異なります。

>>> np.array([[1,2],[3,4]])*np.array([[5,6],[7,8]])
array([[ 5, 12],
       [21, 32]])
>>> np.array([[1,2],[3,4]])@np.array([[5,6],[7,8]])
array([[19, 22],
       [43, 50]])

*は要素ごとの乗算を行った結果を返し、@は行列積を返します。

これで考えると、行列積の演算子は@と覚えておいた方がいいかも知れません。

/は要素ごとの除算を行った結果をかえします。

>>> a1/a2
matrix([[0.2       , 0.33333333],
        [0.42857143, 0.5       ]])

https://note.nkmk.me/python-numpy-matrix/

逆行列、転置行列、行列式

numpy.matrixは、プロパティとして.I.Tで、それぞれ逆行列、転置行列を得られます。

>>> a1.I
matrix([[-2. ,  1. ],
        [ 1.5, -0.5]])
>>> a1.T
matrix([[1., 3.],
        [2., 4.]])
>>> np.linalg.det(a1)
-2.0000000000000004

https://note.nkmk.me/python-numpy-matrix/

連立方程式を解く

numpy.lonalg.solve()を使います。逆行列を左から掛けても出ると思いますが、求解専用のメソッドがあるなら、そちらを使った方が良いかと思います。

a1 = np.matrix([
  [1., 2.],
  [3., 4.]
])

b = np.matrix([[50.],[110.]])
>>> np.linalg.solve(a1,b)
matrix([[10.],
        [20.]])

https://numpy.org/doc/stable/reference/generated/numpy.linalg.solve.html

numpy.array だとこうなる

  • .Iが無いので、numpy.linalg.inv()を使います。
  • .Tが無いので、numpy.transpose()を使います。invと名前空間が違うので注意して下さい。
  • 上述の通り、*の振る舞いが異なります。
  • numpy.lonalg.solve() は問題なく解けます。

matrixとarrayが混じると * はどうなる?

numpy.matrixnumpy.arrayとで*の振る舞いが異なりますが、混じったらどうなるでしょう?

>>> np.matrix([[1,2],[3,4]])*np.array([[5,6],[7,8]])
matrix([[19, 22],
        [43, 50]])
>>> np.array([[1,2],[3,4]])*np.matrix([[5,6],[7,8]])
matrix([[19, 22],
        [43, 50]])

どちらも行列積になりました (numpy.matrix * numpy.matrixと同じ)。

本記事のライセンス

クリエイティブ・コモンズ・ライセンス
この記事は クリエイティブ・コモンズ 表示 4.0 国際 ライセンス の下に提供されています。

Discussion