Suppressing "nesting" (recursion, descent) in array construction.
Hi, I have a list of tuples that I am using as keys and I would like to sort this along with some other arrays using argsort. How can I do this? I would like to do something like: # These are constructed using lists because they accumulate using append() data = [1.0, 3,0] keys = [('a',1),('b',2)] # Convert to arrays for indexing data = array(data1) keys = array(keys) # <Converts to a 2d array rather than 1d array of tuples . inds = argsort(data) data[:] = data[inds] keys[:] = keys[inds] It seems there should be some way of specifying to the array constructor not to 'descend' (perhaps by specifying the desired dimensions of the final array or something) but I cannot find a nice way around this. Any suggestions? Thanks, Michael.
El dc 20 de 06 del 2007 a les 01:38 0700, en/na Michael McNeil Forbes va escriure:
Hi,
I have a list of tuples that I am using as keys and I would like to sort this along with some other arrays using argsort. How can I do this? I would like to do something like:
# These are constructed using lists because they accumulate using append() data = [1.0, 3,0] keys = [('a',1),('b',2)]
# Convert to arrays for indexing data = array(data1) keys = array(keys) # <Converts to a 2d array rather than 1d array of tuples .
inds = argsort(data) data[:] = data[inds] keys[:] = keys[inds]
It seems there should be some way of specifying to the array constructor not to 'descend' (perhaps by specifying the desired dimensions of the final array or something) but I cannot find a nice way around this.
Here is a possible approach using recarrays: In [54]:data = [3.0, 1.0] In [55]:keys = [('a',1),('b',2)] In [56]:tmp=numpy.array(keys, dtype="S1,i4") In [57]:dest=numpy.empty(shape=len(keys), dtype="S1,i4,f8") In [58]:dest['f0'] = tmp['f0'] In [59]:dest['f1'] = tmp['f1'] In [60]:dest['f2'] = data In [61]:dest Out[61]: array([('a', 1, 3.0), ('b', 2, 1.0)], dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<f8')]) In [62]:dest.sort(order='f2') In [63]:dest Out[63]: array([('b', 2, 1.0), ('a', 1, 3.0)], dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<f8')]) If you want to retrieve the keys and data from the dest recarray afterwards, that's easy: In [111]:data2=dest['f2'].tolist() In [112]:keys2=dest.getfield('S1,i4').tolist() In [113]:data2 Out[113]:[1.0, 3.0] In [114]:keys2 Out[114]:[('b', 2), ('a', 1)] Cheers,  Francesc Altet  Be careful about using the following code  Carabos Coop. V.  I've only proven that it works, www.carabos.com  I haven't tested it.  Donald Knuth
Hi, That is a little more complicated than I want, but it shows me the solution: Construct the array of the desired shape first, then fill it. data = [1.0, 3,0] keys = [('a',1),('b',2)] # Convert to arrays for indexing data_array = array(data1) key_array = empty(len(keys),dtype=tuple) key_array[:] = keys[:] inds = argsort(data) data_array[:] = data[inds] key_array[:] = keys[inds] Thanks! Michael. On 20 Jun 2007, at 4:57 AM, Francesc Altet wrote:
El dc 20 de 06 del 2007 a les 01:38 0700, en/na Michael McNeil Forbes va escriure:
Hi,
I have a list of tuples that I am using as keys and I would like to sort this along with some other arrays using argsort. How can I do this? I would like to do something like:
# These are constructed using lists because they accumulate using append() data = [1.0, 3,0] keys = [('a',1),('b',2)]
# Convert to arrays for indexing data = array(data1) keys = array(keys) # <Converts to a 2d array rather than 1d array of tuples .
inds = argsort(data) data[:] = data[inds] keys[:] = keys[inds]
It seems there should be some way of specifying to the array constructor not to 'descend' (perhaps by specifying the desired dimensions of the final array or something) but I cannot find a nice way around this.
Here is a possible approach using recarrays:
In [54]:data = [3.0, 1.0] In [55]:keys = [('a',1),('b',2)] In [56]:tmp=numpy.array(keys, dtype="S1,i4") In [57]:dest=numpy.empty(shape=len(keys), dtype="S1,i4,f8") In [58]:dest['f0'] = tmp['f0'] In [59]:dest['f1'] = tmp['f1'] In [60]:dest['f2'] = data In [61]:dest Out[61]: array([('a', 1, 3.0), ('b', 2, 1.0)], dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<f8')]) In [62]:dest.sort(order='f2') In [63]:dest Out[63]: array([('b', 2, 1.0), ('a', 1, 3.0)], dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<f8')])
If you want to retrieve the keys and data from the dest recarray afterwards, that's easy:
In [111]:data2=dest['f2'].tolist() In [112]:keys2=dest.getfield('S1,i4').tolist() In [113]:data2 Out[113]:[1.0, 3.0] In [114]:keys2 Out[114]:[('b', 2), ('a', 1)]
Cheers,
 Francesc Altet  Be careful about using the following code  Carabos Coop. V.  I've only proven that it works, www.carabos.com  I haven't tested it.  Donald Knuth
El dc 20 de 06 del 2007 a les 12:43 0700, en/na Michael McNeil Forbes va escriure:
Hi,
That is a little more complicated than I want, but it shows me the solution: Construct the array of the desired shape first, then fill it.
data = [1.0, 3,0] keys = [('a',1),('b',2)]
# Convert to arrays for indexing data_array = array(data1) key_array = empty(len(keys),dtype=tuple) key_array[:] = keys[:]
the later two statements can also be written as: key_array = array(keys, dtype=tuple)
inds = argsort(data) data_array[:] = data[inds] key_array[:] = keys[inds]
Yeah, much simpler than my first approach. Cheers,  Francesc Altet  Be careful about using the following code  Carabos Coop. V.  I've only proven that it works, www.carabos.com  I haven't tested it.  Donald Knuth
key_array = empty(len(keys),dtype=tuple) key_array[:] = keys[:]
the later two statements can also be written as:
key_array = array(keys, dtype=tuple)
These are not equivalent:
keys = [('a',1),('b',2)] key_array = array(keys, dtype=tuple) key_array array([[a, 1], [b, 2]], dtype=object)
key_array = empty(len(keys),dtype=tuple) key_array[:] = keys[:] key_array array([('a', 1), ('b', 2)], dtype=object)
Thanks, Michael.
El dj 21 de 06 del 2007 a les 06:24 0700, en/na Michael McNeil Forbes va escriure:
key_array = empty(len(keys),dtype=tuple) key_array[:] = keys[:]
the later two statements can also be written as:
key_array = array(keys, dtype=tuple)
These are not equivalent:
keys = [('a',1),('b',2)] key_array = array(keys, dtype=tuple) key_array array([[a, 1], [b, 2]], dtype=object)
key_array = empty(len(keys),dtype=tuple) key_array[:] = keys[:] key_array array([('a', 1), ('b', 2)], dtype=object)
Ops. You are right. I think I was fooled by the 'dtype=tuple' argument which is in fact equivalent to 'dtype=object'.  Francesc Altet  Be careful about using the following code  Carabos Coop. V.  I've only proven that it works, www.carabos.com  I haven't tested it.  Donald Knuth
On 6/20/07, Michael McNeil Forbes <mforbes@physics.ubc.ca> wrote:
Hi,
I have a list of tuples that I am using as keys and I would like to sort this along with some other arrays using argsort. How can I do this? I would like to do something like:
You might want the keys in an object array, otherwise you end up with strings for all the values. Why are they keys? Do you want to sort on them also? Anyway, if you use take(keys, inds, axis=0) you will get an array with the rows containing the keys rearranged as I think you want. Chuck
Using take or array or similar operations on the initial list descends ignoring the tuples and converting the list to a multiple dimension array:
take(keys,[1,0],axis=0) array([['b', '2'], ['a', '1']], dtype='S4')
It is sorted as I want, but I can nolonger use them as keys. The problem can be solved by creating an empty array first, then copying. Thanks, Michael.
On 6/20/07, Michael McNeil Forbes <mforbes@physics.ubc.ca> wrote: Hi,
I have a list of tuples that I am using as keys and I would like to sort this along with some other arrays using argsort. How can I do this? I would like to do something like:
You might want the keys in an object array, otherwise you end up with strings for all the values. Why are they keys? Do you want to sort on them also? Anyway, if you use take(keys, inds, axis=0) you will get an array with the rows containing the keys rearranged as I think you want.
Chuck
participants (3)

Charles R Harris

Francesc Altet

Michael McNeil Forbes