Sponsored Link

月別アーカイブ: 9月 2014

(72) multiprocessingでマルチプロセス処理

(72) multiprocessingでマルチプロセス処理

(71) threading.Threadでマルチスレッド処理 と同じことをマルチプロセスで実行してみる。
複数プロセスで実行する関数を作成する。

from multiprocessing import Process, Manager

def makeMsg(name, outList, outDict):
    msg = 'Hello! I am %s.' % name
    outList.append(msg)
    outDict[name] = msg   # or outDict.update({name: msg})

プロセスを3個起動してみる。

if __name__ == '__main__':
    names = ['aaa','bbb','ccc']
    mng = Manager()
    outList = mng.list()
    outDict = mng.dict()

    prs = []
    for name in names:
        pr = Process(target=makeMsg, args=(name, outList, outDict))
        prs.append(pr)

    for i in range(len(prs)):
        prs[i].start()

    for i in range(len(prs)):
        prs[i].join()

    print outDict.keys()
    print outDict
    print outList

実行結果

[user@]$ python hello_mp.py
['aaa', 'bbb', 'ccc']
{'aaa': 'Hello! I am aaa.', 'bbb': 'Hello! I am bbb.', 'ccc': 'Hello! I am ccc.'}
['Hello! I am aaa.', 'Hello! I am bbb.', 'Hello! I am ccc.']

(71) threading.Threadでマルチスレッド処理

(71) threading.Threadでマルチスレッド処理

threading.Thread のサブクラスとして HelloThread を作る。
実行されると文字列を作って出力するだけの処理を実装する。

from threading import Thread
class HelloThread( Thread ):
    def __init__( self, n ):
        Thread.__init__(self)
        self.n = n
    def run(self):
        self.msg = 'Hello! I am %s.' % self.n

スレッドを3個起動してみる。

if __name__ == '__main__':
    names = ['aaa','bbb','ccc']
    ths = []
    for name in names:
        th = HelloThread(name)
        ths.append(th)

    for i in range(len(ths)):
        ths[i].start()

    res = []
    for i in range(len(ths)):
        ths[i].join()
        res.append(ths[i].msg)
    print res

これらを hello.py に記述し、実行した結果は以下の通り。

[user@]$ python hello.py
['Hello! I am aaa.', 'Hello! I am bbb.', 'Hello! I am ccc.']

(70) numpy.reshapeは浅いコピー

(70) numpy.reshapeは浅いコピー

4行3列の乱数配列aを作成する。

>>> import numpy as np
>>> a = np.random.rand(4,3)
>>> a
array([[ 0.15940847,  0.56564422,  0.82868468],
       [ 0.55344639,  0.55527501,  0.75242168],
       [ 0.43876864,  0.50025427,  0.07168502],
       [ 0.15186   ,  0.00686738,  0.98197383]])

配列aを numpy.reshape で 6行2列に変形する。

>>> b = np.reshape(a, (6,2))
>>> b
array([[ 0.15940847,  0.56564422],
       [ 0.82868468,  0.55344639],
       [ 0.55527501,  0.75242168],
       [ 0.43876864,  0.50025427],
       [ 0.07168502,  0.15186   ],
       [ 0.00686738,  0.98197383]])

配列bの要素の値を書き換える。

>>> b[3,1] = 0
>>> b
array([[ 0.15940847,  0.56564422],
       [ 0.82868468,  0.55344639],
       [ 0.55527501,  0.75242168],
       [ 0.43876864,  0.        ],
       [ 0.07168502,  0.15186   ],
       [ 0.00686738,  0.98197383]])

すると、配列aの要素も書き換わっている!

>>> a
array([[ 0.15940847,  0.56564422,  0.82868468],
       [ 0.55344639,  0.55527501,  0.75242168],
       [ 0.43876864,  0.        ,  0.07168502],
       [ 0.15186   ,  0.00686738,  0.98197383]])

numpy.reshape したものを別のオブジェクトに代入したい場合、numpy.copy を使用する。

>>> a = np.random.rand(4,3)
>>> a
array([[ 0.59587499,  0.33831817,  0.75324048],
       [ 0.67519994,  0.57802629,  0.48760045],
       [ 0.27385989,  0.02654679,  0.46217751],
       [ 0.20590104,  0.31475441,  0.31250744]])
>>> b = a.reshape(6,2).copy()
>>> b
array([[ 0.59587499,  0.33831817],
       [ 0.75324048,  0.67519994],
       [ 0.57802629,  0.48760045],
       [ 0.27385989,  0.02654679],
       [ 0.46217751,  0.20590104],
       [ 0.31475441,  0.31250744]])
>>> b[3,0] = 0
>>> b
array([[ 0.59587499,  0.33831817],
       [ 0.75324048,  0.67519994],
       [ 0.57802629,  0.48760045],
       [ 0.        ,  0.02654679],
       [ 0.46217751,  0.20590104],
       [ 0.31475441,  0.31250744]])
>>> a
array([[ 0.59587499,  0.33831817,  0.75324048],
       [ 0.67519994,  0.57802629,  0.48760045],
       [ 0.27385989,  0.02654679,  0.46217751],
       [ 0.20590104,  0.31475441,  0.31250744]])

こう書いても同じ。

>>> a = np.random.rand(4,3)
>>> a
array([[ 0.59738729,  0.8289699 ,  0.22344194],
       [ 0.86271615,  0.76692546,  0.1131666 ],
       [ 0.61305503,  0.28302821,  0.24619501],
       [ 0.10828006,  0.38060943,  0.46060143]])
>>> b = np.copy(a.reshape(6,2))
>>> b
array([[ 0.59738729,  0.8289699 ],
       [ 0.22344194,  0.86271615],
       [ 0.76692546,  0.1131666 ],
       [ 0.61305503,  0.28302821],
       [ 0.24619501,  0.10828006],
       [ 0.38060943,  0.46060143]])
>>> b[3,0] = 0
>>> b
array([[ 0.59738729,  0.8289699 ],
       [ 0.22344194,  0.86271615],
       [ 0.76692546,  0.1131666 ],
       [ 0.        ,  0.28302821],
       [ 0.24619501,  0.10828006],
       [ 0.38060943,  0.46060143]])
>>> a
array([[ 0.59738729,  0.8289699 ,  0.22344194],
       [ 0.86271615,  0.76692546,  0.1131666 ],
       [ 0.61305503,  0.28302821,  0.24619501],
       [ 0.10828006,  0.38060943,  0.46060143]])

(69) numpy配列の浅いコピー深いコピー

(69) numpy配列の浅いコピー深いコピー

普通に代入した場合、参照が返される。
→ 一方のオブジェクトへの変更が、両方に反映される。

>>> import numpy as np
>>> a = np.random.randint(1,10,(3,4))
>>> a
array([[8, 1, 4, 5],
       [4, 9, 9, 9],
       [8, 3, 5, 5]])
>>>
>>> b = a
>>> b[2,2] = -1
>>> b
array([[ 8,  1,  4,  5],
       [ 4,  9,  9,  9],
       [ 8,  3, -1,  5]])
>>> a
array([[ 8,  1,  4,  5],
       [ 4,  9,  9,  9],
       [ 8,  3, -1,  5]])

numpy.copy を使用した場合、別オブジェクトが生成される。
→ 一方のオブジェクトの変更が、他方に反映されない。

>>> a = np.random.randint(1,10,(3,4))
>>> a
array([[8, 4, 7, 7],
       [2, 6, 3, 7],
       [9, 8, 2, 5]])
>>>
>>> c = a.copy()
>>> c
array([[8, 4, 7, 7],
       [2, 6, 3, 7],
       [9, 8, 2, 5]])
>>> c[2,2] = -1
>>> c
array([[ 8,  4,  7,  7],
       [ 2,  6,  3,  7],
       [ 9,  8, -1,  5]])
>>> a
array([[8, 4, 7, 7],
       [2, 6, 3, 7],
       [9, 8, 2, 5]])

(68) rangeとxrange

(68) rangeとxrange

range xrange は同じように使える。

>>> for i in range(3,6):
...    print i
...
3
4
5
>>> for i in xrange(3,6):
...    print i
...
3
4
5

作られるオブジェクトはそれぞれ異なる。

>>> r = range(3,6)
>>> r
[3, 4, 5]
>>> x = xrange(3,6)
>>> x
xrange(3, 6)

でも、やっぱり同じように使える。

>>> for i in r:
...     print i
...
3
4
5
>>> for i in x:
...     print i
...
3
4
5

rangeで生成されるのが listなのに対して、xrangeが生成するのは iteratorとのこと。
すなわち、配列要素数が増えた場合に xrangeの方がメモリを節約できるとのこと。

(67) numpyで配列要素の積

(67) numpyで配列要素の積

numpy.prod で配列要素の積を算出できる。
軸指定なしならば全要素を対象、
axis=Nで軸指定すれば任意方向の要素の積を算出できる。

>>> import numpy as np
>>> a = np.random.randint(0,10,(3,2))
>>> a
array([[9, 4],
       [7, 1],
       [3, 5]])
>>>
>>> a.prod()
3780
>>>
>>> a.prod(axis=0)
array([189,  20])
>>>
>>> a.prod(axis=1)
array([36,  7, 15])

(66) numpyで配列の条件検索

(66) numpyで配列の条件検索

以下のような乱数配列aを作成する。

>>> import numpy as np
>>> a = np.random.randint(0,5,10)
>>> a
array([1, 2, 2, 0, 1, 3, 2, 1, 1, 4])

値が3以上の要素を検索する。→ [5]に3, [9]に4が検出された。

>>> b = np.where(a >= 3)
>>> b
(array([5, 9]),)
>>> a[b]
array([3, 4])

非0の要素を検索する。

>>> c = np.nonzero(a)
>>> c
(array([0, 1, 2, 4, 5, 6, 7, 8, 9]),)
>>> a[c]
array([1, 2, 2, 1, 3, 2, 1, 1, 4])

これでも同じこと。

>>> d = np.where(a != 0)
>>> d
(array([0, 1, 2, 4, 5, 6, 7, 8, 9]),)
>>> a[d]
array([1, 2, 2, 1, 3, 2, 1, 1, 4])

(65) numpyで値が0の配列要素をカウント

(65) numpyで値が0の配列要素をカウント

numpy.count_nonzero で値が0の配列要素数をカウントできる。

>>> import numpy as np
>>> a = np.random.rand(10)
>>> a
array([ 0.35002505,  0.54780005,  0.89527122,  0.64347181,  0.51200932,
        0.11512311,  0.73636012,  0.30606429,  0.57073214,  0.06892677])
>>> b = (a > 0.5) * 1
>>> b
array([0, 1, 1, 1, 1, 0, 1, 0, 1, 0])
>>> np.count_nonzero(b)
6

条件検索で非0の要素のリストを取得し、その要素数をカウントする方法でもよい。

>>> len(np.where(b!=0)[0])
>>> 6

(64) numpyで配列要素をフリップ

(64) numpyで配列要素をフリップ

以下のような乱数配列aを作成する。

>>> import numpy as np
>>> a = np.random.randint(0,10,10)
>>> a
array([9, 0, 1, 8, 0, 4, 6, 5, 5, 4])

配列aの要素の順序を反転してみる。
最終要素[-1]から-1ずつインデックスをずらすことにより実現する。

>>> b = a[-1::-1]
>>> b
array([4, 5, 5, 6, 4, 0, 8, 1, 0, 9])

(63) numpyでソート後配列のインデックスを取得

(63) numpyでソート後配列のインデックスを取得

以下のような乱数配列aを作る。

>>> import numpy as np
>>> a = np.random.rand(10)
>>> a
array([ 0.4556755 ,  0.82176872,  0.49312231,  0.17689834,  0.96413341,
        0.41666999,  0.91981665,  0.26402886,  0.67935056,  0.80891284])

配列要素をソートしたい場合、numpy.sort を使えばよい。

>>> b = np.sort(a)
>>> b
array([ 0.17689834,  0.26402886,  0.41666999,  0.4556755 ,  0.49312231,
        0.67935056,  0.80891284,  0.82176872,  0.91981665,  0.96413341])

降順にしたい場合はソート後の配列をフリップする。

>>> c = b[-1::-1]
>>> c
array([ 0.96413341,  0.91981665,  0.82176872,  0.80891284,  0.67935056,
        0.49312231,  0.4556755 ,  0.41666999,  0.26402886,  0.17689834])

本題の ソート後の配列要素インデックスを得るには? numpy.argsort を使う。

>>> x = np.argsort(a)
>>> x
array([3, 7, 5, 0, 2, 8, 9, 1, 6, 4])

得られたインデックスを使用して、配列要素のソートもできる。

>>> a[x]
array([ 0.17689834,  0.26402886,  0.41666999,  0.4556755 ,  0.49312231,
        0.67935056,  0.80891284,  0.82176872,  0.91981665,  0.96413341])
>>> b - a[x]
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])