re: [python(x,y)] Help with Arrays -- New User with MATLAB Background

214 views
Skip to first unread message

Jean-Paul JADAUD

unread,
Jun 18, 2012, 5:26:19 PM6/18/12
to pyth...@googlegroups.com

 

Hi,

 

You should have a look on tutorial material such as

 

http://www.scipy.org/Getting_Started

 

http://www.scipy.org/Tentative_NumPy_Tutorial

 

http://scipy-lectures.github.com/

 

You probably can find other pointers to tutorials suited to Matlab users.  

 

 

Cheers,

 

JP Jadaud

 

 

 

 


 
 


> Message du 18/06/12 09:12
> De : "Bram"
> A : pyth...@googlegroups.com
> Copie à :
> Objet : [python(x,y)] Help with Arrays -- New User with MATLAB Background
>
>
Hi all,

>
I'm teaching myself the in's and out's of Python as I expect to use it by recoding my old MATLAB work into Python. Once I've got a handle on what I already can do in MATLAB then I plan to branch out and see how I can do more. 

>
I'm trying to fill an array inside a loop and it's telling me the name isn't defined. It works if I define the array with zeros first, but I'd rather just let it add values as it steps through the loop because I'll end up defining a bunch of variables. MATLAB has always warned me this is inefficient, but it significantly shortens the code and it's never gotten bogged down. Is there a way to make Python fill an array in a loop without having to set it first?

>
In other words if I've read in data for a, b, and c so I can calculate v, the following works but not without the first line. I have a lot of calculations like this and I'd like to avoid a block of lines like the first one.

>
v = zeros([3])
for n in 0,1,2
     v[n] = a[n]*b[n]/c[n]

>
Thanks.

>

--
You received this message because you are subscribed to the Google Groups "python(x,y)" group.
To view this discussion on the web visit https://groups.google.com/d/msg/pythonxy/-/uxVgEZyeEyUJ.
To post to this group, send email to pyth...@googlegroups.com.
To unsubscribe from this group, send email to pythonxy+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pythonxy?hl=en.

Joseph Barraud

unread,
Jul 13, 2012, 8:41:01 AM7/13/12
to pyth...@googlegroups.com
Hi Bram,

There are probably very good reasons why it is better to define the
size of the v array first. But if v is supposed to have the same size
as the others, then you can simply type:
v = a*b/c

If you have a Matlab background and need more help with Numpy, I would
suggest this page:
http://mathesaurus.sourceforge.net/matlab-numpy.html

Cheers,
Joseph

gwhite

unread,
Apr 19, 2014, 1:22:36 PM4/19/14
to pyth...@googlegroups.com


On Saturday, June 16, 2012 7:40:32 PM UTC-7, Bram wrote:
Hi all,

I'm teaching myself the in's and out's of Python as I expect to use it by recoding my old MATLAB work into Python. Once I've got a handle on what I already can do in MATLAB then I plan to branch out and see how I can do more. 

I'm trying to fill an array inside a loop and it's telling me the name isn't defined. It works if I define the array with zeros first, but I'd rather just let it add values as it steps through the loop because I'll end up defining a bunch of variables. MATLAB has always warned me this is inefficient, but it significantly shortens the code and it's never gotten bogged down. Is there a way to make Python fill an array in a loop without having to set it first?

In other words if I've read in data for a, b, and c so I can calculate v, the following works but not without the first line. I have a lot of calculations like this and I'd like to avoid a block of lines like the first one.

v = zeros([3])
for n in 0,1,2
     v[n] = a[n]*b[n]/c[n]

Thanks.

Preliminary note: give up trying to find a general language that is as concise and intuitive as MATLAB for what MATLAB was built for.  It ain't gonna happen.  There is a reason why it is dominant in the field (and expensive).  Clones and clone-ish (OCTAVE, SCILAB, etc) will be much better at emulating.

Short answer is that it will not work the way you are asking for.  (MATLAB will simply take care of the simultaneous creation and then resize for you.)  Getting somewhat closer:

>>> import numpy as np
>>> a = np.array([1., 2., 3.])
>>> b = np.array([10.,20.,30.])
>>> c = np.array([-1.,1.,-2.])
>>> v = []
>>> for k in 0,1,2:
    v = np.concatenate((v,[a[k]*b[k]/c[k]]))
>>> v
array([-10.,  40., -45.])
>>> type(v)
<type 'numpy.ndarray'>

I think you're still going to need to make v first, because ultimately it is referencing itself.  (You could do a conditional, but you don't save lines of code.)  As you mentioned the recursive resizing method is very inefficient.  If a, b, and c are all the same size, then it is so easy (same as MATLAB):

>>> v=a*b/c;v
array([-10.,  40., -45.])

Even if it is a subset it is easy:

>>> v=a[1:]*b[1:]/c[1:];v
array([ 40., -45.])

I too came from a MATLAB background.  In MATLAB, unless you say differently (like make a 'string'), every object is automatically a double precision and complex (if needed) array of any dimension you want, from empty to scaler to MxNx....  MATLAB is making your v and it is automatically an array instantly.

This is unequivocally not the case in Python, as it is a more general language.  So you need to take care of more things and that takes some getting used to.  MATLAB started as a pure math engine (MATrix LABoratory), so the philosophy is very different.  Lists, numbers, and Numpy arrays are not the same thing, and if you are like me, it will be a little confusing at first.

For example, even 1 and 1.0 are not quite the same thing in Python.  MATLAB has them both as float right out of the boat.

>>> type(1);type(1.0)
<type 'int'>
<type 'float'>

--------------
Here is another basic thing bewildering to the MATLAB user (ignoring the 0 or 1 start index difference):

>>> v=1
>>> v[0]

Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    v[0]
TypeError: 'int' object has no attribute '__getitem__'

No index because it has no dimension:
>>> import numpy as np
>>> np.ndim(1)
0

--------------
look at this:
>>> np.size(np.array([1,2,3,4,5,6]))
6
>>> np.shape(np.array([1,2,3,4,5,6]))
(6,)
>>> np.size(np.array([[1,2,3,4,5,6]]))
6
>>> np.shape(np.array([[1,2,3,4,5,6]]))
(1, 6)

But in MATLAB:
>> size(1:6)
ans =
      1  6

Check some indexing as a result:
>>> x=np.array([1,2,3,4,5,6])
>>> x[3]
4
>>> x[0,3]

Traceback (most recent call last):
  File "<pyshell#32>", line 1, in <module>
    x[0,3]
IndexError: too many indices
>>> y=np.array([[1,2,3,4,5,6]])
>>> y[0,3]
4

This distinction doesn't exist in MATLAB, or at least not obviously so.

>> x(1,4) %MATLAB *vector* is 1xN or Nx1
ans = 4

One really has to watch these details in Python.  Numpy does, however, get you most of the way there.

But going back to your initial question, even given MATLAB code, not preallocating and vectorizing whenever possible is "bad practice."  Numpy allows similar vectorizing, although Python as a whole is not vectorized like MATLAB. 

Presuming your a[:], b[:], and c[:] vectors (an assumption) are already dimensionally the same, and are numpy arrays, then I don't see why you don't simply do the basic vectorized form.  It is the "right way" to code.

Also, watch out for copys in Python.  I suggest using deepcopy (in the copy module).

y=x

Can't be done as a quick preallocate, because y and x are the same thing in Python, but not in MATLAB.

y=x+0 # quick shallow copy in python
y=copy.deepcopy(x) # a real "deep" (complete) copy in python
Reply all
Reply to author
Forward
0 new messages