#Python 小技 配列演算
pypyでpython scriptを実行するときにつかった小技のメモ。
pypyとはpython scriptを高速実行するための異なるpython実行系である。こいつは確かに速い。しかし、pypyとnumpyの相性が猛烈に悪い. 最近はinstallとimport自体はすんなり通るものの、当のnumpyによる計算が猛烈に遅くなる。
これでは意味がないということでpypyを諦める人もいそうなので、ここではnumpyを使わない配列演算を扱ってみる。
###1. 1次元配列の加減乗除
まずは単なるlist同士の足し算
array1 = [4,5,6]
array2 = [1,2,3]
array_add = list(map(lambda x,y: x+y, array1, array2))
#[5,7,9]
解説すると
lambdaは手軽に関数を作りたいときに便利なやつ。上の例では、xとyを2つの引数を足し算して返す関数を作っている。一方で map()は、1つ目の引数に関数、そして2個目以降の引数には1つ目の関数の引数を要素に持った配列をとり、配列の中の要素を順番に関数にかけてくれる。 つまり、(x,y)には(4,1),(5,2),(6,3)が順番に、lambdaで作った関数に渡されて、その返り値である和が計算される。map()はpython2.系ではtupleが返り値になるが、python3.系ではiterが返り値になるので、2.でも3.でも動くようにlist()で囲むことをおすすめする。
同様に
#引き算
array_subtract = list(map(lambda x,y: x-y, array1, array2))
#[3,3,3]
#掛け算
array_multiple = list(map(lambda x,y: x*y, array1, array2))
#[4,10,18]
#割り算
array_div = list(map(lambda x,y: x/y, array1, array2))
#[4,2.5,2] python3.系
#[4,2,2] python2.系
###2. 2次元配列の足し算
1次元のときのことを応用すれば、numpyを使わないで多次元配列の加減乗除だってできる。
array1 = [[1,2,3],[1,2,3]]
array2 = [[2,3,4],[2,3,4]]
array_add = list(map(lambda x,y: list(map(lambda a,b: a+b, x,y)), array1, array2))
#[[3, 5, 7], [3, 5, 7]]
と、このようにnumpyを使わなくてもmapとlambdaを駆使すれば、配列同士の演算はおちゃのこさいさいである。pypyを使わないひとも、わざわざnumpyをimportしなくてもなぁというときに使ってみてください。
おまけ. 転置
演算以外によく使うものとして、2次元配列の転置。
array1 = [[1,2,3],[3,4,5],[6,7,8]]
array1_t = list(zip(*array1))
#[(1,3,6),(2,4,7),(3,5,8)]