1

I am defining an array of two's, with one's on either end. In MATLAB this can be acheived by

x = [1 2*ones(1,3) 1]

In Python, however, numpy gives something quite different:

import numpy
numpy.array([[1],2*numpy.ones(3),[1]])

What is the most efficient way to perform this MATLAB command in Python?

Doubt
  • 1,163
  • 2
  • 15
  • 26

2 Answers2

7
In [33]: import numpy as np

In [34]: np.r_[1, 2*np.ones(3), 1]
Out[34]: array([ 1.,  2.,  2.,  2.,  1.])

Alternatively, you could use hstack:

In [42]: np.hstack(([1], 2*np.ones(3), [1]))
Out[42]: array([ 1.,  2.,  2.,  2.,  1.])

In [45]: %timeit np.r_[1, 2*np.ones(300), 1]
10000 loops, best of 3: 27.5 us per loop

In [46]: %timeit np.hstack(([1], 2*np.ones(300), [1]))
10000 loops, best of 3: 26.4 us per loop

In [48]: %timeit np.append([1],np.append(2*np.ones(300)[:],[1]))
10000 loops, best of 3: 28.2 us per loop

Thanks to DSM for pointing out that pre-allocating the right-sized array from the very beginning, can be much much faster than appending, using r_ or hstack on smaller arrays:

In [49]: %timeit a = 2*np.ones(300+2); a[0] = 1; a[-1] = 1
100000 loops, best of 3: 6.79 us per loop

In [50]: %timeit a = np.empty(300+2); a.fill(2); a[0] = 1; a[-1] = 1
1000000 loops, best of 3: 1.73 us per loop
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • Thanks unutbu. In the future, how should I go about trying to find routines like this? – Doubt Feb 02 '13 at 15:07
  • It should be noted though that `r_` can be 4+ times slower than simply doing `2*ones(n+2)` and then patching the edges. This won't be an issue unless it's in an inner loop, of course. – DSM Feb 02 '13 at 15:08
  • @DSM: Could you elaborate? Perhaps it depends on the version of numpy? I compared `r_` with `hstack` and got roughly comparable results. – unutbu Feb 02 '13 at 15:18
  • @unutbu: I mean versus `a = 2*np.ones(3+2); a[0] = 1; a[-1] = 1;`, which for me (1.6.2) is consistently about 4 times faster. – DSM Feb 02 '13 at 15:24
  • @Doubt: Experience helps. There is no shortcut. I learned a lot of numpy functions by just going through tutorials (like the [numpy book](http://www.tramy.us/)), taking notes and writing example code snippets. If memory serves, I think I first saw `r_` used [here](http://stackoverflow.com/a/3035188/190597). – unutbu Feb 02 '13 at 15:27
  • @DMS: Oh, okay. I agree. It always pays to allocate the right-sized arrays from the very beginning. – unutbu Feb 02 '13 at 15:31
  • @unutbu , for completeness, you may check CPU time also for `np.append([1],np.append(2*np.ones(300)[:],[1]))` – Jan Feb 02 '13 at 15:36
  • @Jan: Sure. I've added it above. – unutbu Feb 02 '13 at 15:39
  • And then there's things like `a = np.empty(300+2); a.fill(2); a[0] = 1; a[-1] = 1` but these games don't usually repay the investment of time in them.. – DSM Feb 02 '13 at 15:50
  • Thanks, DSM. I'll add it anyway. – unutbu Feb 02 '13 at 15:52
0

Use numpy.ones instead of just ones:

numpy.array([[1],2*numpy.ones(3),[1]])
Sudip Kafle
  • 4,286
  • 5
  • 36
  • 49
  • That will give a very different object, not `array([1, 2, 2, 2, 1])` -- that's the OP's problem. (If the OP's code worked, probably a `from numpy import *` happened, or the OP simply copied the code incorrectly.) – DSM Feb 02 '13 at 15:01
  • Thanks, I have fixed this. Sorry for the confusion. – Doubt Feb 02 '13 at 15:05