1

Suppose I construct a numpy record array like this

num_rows = <whatever>
data = np.zeros(
    (num_rows,),
    dtype={
        'names':['apple', 'banana'],
        'formats': ['f8', 'f8']
    }

Now I can access data either by name or index. For example, the following are the same:

data['banana'][0]

and

data[0]['banana']

etc. Is there a way to alias different names? For example, can I set things up so that there's another name manzana such that

data['manzana']

is the same thing as

data['apple']

?

2 Answers 2

3

['offsets' and 'titles' are 2 mechanisms for giving different names to fields]

There is an offset parameter that can function in this way. Usually it is used to split another field into several pieces (e.g. an int into bytes). But it also works with identical fields. In effect it defines several fields with overlapping data.

In [743]: dt=np.dtype({'names':['apple','manzana','banana','guineo'],
       'formats':['f8','f8','f8','f8'], 
       'offsets':[0,0,8,8]})

In [745]: np.zeros((3,),dtype=dt)
Out[745]: 
array([(0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0)], 
      dtype={'names':['apple','manzana','banana','guineo'], 
        'formats':['<f8','<f8','<f8','<f8'], 
        'offsets':[0,0,8,8], 'itemsize':16})

In [746]: A=np.zeros((3,),dtype=dt)

In [747]: A['banana']=[1,2,3]

In [748]: A
Out[748]: 
array([(0.0, 0.0, 1.0, 1.0),  
       (0.0, 0.0, 2.0, 2.0), 
       (0.0, 0.0, 3.0, 3.0)], 
      dtype={'names':['apple','manzana','banana','guineo'], 'formats':['<f8','<f8','<f8','<f8'], 'offsets':[0,0,8,8], 'itemsize':16})

In [749]: A['guineo']
Out[749]: array([ 1.,  2.,  3.])

In [750]: A['manzana']=[.1,.2,.3]

In [751]: A['apple']
Out[751]: array([ 0.1,  0.2,  0.3])

In [752]: A
Out[752]: 
array([(0.1, 0.1, 1.0, 1.0),  
       (0.2, 0.2, 2.0, 2.0), 
       (0.3, 0.3, 3.0, 3.0)], 
      dtype={'names':['apple','manzana','banana','guineo'], 'formats':['<f8','<f8','<f8','<f8'], 'offsets':[0,0,8,8], 'itemsize':16})

There's another dtype parameter, titles that is better suited to your needs, and easier to understand:

http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html

In [792]: dt1=np.dtype({'names':['apple','banana'],'formats':['f8','f8'], 'titles':['manzana', 'guineo'], 'offsets':[0,8]})

In [793]: A1=np.zeros((3,),dtype=dt1)

In [794]: A1
Out[794]: 
array([(0.0, 0.0), (0.0, 0.0), (0.0, 0.0)], 
      dtype=[(('manzana', 'apple'), '<f8'), (('guineo', 'banana'), '<f8')])

In [795]: A1['apple']=[1,2,3]

In [796]: A1['guineo']=[.1,.2,.3]

In [797]: A1
Out[797]: 
array([(1.0, 0.1), (2.0, 0.2), (3.0, 0.3)], 
      dtype=[(('manzana', 'apple'), '<f8'), (('guineo', 'banana'), '<f8')])

In [798]: A1['banana']
Out[798]: array([ 0.1,  0.2,  0.3])
Sign up to request clarification or add additional context in comments.

2 Comments

I get the idea but I don't understand the particulars here. It looks like banana and guineo have offsets of 8. How is that making apple and manzana share data? I'm probably missing something obvious.
With the same offset, apple and manzana are different fields that share data. But I found titles which is closer to your idea of aliases.
0

I have put the answer of @hpaulj into a simple method and share it here in case someone wants to use it.

def add_alias(arr, original, alias):
    """
    Adds an alias to the field with the name original to the array arr.
    Only one alias per field is allowed.
    """

    if arr.dtype.names is None:
        raise TypeError("arr must be a structured array. Use add_name instead.")
    descr = arr.dtype.descr

    try:
        index = arr.dtype.names.index(original)
    except ValueError:
        raise ValueError("arr does not have a field named '" + str(original) 
                         + "'")

    if type(descr[index][0]) is tuple:
        raise ValueError("The field " + str(original) + 
                         " already has an alias.")

    descr[index] = ((alias, descr[index][0]), descr[index][1])
    arr.dtype = np.dtype(descr)
    return arr

def add_name(arr, name):
    """
    Adds a name to the data of an unstructured array.
    """

    if arr.dtype.names is not None:
        raise TypeError("arr must not be a structured array. "
                        + "Use add_alias instead.")
    arr.dtype = np.dtype([(name, arr.dtype.name)])
    return arr

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.