<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Dec 3, 2014 at 2:21 AM, Emanuele Olivetti <span dir="ltr"><<a href="mailto:emanuele@relativita.com" target="_blank">emanuele@relativita.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">On 12/03/2014 04:32 AM, Ryan Nelson wrote:<br>
> Emanuele,<br>
><br>
> This doesn't address your question directly. However, I wonder if you<br>
> could approach this problem from a different way to get what you want.<br>
><br>
> First of all, create a "index" array and then just vstack all of your<br>
> arrays at once.<br>
><br>
><br>
<br>
Ryan,<br>
<br>
Thank you for your solution. Indeed it works. But it seems to me<br>
that manually creating an index and re-implementing slicing<br>
should be the last resort. NumPy is *great* and provides excellent<br>
slicing and assembling tools. For some reason, that I don't fully<br>
understand, when dtype=np.object the ndarray constructor<br>
tries to be "smart" and creates unexpected results that cannot<br>
be controlled.<br>
<br>
Another simple example:<br>
---<br>
import numpy as np<br>
from numpy.random import rand, randint<br>
n_arrays = 4<br>
shape0_min = 2<br>
shape0_max = 4<br>
for a in range(30):<br>
     list_of_arrays = [rand(randint(shape0_min, shape0_max), 3) for i in<br>
range(n_arrays)]<br>
     array_of_arrays = np.array(list_of_arrays, dtype=np.object)<br>
     print("shape: %s" % (array_of_arrays.shape,))<br>
---<br>
the usual output is:<br>
shape: (4,)<br>
but from time to time, when the randomly generated arrays have - by chance - the<br>
same shape, you get:<br>
shape: (4, 2, 3)<br>
which may crash your code at runtime.<br>
<br>
To NumPy developers: is there a specific reason for np.array(..., dtype=np.object)<br>
to be "smart" instead of just assembling an array with the provided objects?<br></blockquote><div><br></div><div>The safe way to create 1D object arrays from a list is by preallocating them, something like this:</div><div><br></div><div><div>>>> a = [np.random.rand(2, 3), np.random.rand(2, 3)]</div><div>>>> b = np.empty(len(a), dtype=object)</div><div>>>> b[:] = a</div><div>>>> b</div><div>array([ array([[ 0.124382  ,  0.04489531,  0.93864908],</div><div>       [ 0.77204758,  0.63094413,  0.55823578]]),</div><div>       array([[ 0.80151723,  0.33147467,  0.40491018],</div><div>       [ 0.09905844,  0.90254708,  0.69911945]])], dtype=object)</div></div><div><br></div><div>It's only a tad more verbose than your current code, and you can always wrap it in a helper function if you find 2 lines of code to be too many.</div><div><br></div><div>As to why np.array tries to be smart, keep in mind that there are other applications of object arrays than having stacked sequences. The following code computes the 100-th Fibonacci number using the matrix form of the recursion (<a href="http://en.wikipedia.org/wiki/Fibonacci_number#Matrix_form">http://en.wikipedia.org/wiki/Fibonacci_number#Matrix_form</a>), numpy's linear algebra capabilities, and Python's arbitrary precision ints:</div><div><br></div><div><div>>>> a = np.array([[0, 1], [1, 1]], dtype=object)</div><div>>>> np.linalg.matrix_power(a, 99)[0, 0]</div><div>135301852344706746049L</div></div><div><br></div><div>Trying to do this with any other type would result in either wrong results due to overflow:</div><div><br></div><div><div>>>> a = np.array([[0, 1], [1, 1]])</div><div>>>> np.linalg.matrix_power(a, 99)[0, 0]</div><div>-90618175</div></div><div><br></div><div>or lost precision:</div><div><br></div><div><div>>>> a = np.array([[0, 1], [1, 1]], dtype=np.double)</div><div>>>> np.linalg.matrix_power(a, 99)[0, 0]</div><div>1.3530185234470674e+20</div></div><div><br></div><div>Jaime</div></div>-- <br><div class="gmail_signature">(\__/)<br>( O.o)<br>( > <) Este es Conejo. Copia a Conejo en tu firma y ayúdale en sus planes de dominación mundial.</div>
</div></div>