map
Fernando Perez
fperez528 at yahoo.com
Fri Jun 7 15:24:47 EDT 2002
Giorgi Lekishvili wrote:
> Hi all!
>
> Is there a way to map a function with several arguments to a list? E.g.,
>
>>>>import math
>>>>import MLab
>>>>a=MLab.rand(3,5)
>>>>b=map(math.pow,a)
>
> of course, this doesn't work.
>
> What to do? My task is to optimize the power (i.e., y in pow(x,y)) to
> achieve maximal performance.
>
>
> thanx,
> Giorgi
>
> PS: Perhaps I have missed the needed functionality, that's presented in
> NumPy?
It's hard to tell what you're trying to do, since a 3x5 array doesn't have an
'obvious' way to be used as an argument to pow. But anyway, for 'maximal
performance' you should use NumPy the way it was meant to be used. It already
overloads ** so you can just write:
In [1]: import MLab
In [2]: a=MLab.rand(3,5)
In [3]: a
Out[3]:
array([[ 0.7906459 , 0.9962979 , 0.59841698, 0.13870062, 0.93503422],
[ 0.03783634, 0.68916065, 0.79217309, 0.23443535, 0.87729597],
[ 0.04226565, 0.4821128 , 0.8859337 , 0.45935223, 0.47994375]])
In [4]: a**3
Out[4]:
array([[ 4.94249303e-01, 9.88934754e-01, 2.14294850e-01,
2.66830335e-03,
8.17490114e-01],
[ 5.41660550e-05, 3.27311607e-01, 4.97118874e-01,
1.28845512e-02,
6.75209283e-01],
[ 7.55027297e-05, 1.12058801e-01, 6.95350325e-01,
9.69253713e-02,
1.10553126e-01]])
As a rule of thumb, in Numeric NEVER roll your own loops (even using map).
Right there you kill all of the speed advantage of NumPy. If you can't find a
way to write things with Numeric's functions and absolutely need to loop by
hand, it will be dog slow. At that point, your only option is to write the
tight loops in C, which is actually extremely easy to do using weave
(http://scipy.org)
Here's a quick comparison showing the disaster you're heading into if you try
to use loops/map instead of properly using numeric:
In [1]: import MLab, Numeric
In [2]: def loop_pow3(arr):
...: out = Numeric.zeros(len(arr),arr.typecode())
...: for i in xrange(len(arr)):
...: out[i] = arr[i]**3
...: return out
...:
In [3]: numpow3 = lambda x:x**3
In [4]: pow3=lambda x: pow(x,3)
In [5]: a=MLab.rand(100000)
In [6]: time_test (1,numpow3,a)
Out[6]: 0.070000000000000062
In [7]: time_test (1,map,pow3,a)
Out[7]: 1.1199999999999999
In [8]: time_test (1,loop_pow3,a)
Out[8]: 0.54000000000000004
In [9]: _7/_6
Out[9]: 15.999999999999984
In [10]: _8/_6
Out[10]: 7.7142857142857082
So in summary, using map is a factor of 16 slower than using Numeric's
builtin operators (or rather its natural overloading of **) and using loops
is a factor of 8 slower.
Unless you have a lot of time to sit around and wait, I'd recommmend spending
an hour or two cuddled up with the Numeric documentation. It's a complete (if
'creatively' organized ;) reference.
Cheers,
f.
More information about the Python-list
mailing list