Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am on my transitional trip from MATLAB to scipy(+numpy)+matplotlib. I keep having issues when implementing some things. I want to create a simple vector array in three different parts. In MATLAB I would do something like:

vector=[0.2,1:60,60.8];

This results in a one dimensional array of 62 positions. I'm trying to implement this using scipy. The closest I am right now is this:

a=[[0.2],linspace(1,60,60),[60.8]]

However this creates a list, not an array, and hence I cannot reshape it to a vector array. But then, when I do this, I get an error

a=array([[0.2],linspace(1,60,60),[60.8]])
ValueError: setting an array element with a sequence.

I believe my main obstacle is that I can't figure out how to translate this simple operation in MATLAB:

a=[1:2:20];

to numpy. I know how to do it to access positions in an array, although not when creating a sequence. Any help will be appreciated, thanks!

share|improve this question

7 Answers 7

up vote 10 down vote accepted

Well NumPy implements MATLAB's array-creation function, vector, using two functions instead of one--each implicitly specifies a particular axis along which concatenation ought to occur. These functions are:

  • r_ (row-wise concatenation) and

  • c_ (column-wise)


So for your example, the NumPy equivalent is:

>>> import numpy as NP

>>> v = NP.r_[.2, 1:10, 60.8]

>>> print(v)
     [  0.2   1.    2.    3.    4.    5.    6.    7.    8.    9.   60.8]

The column-wise counterpart is:

>>> NP.c_[.2, 1:10, 60.8]

slice notation works as expected [start:stop:step]:

>>> v = NP.r_[.2, 1:25:7, 60.8]

>>> v
  array([  0.2,   1. ,   8. ,  15. ,  22. ,  60.8])

Though if an imaginary number of used as the third argument, the slicing notation behaves like linspace:

>>> v = NP.r_[.2, 1:25:7j, 60.8]

>>> v
  array([  0.2,   1. ,   5. ,   9. ,  13. ,  17. ,  21. ,  25. ,  60.8])


Otherwise, it behaves like arange:

>>> v = NP.r_[.2, 1:25:7, 60.8]

>>> v
  array([  0.2,   1. ,   8. ,  15. ,  22. ,  60.8])
share|improve this answer
    
thanks doug! that is extremely cool, and it's two characters away to be as compact as matlab. great! –  vint-i-vuit May 29 '12 at 9:16
    
@vint-i-vuit no problem. If my answer was helpful to you, please mark it as "accepted" by clicking the 'check mark', visible when you mouse-over the score at upper left hand corner of my answer. (Or if another answer was more helpful, obviously you'll want to mark that one instead). Yes it's two more characters but i think it's worth it so NumPy can have one function for each of two axes to concatenate along (r_ & c_). –  doug May 29 '12 at 22:49
    
did not know that, yes! I learnt a lot from all the posts, they all work as I wanted, but possibly yours is the closest to MATLAB. thanks to all! –  vint-i-vuit May 31 '12 at 12:56
1  
c_ is not a column-wise counterpart... it's a shorthand version of a special r_ call.. Your example for the c_ call will not work. –  Norfeldt Dec 7 '12 at 22:01

You could try something like:

a = np.hstack(([0.2],np.linspace(1,60,60),[60.8]))
share|improve this answer
    
true! that works too, thanks JoshAdel. Also, is linspace the only option whenever I want to do something like a=[1:2:20] ? Which implies that I do not know the final size of the vector, just the step and start/end points. [bis] –  vint-i-vuit May 25 '12 at 11:43
    
Just found it myself thanks to mgilson. The answer is range(start,stop,step). great! –  vint-i-vuit May 25 '12 at 11:46
    
@vint-i-vuit Note that the python built-in range function only works for integer values. Numpy provides arange which will do the same thing (also with floats if you want it to) returning an array, but the documentation states that linspace is a better option in most cases since (due to roundoff), the results from arange might not be exactly what you expect. –  mgilson May 25 '12 at 11:50
    
@mgilson thanks for the insight. However I usually require the functionality of range/arange more than linspace ( I rarely used linspace in MATLAB). Since I tend to implement arrays knowing the step-size instead of the final vector size. I will take that into account! –  vint-i-vuit May 25 '12 at 11:57
np.concatenate([[.2], linspace(1,60,60), [60.8]])
share|improve this answer
    
damnit, true! that works, thanks larsmans. Also, is linspace the only option whenever I want to do something like a=[1:2:20] ? Which implies that I do not know the final size of the vector, just the step and start/end points. –  vint-i-vuit May 25 '12 at 11:41
    
Just found it myself thanks to mgilson. The answe is range(start,stop,step). great! –  vint-i-vuit May 25 '12 at 11:44
1  
You could also try np.arange(1,20,2) although be careful since this operation is not inclusive of the last number in the range (e.g. array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]) ). I forget how Matlab handles this and I've long since removed it from my machine. –  JoshAdel May 25 '12 at 11:45
    
Good to know! thanks. MATLAB to my knowledge keeps increasing/decreasing and if the end point happens to be in the range such as a=[0:2:10], then a contains it. If however the end point is not included, such as in a2=[1:2:10], then 10 is not included in a2. –  vint-i-vuit May 25 '12 at 11:50

Does arange(0.2,60.8,0.2) do what you want?

http://docs.scipy.org/doc/numpy/reference/generated/numpy.arange.html

share|improve this answer
    
indeed! arange() is a function I'll be using pretty often from now on, thanks for sharing too. –  vint-i-vuit May 25 '12 at 12:01

I somehow like the idea of constructing these segmented ranges you mentioned. If you use them alot, maybe a small function like

import numpy as np

def segrange(*args):
    result = []
    for arg in args:
        if hasattr(arg,'__iter__'):
            result.append(range(*arg))
        else:
            result.append([arg])
    return np.concatenate(result)

that gives you

>>> segrange(1., (2,5), (5,10,2))
[ 1.  2.  3.  4.  5.  7.  9.]

would be nice to have. Although, I would probably go for the answer using concatenate/hstack.

share|improve this answer
    
that's a nice thought! I think I'll try to stick to the + operator used in mgilson's reply from now, since it's the one that I find closest to matlab, hence less effort remembering. However I will see if executing that code is more convenient in some cases :) –  vint-i-vuit May 25 '12 at 12:51
1  
Correct me if I'm wrong, but I think that isinstance(arg,list) is preferred over type(arg) is list. Also, you could shorten that entire if block to hasattr(arg,'__iter__') (and catch all sorts of other iterables while you're at it) –  mgilson May 25 '12 at 14:56
    
yep, your right mgilson. but doug's answer bringing up _r supersedes all ^^ –  pwuertz May 30 '12 at 10:54

if I understand the matlab correctly, you could accomplish something like this using:

a=np.array([0.2]+list(range(1,61))+[60.8])

But there's probably a better way...the list(range(1,61)) could just be range(1,61) if you're using python 2.X.

This works by creating 3 lists and then concatenating them using the + operator.

The reason your original attempt didn't work is because

a=[ [0.2], np.linspace(1,60,60), [60.8] ] creates a list of lists -- in other words:

a[0] == [0.2] #another list (length 1)
a[1] == np.linspace(1,60,60) #an array (length 60)
a[2] == [60.8] #another list (length 1)

The array function expects an iterable that is a sequence, or a sequence of sequences that are the same length.

share|improve this answer
    
great mgilson! that's probably the closest to MATLAB syntax. Still not as compact as a=[0.2,1:60,60.8] but cool. thank you very much, I see it more clear now. –  vint-i-vuit May 25 '12 at 11:49
    
I think you'll find that while a lot of things in numpy are just as concise as in matlab (and a couple things slightly more concise), there are quite a few things that aren't quite as concise -- However, In general I find the code much more intuitive. –  mgilson May 25 '12 at 11:56
    
Up to know, the flexibility gained, specially at plotting, is so hugely worth the 'less-conciseness' of the syntax, so far. :) –  vint-i-vuit May 25 '12 at 11:59

Have a look at np.r_. It's basically equivalent to what everyone else has suggested, but if you're coming from matlab, it's a bit more intuitive (and if you're coming from any other language, it's a bit counter-intuitive).

As an example, vector=[0.2,1:60,60.8]; translates to:

vector = np.r_[0.2, 1:61, 60.8]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.