<br><br><div class="gmail_quote">On 26 June 2012 04:20, Saurabh Kabra <span dir="ltr"><<a href="mailto:skabra@gmail.com" target="_blank">skabra@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">Thanks guys </span></div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><div>
<span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br></span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">I implemented a numpy array with fancy indices and got rid of the list and the loops. The time to do the mapping improved ~10x. As a matter of fact, the number of elements in array A to be summed and mapped was different for each element in B (which was the reason I was using lists). But I solved that problem by simply adding zero elements to make a regular 3D numpy array out of the list.</span></div>
</span></blockquote><div><br></div><div>Is that good enough, or are you looking for more speedup?</div><div><br></div><div>Padding with zeros to create the larger-than-needed array may be less time-efficient (and is definitely less memory efficient) than extracting each subarray in a loop. Consider the following:</div>
<div><br></div><div><div>>>> import numpy</div><div>>>> a = numpy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])</div><div>>>> a</div><div>array([[1, 2, 3],</div><div>       [4, 5, 6],</div><div>       [7, 8, 9]])</div>
<div>>>> af = a.flatten()</div><div>>>> af</div><div>array([1, 2, 3, 4, 5, 6, 7, 8, 9])</div><div>>>> indices = [[1, 7, 8], [0, 1], [8, 4]]</div><div>>>> indices = [numpy.array(inds) for inds in indices]</div>
<div>>>> indices</div><div>[array([1, 7, 8]), array([0, 1]), array([8, 4])]</div><div>>>> for inds in indices:</div><div>...     print inds, af[inds], af[inds].sum()</div><div>...</div><div>[1 7 8] [2 8 9] 19</div>
<div>[0 1] [1 2] 3</div><div>[8 4] [9 5] 14</div><div><br></div><div>Knowing the most efficient way depends on a number of things. The first would be whether or not the operation you're describing is repeated. If, for example, you keep doing this for the same indices but each time changing the array A then you should try precomputing all the indices as a list of numpy arrays (as shown above).</div>
</div><div><br></div><div>On the other hand, if you're repeating with the same matrix A but different sets of indices, you'll need to think about how you are generating the indices.</div><div><br></div><div>In my experience the fastest way to do something like this would be to use cython as suggested above by Stefan.</div>
<div><br></div><div>Oscar.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><div>
<span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"> </span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br></span></div><div>Saurabh</div><div><div class="h5"><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br>

</span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br></span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br>
</span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br></span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br>
</span></div>On 25 June 2012 08:24, Stefan Behnel </div></div></span><span dir="ltr" style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><<a href="mailto:stefan_ml@behnel.de" style="color:rgb(17,85,204)" target="_blank">stefan_ml@behnel.de</a>></span><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"> wrote:</span><div class="HOEnZb">
<div class="h5"><br style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">
<blockquote class="gmail_quote" style="padding-left:1ex;border-left-color:rgb(204,204,204);color:rgb(34,34,34);border-left-style:solid;font-size:13px;margin:0px 0px 0px 0.8ex;font-family:arial,sans-serif;border-left-width:1px">

Saurabh Kabra, <a href="tel:25.06.2012%2005" value="+12506201205" style="color:rgb(17,85,204)" target="_blank">25.06.2012 05</a>:37:<br><div>> I have written a script to map a 2D numpy array(A) onto another array(B) of<br>

> different dimension. more than one element (of array A) are summed and<br>> mapped to each element of array B.  To achieve this I create a list where I<br>> store the index of array A to be mapped to array B. The list is the<br>

> dimension of array B (if one can technically say that) and each element is<br>> a list of indices to be summed. Then I parse this list with a nested loop<br>> and compute each element of array B. </div></blockquote>

<blockquote class="gmail_quote" style="padding-left:1ex;border-left-color:rgb(204,204,204);color:rgb(34,34,34);border-left-style:solid;font-size:13px;margin:0px 0px 0px 0.8ex;font-family:arial,sans-serif;border-left-width:1px">

<div>><br>> Because of the nested loop and the big arrays the process takes a minute or<br>> so. My question is: is there a more elegant and significantly faster way of<br>> doing this in python?<br><br></div>

I'm sure there's a way to do this kind of transformation more efficiently<br>in NumPy. I faintly recall that you can use one array to index into<br>another, something like that might do the trick already. In any case, using<br>

a NumPy array also for the mapping matrix sounds like a straight forward<br>thing to try.<br></blockquote><div style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br>
</div><div style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">I can't tell from the description of the problem what you're trying to do but for the special case of summing along one axis of a numpy array of dimension N to produce a new numpy array of dimension N-1, there is  fast builtin support in numpy:</div>

<div style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br></div><div style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">
<div>>>> import numpy</div><div>>>> a = numpy.array([[1, 2], [3, 4]])</div><div>>>> a</div><div>array([[1, 2],</div><div>       [3, 4]])</div><div>>>> a.sum()   # sum of all elements</div>

<div>10</div><div>>>> a.sum(axis=1)  # sum of each row</div><div>array([3, 7])</div><div>>>> a.sum(axis=0)  # sum of each column</div><div>array([4, 6])</div></div><div style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">

<br></div><div style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">If your problem is not in this form, you can use numpy's fancy indexing to convert it to this form, provided the number of elements summed from A is the same for each element of B (i.e. if each element of B is the result of summing exactly 10 elements chosen from A).</div>

<div style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br></div><blockquote class="gmail_quote" style="padding-left:1ex;border-left-color:rgb(204,204,204);color:rgb(34,34,34);border-left-style:solid;font-size:13px;margin:0px 0px 0px 0.8ex;font-family:arial,sans-serif;border-left-width:1px">

<br>But you might also want to take a look at Cython. It sounds like a problem<br>where a trivial Cython implementation would seriously boost the performance.<br><br><a href="http://docs.cython.org/src/tutorial/numpy.html" style="color:rgb(17,85,204)" target="_blank">http://docs.cython.org/src/tutorial/numpy.html</a></blockquote>

<blockquote class="gmail_quote" style="padding-left:1ex;border-left-color:rgb(204,204,204);color:rgb(34,34,34);border-left-style:solid;font-size:13px;margin:0px 0px 0px 0.8ex;font-family:arial,sans-serif;border-left-width:1px">

<br><font color="#888888"><br>Stefan<br></font></blockquote>
</div></div><br>--<br>
<a href="http://mail.python.org/mailman/listinfo/python-list" target="_blank">http://mail.python.org/mailman/listinfo/python-list</a><br>
<br></blockquote></div><br>