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,
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
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
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
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,
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'.
participants (3)

Charles R Harris

Francesc Altet

Michael McNeil Forbes