Sponsored Link

月別アーカイブ: 8月 2014

(51) numpy配列の非ゼロ要素を抽出

(51) numpy配列の非ゼロ要素を抽出

numpy配列から非ゼロ要素のみを抽出したい。

5行5列の配列を作成する。

>>> import numpy as np
>>> a = (np.random.rand(5,5) * 10).astype(np.int32)
>>> a
array([[9, 5, 3, 3, 5],
       [3, 7, 9, 3, 0],
       [4, 6, 6, 4, 2],
       [2, 0, 5, 8, 8],
       [9, 0, 9, 9, 9]], dtype=int32)

非ゼロの要素の行方向、列方向のインデックスを取得する。

>>> np.nonzero(a)
(array([0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]),
 array([0, 1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 2, 3, 4, 0, 2, 3, 4]))

出力結果を見ると、(1,4),(3,1),(4,1)が除外されている。確かにそこには0が格納されている。

非ゼロの要素数をカウントする。

>>> np.nonzero(a)[0].size
22

非ゼロの要素の平均を算出する。

>>> a.sum().astype(np.float32) / np.nonzero(a)[0].size
5.8181818181818183

(50) numpy配列の部分統計計算

(50) numpy配列の部分統計計算

numpy配列に対して部分的に平均値や標準偏差を求めたい。

以下のように 10行8列の整数配列aを作る。

>>> import numpy as np
>>> a = (np.random.rand(10,8) * 10).astype(np.int32)
>>> a
array([[2, 7, 7, 9, 9, 4, 4, 3],
       [8, 1, 4, 5, 2, 2, 0, 9],
       [5, 6, 3, 4, 3, 4, 2, 5],
       [0, 0, 7, 9, 3, 8, 6, 5],
       [0, 0, 8, 0, 5, 8, 9, 3],
       [9, 9, 3, 3, 3, 8, 9, 3],
       [4, 3, 9, 7, 9, 2, 6, 2],
       [2, 9, 9, 5, 0, 7, 6, 0],
       [8, 2, 2, 1, 5, 1, 7, 8],
       [7, 0, 4, 6, 8, 9, 0, 5]], dtype=int32)

a[2][3]を起点に3行2列の範囲に対して統計計算したい。
見辛いので取り出してみる。切り出したものを別変数に代入した方が扱いやすいか…

>>> a[2:2+3, 3:3+2]
array([[4, 3],
       [9, 3],
       [0, 5]], dtype=int32)

sumで総和を求める。

>>> a[2:2+3, 3:3+2].sum()
24

meanで平均値を求める。

>>> a[2:2+3, 3:3+2].mean()
4.0

stdで標準偏差を求める。

>>> a[2:2+3, 3:3+2].std()
2.70801280154532

maxで最大値を求める。

>>> a[2:2+3, 3:3+2].max()
9

minで最小値を求める。

>>> a[2:2+3, 3:3+2].min()
0

(49) numpy配列の部分代入

(49) numpy配列の部分代入

例として8行5列の配列aを作る。

>>> import numpy as np
>>> a = np.random.rand(8,5)
>>> a
array([[ 0.59477343,  0.39696101,  0.8635444 ,  0.57730748,  0.80778975],
       [ 0.36723965,  0.48813453,  0.53213475,  0.0682938 ,  0.23692774],
       [ 0.82790539,  0.02619104,  0.7563847 ,  0.10553861,  0.59796693],
       [ 0.62885835,  0.61025432,  0.60352469,  0.09148856,  0.55585131],
       [ 0.54324068,  0.61347011,  0.6137894 ,  0.8560153 ,  0.39223471],
       [ 0.28993199,  0.37723578,  0.65900017,  0.60465485,  0.56363825],
       [ 0.00705464,  0.58109945,  0.79664211,  0.92434556,  0.01637478],
       [ 0.79555517,  0.61280461,  0.32642076,  0.70221643,  0.17151009]])

これに部分代入する3行2列の配列bを作る。
代入結果がわかりやすいように整数とする。

>>> b=(np.random.rand(3,2) * 10).astype(np.int32).astype(np.float32)
>>> b
array([[ 2.,  7.],
       [ 4.,  6.],
       [ 7.,  7.]], dtype=float32)

a[2][2]を起点にbを代入する。

>>> sb = b.shape
>>> sb
(3, 2)
>>> a[2:2+sb[0], 2:2+sb[1]] = b
>>> a
array([[ 0.59477343,  0.39696101,  0.8635444 ,  0.57730748,  0.80778975],
       [ 0.36723965,  0.48813453,  0.53213475,  0.0682938 ,  0.23692774],
       [ 0.82790539,  0.02619104,  2.        ,  7.        ,  0.59796693],
       [ 0.62885835,  0.61025432,  4.        ,  6.        ,  0.55585131],
       [ 0.54324068,  0.61347011,  7.        ,  7.        ,  0.39223471],
       [ 0.28993199,  0.37723578,  0.65900017,  0.60465485,  0.56363825],
       [ 0.00705464,  0.58109945,  0.79664211,  0.92434556,  0.01637478],
       [ 0.79555517,  0.61280461,  0.32642076,  0.70221643,  0.17151009]])

(48) スプライン補間で内挿

(48) スプライン補間で内挿

以下の4点を通る滑らかなそれっぽい曲線を描きたい。
(x,y)=(-2,4),(-1,1),(1,5),(2,1)

この4点を直線で結んでみる。

import numpy as np
import matplotlib.pyplot as plt
x = np.array([-2,-1,1,2],dtype='float32')
y = np.array([4,1,5,1],  dtype='float32')
plt.plot(x, y)
plt.show()

20140829_02

この4点のX軸上の両端を0.1ステップで40分割し、各X座標に対応するY座標を スプライン補間 で求める。

import scipy.interpolate
xn = np.arange(-2.0, 2.1, 0.1)
rp = scipy.interpolate.splrep(x, y, s=0)
yn = scipy.interpolate.splev(xn, rp, der=0)
plt.plot(x, y)
plt.plot(xn, yn)
plt.show()

20140829_03

P.S.
スプライン補間は3次元でも使える。

(47) matplotlibでグラフ表示できない [解決]

(47) matplotlibでグラフ表示できない [解決]

別マシンへのインストール時に再度はまりそうなのでメモしておく。

(1) 現象

matplotlibを使ってグラフを表示しようとしたが表示されない。エラーも出ず…

>>> import matplotlib.pyplot as plt
>>> plt.plot([1,2,3,4])
>>> plt.show()

うんともすんとも…

(2) 原因

matplotlibの backend指定がデフォルトで画面表示できないもの backend : agg になっていた。
これを画面表示可能な backendに変える必要がある。

(3) 対策

二重三重にはまったので整理して結論だけメモしておく。

(1) Tcl/Tk関連パッケージをインストールする。

# yum install tk.x86_64
# yum install tk-devel.x86_64
# yum install tkinter.x86_64

(2) matplotlibをインストールしなおす。

$ python setup.py build
$ sudo python setup.py install

この時点でまだ表示できないようなら以下を確認する。

(3) matplotlibの設定ファイルの場所を知る。

$ python
>>> import matplotlib
>>> matplotlib.matplotlib_fname()
'/usr/local/lib/python2.7/site-packages/matplotlib-1.3.1-py2.7-linux-x86_64.egg/matplotlib/mpl-data/matplotlibrc'

(4) matplotlibの設定ファイルでbackend指定を書き換える。

# vi /mpl-data/matplotlibrc
#### CONFIGURATION BEGINS HERE
# the default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
# CocoaAgg MacOSX Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG
# Template
# You can also deploy your own backend outside of matplotlib by
# referring to the module name (which must be in the PYTHONPATH) as
# 'module://my_backend'
#backend      : agg
backend      : tkagg

(1),(2)を先にやっていれば、(3),(4)は必要なかったかもしれない。
今度別マシンにインストールするときにはこの手順でやってみよう。

(4) 確認結果

できた!

>>> import matplotlib.pyplot as plt
>>> plt.plot([1,2,3,4])
>>> plt.show()

20140829_01

(x) 面倒な場合はAnaconda

Anaconda(Python distributionの一つ)をインストールすれば、数値計算系の Pythonパッケージをごそっと入れてくれる。もちろん matplotlibも最初から表示できるように設定されている。
参考1: Python Distributions
参考2: Anaconda

Anacondaは以下の手順で非rootでもインストールできる。

wget https://repo.continuum.io/archive/Anaconda3-4.4.0-Linux-x86_64.sh
chmod +x Anaconda3-4.4.0-Linux-x86_64.sh
./Anaconda3-4.4.0-Linux-x86_64.sh

実行時はパスを通す。

export PATH=~/anaconda3/bin/:$PATH
python3

(46) datetime型で日時の引き算

(46) datetime型で日時の引き算

二つの日時の時間差を求める。

>>> import datetime
>>> dt1 = datetime.datetime(2014,8,28,20,57,41)
>>> dt2 = datetime.datetime(2014,8,28,19,51,50)
>>> dt3 = dt1 - dt2
>>> dt3
datetime.timedelta(0, 3951)

結果をtimedeltaなるオブジェクトで返された。(days,seconds)の順に表示されている。
これの中身を見てみる。

>>> dt3.days
0
>>> dt3.seconds
3951
>>> print dt3
1:05:51

3951秒、1時間5分51秒であることが求められた。

(44) 日時文字列をdatetime型に変換

(44) 日時文字列をdatetime型に変換
>>> import datetime
>>> str = "2014/8/28 20:45:32"
>>> dt = datetime.datetime.strptime( str, '%Y/%m/%d %H:%M:%S')

設定できたか?確認してみる。

>>> dt
datetime.datetime(2014, 8, 28, 20, 45, 32)
>>> dt.year
2014
>>> dt.month
8
>>> dt.day
28
>>> dt.hour
20
>>> dt.minute
45
>>> dt.second
32

(42) matplotlib 1.3.1をインストール

(42) matplotlib 1.3.1をインストール

(1) インストーラーをダウンロードする。
http://matplotlib.org/

(2)解凍する。

$ tar zxf matplotlib-1.3.1.tar.gz
$ cd matplotlib-1.3.1

(3) インストールを実行する。

$ python setup.py build
$ sudo python setup.py install

追記: 2014/08/29
matplotlibでグラフが描画できない問題への対処方法を下記記事に記しました。
(47) matplotlibでグラフ表示できない[解決]