469,610 Members | 1,710 Online

# Numeric help!

Hi,

I have the following loop that I think can be written to run faster in
Numeric. I am currently using Numeric.
range_va = [60,61,62,63,64,65,66,67,68,69,70,71,72]
main.xsize= 600
main.ysize= 600
#msgva is an (600x600) Numeric array with mutiple occurrences of the
values in range_va
#sat_id is an (600x600) Numeric array with values ranging from -2 to 2
for z in range_va:
count = 0
mbias = 0
for i in range(main.xsize):
for j in range(main.ysize):
if msgva[i,j] == z:
mbias += sat_id[i,j] # take the sum of the
values
count += 1 # count the occurrences
tmp_array[0,index] = round(mbias/count,1) # store the mean
tmp_array[1,index] = z
index += 1

Any help would be greatly appreciated!

Sincerely,
Sheldon

Jun 28 '06 #1
7 1446
Sheldon wrote:
Hi,

I have the following loop that I think can be written to run faster in
Numeric. I am currently using Numeric.
range_va = [60,61,62,63,64,65,66,67,68,69,70,71,72]
main.xsize= 600
main.ysize= 600
#msgva is an (600x600) Numeric array with mutiple occurrences of the
values in range_va
#sat_id is an (600x600) Numeric array with values ranging from -2 to 2
for z in range_va:
count = 0
mbias = 0
for i in range(main.xsize):
for j in range(main.ysize):
if msgva[i,j] == z:
mbias += sat_id[i,j] # take the sum of the
values
count += 1 # count the occurrences
tmp_array[0,index] = round(mbias/count,1) # store the mean
tmp_array[1,index] = z
index += 1

Any help would be greatly appreciated!

I'm not sufficiently sure this isn't a homework problem, so here's a

Your intuition is correct--there's almost always a faster way to do it
when you're cycling through Numeric array indices in a Python for loop.
Numeric and successors exist mostly to get rid of them.

Given z, you can calculate mbias in one line:

mbias = Numeric.sum(
Numeric.ravel(Numeric.where(msgva==z,sat_id,0)))

Here, the Numeric.where function allows you to filter out entries: it
returns an array with the elements of sat_id, but only where the
corresponding element of msvga==z; otherwise the entry is zero.
Numeric.ravel flattens an multidimensional array into one dimension,
and, of course, Numeric.sum adds up all the elements in the array.

How to get count and to work this into your loop are left as an
exercise.
Carl Banks

Jun 29 '06 #2
Hi Carl,

My days as a student is over for the most part. I am learning python on
my own and Numeric is not properly documented so I am learning by doing
and copying from others. I thought about the problem and a solution
another problem given to me earlier using "putmask" is the solution but
there is a bug that I cannot figure out:
************************
index = 0
for z in range_va:
wk = msgva # working arrary
sattmp = sat_id # working array
valid data pixs
rdata =
compress(ravel(not_equal(sattmp,-999)),ravel(sattmp))
if sum(sum(rdata)) == 0:
av = 0
else:
av = average(rdata,axis=None)
tmparray[0,index] = av
tmparray[1,index] = z
index += 1
print tmparray
***********************************
But the tmparray is returning zeros as averages. When I try just one
value for z everything works. I can't see where I going wrong. I am not
using the original arrays, only the copies and when a new z is chosen
then these are recreated.

Care to help out with this?
/Sheldon

Carl Banks wrote:
Sheldon wrote:
Hi,

I have the following loop that I think can be written to run faster in
Numeric. I am currently using Numeric.
range_va = [60,61,62,63,64,65,66,67,68,69,70,71,72]
main.xsize= 600
main.ysize= 600
#msgva is an (600x600) Numeric array with mutiple occurrences of the
values in range_va
#sat_id is an (600x600) Numeric array with values ranging from -2 to 2
for z in range_va:
count = 0
mbias = 0
for i in range(main.xsize):
for j in range(main.ysize):
if msgva[i,j] == z:
mbias += sat_id[i,j] # take the sum of the
values
count += 1 # count the occurrences
tmp_array[0,index] = round(mbias/count,1) # store the mean
tmp_array[1,index] = z
index += 1

Any help would be greatly appreciated!

I'm not sufficiently sure this isn't a homework problem, so here's a

Your intuition is correct--there's almost always a faster way to do it
when you're cycling through Numeric array indices in a Python for loop.
Numeric and successors exist mostly to get rid of them.

Given z, you can calculate mbias in one line:

mbias = Numeric.sum(
Numeric.ravel(Numeric.where(msgva==z,sat_id,0)))

Here, the Numeric.where function allows you to filter out entries: it
returns an array with the elements of sat_id, but only where the
corresponding element of msvga==z; otherwise the entry is zero.
Numeric.ravel flattens an multidimensional array into one dimension,
and, of course, Numeric.sum adds up all the elements in the array.

How to get count and to work this into your loop are left as an
exercise.
Carl Banks

Jun 29 '06 #3
Sheldon wrote:
Carl Banks wrote:
I'm not sufficiently sure this isn't a homework problem, so here's a
[snip]
My days as a student is over for the most part. I am learning python on
my own and Numeric is not properly documented so I am learning by doing
and copying from others.
Are you aware of this guide?

http://numeric.scipy.org/numpydoc/numdoc.htm

I've seen better documents but it's fairly complete--I wouldn't call it
improper.

I thought about the problem and a solution
another problem given to me earlier using "putmask" is the solution but
there is a bug that I cannot figure out:
************************
index = 0
for z in range_va:
wk = msgva # working arrary
sattmp = sat_id # working array
This appears to be doing something you don't expect. In Python all
names are references; assignments don't create new objects but rather
new names for the same object. In the above, wk and msvga are the same
array: any changes in wk also appear in msvga. So wk[1,1] = 4 also
causes msgva[1,1] to be 4.

Numeric arrays even share data when slicing. If you were to take a
slice of wk, for example, a = wk[0:10,0:10], then modifying a would
also show up in wk (and msvga). (However, slicing most other objects
copies rather than shares the data.)

It's completely different from Matlab, which always copies data.

Here's what you should do:

wk = array(msgva) # this creates a new array for wk
sattmp = array(sat_id)
valid data pixs
Note that the "where" is unnecessary here. equal creates an array of
ones and zeros.
This would overwrite sat_id unless you copy the array as I've shown
above.
rdata =
compress(ravel(not_equal(sattmp,-999)),ravel(sattmp))
I believe you could avoid the above putmask above step and just use
ravel(mask) as the first argument of compress here, or even just
equal(wk,z).

"equal(wx,z)", "mask", and "not_equal(sattmp,-999)" are all equal
arrays.
if sum(sum(rdata)) == 0:
av = 0
rdata is one-dimensional, so you only need one sum call; but why do
this? average will still work if the sum is zero.
else:
av = average(rdata,axis=None)
axis argument isn't necessary here since rdata is one-dimesional.
tmparray[0,index] = av
tmparray[1,index] = z
index += 1
print tmparray
***********************************
But the tmparray is returning zeros as averages. When I try just one
value for z everything works. I can't see where I going wrong. I am not
using the original arrays, only the copies and when a new z is chosen
then these are recreated.
Care to help out with this?
/Sheldon

Other than the array sharing mistake, it looks like it should work.

Also, note that this group disdains top-posting; replies should go
below the quoted text because in these sorts of discussions it's best
to keep things in conversational order, especially for the sake of

Good luck.
Carl Banks

Jun 29 '06 #4
On Thu, 29 Jun 2006 05:25:25 -0400, Sheldon <sh******@gmail.com> wrote:
I am learning python on
my own and Numeric is not properly documented

1. Use NumPy (Numeric's successor): http://www.numpy.org/
2. Documentation is excellent: http://www.tramy.us/
(Also see http://www.scipy.org/Cookbook )

Cheers,
Alan Isaac
Jun 29 '06 #5
Carl Banks wrote:
Sheldon wrote:
Carl Banks wrote:
I'm not sufficiently sure this isn't a homework problem, so here's a

[snip]

My days as a student is over for the most part. I am learning python on
my own and Numeric is not properly documented so I am learning by doing
and copying from others.

Are you aware of this guide?

http://numeric.scipy.org/numpydoc/numdoc.htm

I've seen better documents but it's fairly complete--I wouldn't call it
improper.

I thought about the problem and a solution
another problem given to me earlier using "putmask" is the solution but
there is a bug that I cannot figure out:
************************
index = 0
for z in range_va:
wk = msgva # working arrary
sattmp = sat_id # working array

This appears to be doing something you don't expect. In Python all
names are references; assignments don't create new objects but rather
new names for the same object. In the above, wk and msvga are the same
array: any changes in wk also appear in msvga. So wk[1,1] = 4 also
causes msgva[1,1] to be 4.

Numeric arrays even share data when slicing. If you were to take a
slice of wk, for example, a = wk[0:10,0:10], then modifying a would
also show up in wk (and msvga). (However, slicing most other objects
copies rather than shares the data.)

It's completely different from Matlab, which always copies data.

Here's what you should do:

wk = array(msgva) # this creates a new array for wk
sattmp = array(sat_id)
valid data pixs

Note that the "where" is unnecessary here. equal creates an array of
ones and zeros.

This would overwrite sat_id unless you copy the array as I've shown
above.
rdata =
compress(ravel(not_equal(sattmp,-999)),ravel(sattmp))

I believe you could avoid the above putmask above step and just use
ravel(mask) as the first argument of compress here, or even just
equal(wk,z).

"equal(wx,z)", "mask", and "not_equal(sattmp,-999)" are all equal
arrays.
if sum(sum(rdata)) == 0:
av = 0

rdata is one-dimensional, so you only need one sum call; but why do
this? average will still work if the sum is zero.
else:
av = average(rdata,axis=None)

axis argument isn't necessary here since rdata is one-dimesional.
tmparray[0,index] = av
tmparray[1,index] = z
index += 1
print tmparray
***********************************
But the tmparray is returning zeros as averages. When I try just one
value for z everything works. I can't see where I going wrong. I am not
using the original arrays, only the copies and when a new z is chosen
then these are recreated.
Care to help out with this?
/Sheldon

Other than the array sharing mistake, it looks like it should work.

Also, note that this group disdains top-posting; replies should go
below the quoted text because in these sorts of discussions it's best
to keep things in conversational order, especially for the sake of

Good luck.
Carl Banks

Thanks for the tips about the array and how it is copied. I figured
this out late yesterday and wrote a dirty solution to this problem but
your is more elegant and concise.
Yes, where statement is not needed and I removed it. The replacement is
the following:

average(compress(ravel(equal(wk,z)),ravel(sattmp)) ,axis=None)
This is much more compact and elegant. Thanks for pointing this out.
I don't know why average() returned a divide by zero error and to avoid
this I inserted this if statement. Now it works much better !

Much obliged,
Sheldon

Jun 30 '06 #6
Sheldon wrote:
average(compress(ravel(equal(wk,z)),ravel(sattmp)) ,axis=None)
This is much more compact and elegant. Thanks for pointing this out.
I don't know why average() returned a divide by zero error and to avoid
this I inserted this if statement. Now it works much better !

Probably you had a case where the array length was zero, but it
wouldn't happen in the present case unless your input arrays are zero
by zero.
Carl Banks

Jun 30 '06 #7

Carl Banks wrote:
Sheldon wrote:
average(compress(ravel(equal(wk,z)),ravel(sattmp)) ,axis=None)
This is much more compact and elegant. Thanks for pointing this out.
I don't know why average() returned a divide by zero error and to avoid
this I inserted this if statement. Now it works much better !

Probably you had a case where the array length was zero, but it
wouldn't happen in the present case unless your input arrays are zero
by zero.
Carl Banks
Thanks for you help kind Sir!

/Sheldon

Jul 3 '06 #8

### This discussion thread is closed

Replies have been disabled for this discussion.