7

often when working with numpy I find the distinction annoying - when I pull out a vector or a row from a matrix and then perform operations with np.arrays there are usually problems.

to reduce headaches, I've taken to sometimes just using np.matrix (converting all np.arrays to np.matrix) just for simplicity. however, I suspect there are some performance implications. could anyone comment as to what those might be and the reasons why?

it seems like if they are both just arrays underneath the hood that element access is simply an offset calculation to get the value, so I'm not sure without reading through the entire source what the difference might be.

more specifically, what performance implications does this have:

v = np.matrix([1, 2, 3, 4])
# versus the below
w = np.array([1, 2, 3, 4])

thanks

smci
  • 32,567
  • 20
  • 113
  • 146
lollercoaster
  • 15,969
  • 35
  • 115
  • 173
  • 1
    Duplicate of [http://stackoverflow.com/questions/4151128/what-are-the-differences-between-numpy-arrays-and-matrices-which-one-should-i-u](http://stackoverflow.com/questions/4151128/what-are-the-differences-between-numpy-arrays-and-matrices-which-one-should-i-u) – John Lyon Jun 04 '13 at 23:41
  • 2
    yes, but my question is about performance, which is not mentioned in that post. I'll edit my question to make that focus more clear. – lollercoaster Jun 04 '13 at 23:45
  • 2
    I doubt that there are any significant performance implications, but it's kind of hard to say without knowing exactly what you're planning on *doing* with the object once you create it. Why not make some test functions and give `timeit` a try? – mgilson Jun 05 '13 at 00:02
  • @mgilson yes I certainly will. My question was also "why the difference". matlab for example, treats such data structures the same. so I figured there was a reasoning behind it for the numpy implementiation. my question is also about understanding. – lollercoaster Jun 05 '13 at 00:32
  • 5
    The `matrix` class is a subclass of numpy's `ndarray` object, implemented entirely in Python. So every call you make on a `matrix` object is going to require a few extra Python calls, mostly to make sure that the object always remains 2D. So it may be a little slower than an `ndarray`, although the differences are very likely negligible – Jaime Jun 05 '13 at 04:08
  • What size matrix (what size N), and what sort of operation? Summing? Transposing? Multiplication? Matrix exponentiation? – smci Mar 15 '20 at 04:52
  • Please state both the numpy and Python versions in answers. Also, it's useful to express the ratio when comparing array to matrix, rather than raw timings. And to consider scaleability as size NxN increases. Assuming by 'array' we mean '2D array', which it usually does, for all non-scientists. – smci Mar 15 '20 at 04:57

2 Answers2

5

There is a general discusion on SciPy.org and on this question.

To compare performance, I did the following in iPython. It turns out that arrays are significantly faster.

In [1]: import numpy as np
In [2]: %%timeit
   ...: v = np.matrix([1, 2, 3, 4])
100000 loops, best of 3: 16.9 us per loop

In [3]: %%timeit
   ...: w = np.array([1, 2, 3, 4])
100000 loops, best of 3: 7.54 us per loop

Therefore numpy arrays seem to have faster performance than numpy matrices.

Versions used:

Numpy: 1.7.1

IPython: 0.13.2

Python: 2.7

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Lee
  • 29,398
  • 28
  • 117
  • 170
5

I added some more tests, and it appears that an array is considerably faster than matrix when array/matrices are small, but the difference gets smaller for larger data structures:

Small (4x4):

In [11]: a = [[1,2,3,4],[5,6,7,8]]

In [12]: aa = np.array(a)

In [13]: ma = np.matrix(a)

In [14]: %timeit aa.sum()
1000000 loops, best of 3: 1.77 us per loop

In [15]: %timeit ma.sum()
100000 loops, best of 3: 15.1 us per loop

In [16]: %timeit np.dot(aa, aa.T)
1000000 loops, best of 3: 1.72 us per loop

In [17]: %timeit ma * ma.T
100000 loops, best of 3: 7.46 us per loop

Larger (100x100):

In [19]: aa = np.arange(10000).reshape(100,100)

In [20]: ma = np.matrix(aa)

In [21]: %timeit aa.sum()
100000 loops, best of 3: 9.18 us per loop

In [22]: %timeit ma.sum()
10000 loops, best of 3: 22.9 us per loop

In [23]: %timeit np.dot(aa, aa.T)
1000 loops, best of 3: 1.26 ms per loop

In [24]: %timeit ma * ma.T
1000 loops, best of 3: 1.24 ms per loop

Notice that matrices are actually slightly faster for multiplication.

I believe that what I am getting here is consistent with what @Jaime is explaining the comment.

smci
  • 32,567
  • 20
  • 113
  • 146
Akavall
  • 82,592
  • 51
  • 207
  • 251
  • Performance always depend heavily on version number. Can you please state both the numpy and Python (2.7.6?) versions in your answer? Also, would be nice to see numbers for numpy 1.18 and Python 3.7/3.8. – smci Mar 15 '20 at 04:54