LoginSignup
8
8

More than 5 years have passed since last update.

Numpy を使わない多次元配列計算 その2

Last updated at Posted at 2017-08-24

Numpyを使わない多次元配列計算

以前に、http://qiita.com/ponnhide/items/c919f3bc549d1228c800 の記事で、numpyを用いない配列計算について取り扱ったが、この記事はその発展版

なぜnumpyを使わないか。

numpyを使えばできるのに、何故使わない方法を考えるか。ただの趣味という側面もあるが、単にpypy上でnumpyを使うと異常に実行が遅くなるためである。まぁきっと他にも使い道はあると思う。

前回の復習(加減乗除)

前回の記事で、「mapとlambdaを駆使すれば、配列同士の演算はおちゃのこさいさい」とか書いてしまったがぶっちゃけlambdaよりは、operatar モジュールを使った方がはるかにスクリプトが簡素ですむ。operator モジュールを使うと、演算子を関数形式で用いることができる。例えば、operator.add(a,b)a+b と同義である。

まずは
1次元配列の和

from operator import add
>>> array1 = [4,5,6]
>>> array2 = [1,2,3]
>>> list(map(add, array1, array2))
[5,7,9]

2次元配列の和
結局、ここではlambdaを使うわけだが、

>>> array1 = [[1,2,3],[1,2,3]]
>>> array2 = [[2,3,4],[2,3,4]]
>>> list(map(lambda x,y: list(map(add, x,y)), array1, array2))
[[3, 5, 7], [3, 5, 7]]

どうしてもlambdaには頼らないぞっていう場合は、リスト内包表記をつかって、

>>> [list(map(add, x,y)) for x,y in zip(array1,array2)]
[[3, 5, 7], [3, 5, 7]]

みたいな書き方もできる。こっちの方がスッキリしてるか。

行列の掛け算

前回は扱わなかったが、numpyを使わずにと豪語するなら、やっぱり行列の掛け算(要素同士の積じゃなくてdot積)もやるべきだろということで、無理やり考えてみた。

>>> from operator import mul
>>> array1 = [[2,3],[1,4],[2,1]]
>>> array2 = [[3,1,2],[2,4,2]]
>>> [[sum(map(mul, row, col)) for col in zip(*array2)] for row in array1]
[[12, 14, 10], [11, 17, 10], [8, 6, 6]]

よしできた。しかし、array1が 1行xn列 の場合だと上記の書き方ではできない。array1が 1行xn列 場合は、

>>> from operator import mul
>>> array1 = [1,0,0,1]
>>> array2 = [[0,1],[1,1],[1,0],[1,0]]
>>> [sum(map(mul, array1, col)) for col in zip(*array2)]
[1,1]

うーむ。lambdaや、三項演算子を駆使すれば、統一した書き方もできるかな。。

統計関連

特に使い方には触れないが、python3.4以降の環境ならデフォルトで、statistics モジュールが入っている。これを使えば、list型のまま基本的な統計量は計算が可能。
https://docs.python.jp/3/library/statistics.html

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8