pyhrf.ndarray module

pyhrf.ndarray module

pyhrf.ndarray module – This module provides classes and functions to handle multi-dimensionnal numpy array (ndarray) objects and extend them with some semantics (axes labels and axes domains). See xndarray class. (TODO: make xndarray inherit numpy.ndarray?)exception pyhrf.ndarray.ArrayMappingError

Bases: exceptions.Exceptionpyhrf.ndarray.expand_array_in_mask(flat_datamaskflat_axis=0dest=Nonem=None)

Map the flat_axis of flat_data onto the region within mask. flat_data is then reshaped so that flat_axis is replaced with mask.shape

m is the result of np.where(mask) -> can be passed to speed up if already done before

Example 1 >>> a = np.array([1,2,3]) >>> m = np.array([[0,1,0], [0,1,1]] ) >>> expand_array_in_mask(a,m) array([[0, 1, 0],[0, 2, 3]])

Example 2 >>> a = np.array([[1,2,3],[4,5,6]]) >>> m = np.array([[0,1,0], [0,1,1]] ) >>> expand_array_in_mask(a,m,flat_axis=1) array([[[0, 1, 0],[0, 2, 3]],<BLANKLINE>[[0, 4, 0],[0, 5, 6]]])pyhrf.ndarray.merge(arraysmaskaxisfill_value=0)

Merge the given arrays into a single array according to the given mask, with the given axis being mapped to those of mask. Assume that arrays[id] corresponds to mask==id and that all arrays are in the same orientation.Arg:

pyhrf.ndarray module
  • arrays (dict of xndarrays):
  • mask (xndarray): defines the mapping between the flat axis in thearrays to merge and the target expanded axes.
  • axis (str): flat axis for the


Stack xndarray instances in list ‘c_list’ along a new axis label ‘axis’. If ‘domain’ (numpy array or list) is provided, it is associated to the new axis. All cuboids in ‘c_list’ must have the same orientation and domains. ‘axis_pos’ defines the position of the new axis: either ‘first’ or ‘last’.

Example: >>> import numpy as np >>> from pyhrf.ndarray import xndarray, stack_cuboids >>> c1 = xndarray(np.arange(4*3).reshape(4,3), [‘x’,’y’]) >>> c1 axes: [‘x’, ‘y’], array([[ 0, 1, 2],[ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]])

>>> c2 = xndarray(np.arange(4*3).reshape(4,3)*2, ['x','y'])
>>> c2
axes: ['x', 'y'], array([[ 0,  2,  4],
       [ 6,  8, 10],
       [12, 14, 16],
       [18, 20, 22]])
>>> c_stacked = stack_cuboids([c1,c2], 'stack_axis', ['c1','c2'])
>>> print c_stacked.descrip()  
* shape : (2, 4, 3)
* dtype : int64
* orientation: ['stack_axis', 'x', 'y']
* value label: value
* axes domains:
  'stack_axis': array(['c1', 'c2'],
  'x': arange(0,3,1)
  'y': arange(0,2,1)

TODO: enable broadcasting (?)pyhrf.ndarray.tree_to_xndarray(treelevel_labels=None)

Stack all arrays within input tree into a single array.

Parameters:tree () – nested dictionnaries of xndarray objects. Each level of the tree correspond to a target axis, each key of the tree correspond to an element of the domain associated to that axis.level_labels () – axis labels corresponding to each level of the tree
Returns:xndarray object

Example: >>> from pyhrf.ndarray import xndarray, tree_to_xndarray >>> d = { 1 : { .1 : xndarray([1,2], axes_names=[‘inner_axis’]), .2 : xndarray([3,4], axes_names=[‘inner_axis’]), }, 2 : { .1 : xndarray([1,2], axes_names=[‘inner_axis’]), .2 : xndarray([3,4], axes_names=[‘inner_axis’]), } } >>> tree_to_xndarray(d, [‘level_1’, ‘level_2’]) axes: [‘level_1’, ‘level_2’, ‘inner_axis’], array([[[1, 2],[3, 4]],<BLANKLINE>[[1, 2],[3, 4]]])class pyhrf.ndarray.xndarray(narrayaxes_names=Noneaxes_domains=Nonevalue_label=’value’meta_data=None)

Handles a multidimensional numpy array with axes that are labeled and mapped to domain values.

Example : c = xndarray( [ [4,5,6],[8,10,12] ], [‘time’,’position’], {‘time’:[0.1,0.2]} ) Will represent the following situation:

position ——-> 4 5 6 | t=0.1 |time 8 10 12 | t=0.2 v__eq__(other)

Return true if other cuboid contains the same data. TODO: should it be irrespective of the orientation ?add(cdest=None)astype(t)cexpand(cmaskaxisdest=None)

Same as expand but mask is a cuboid

TODO: + unit testcflatten(cmasknew_axis)copy(copy_meta_data=False)

Return copy of the current cuboid. Domains are copied with a shallow dictionnary copy.descrip()

Return a printable string describing the cuboid.descrip_shape()divide(cdest=None)expand(maskaxistarget_axes=Nonetarget_domains=Nonedest=Nonedo_checks=Truem=None)

Create a new xndarray instance (or store into an existing ‘dest’ cuboid) where ‘axis’ is expanded and values are mapped according to ‘mask’. ‘target_axes’ is a list of the names of the new axes replacing ‘axis’. ‘target_domains’ is a dict of domains for the new axes.

Example: >>> import numpy as np >>> from pyhrf.ndarray import xndarray >>> c_flat = xndarray(np.arange(2*6).reshape(2,6).astype(np.int64), [‘condition’, ‘voxel’], {‘condition’ : [‘audio’,’video’]}) >>> print c_flat.descrip() # doctest: +NORMALIZE_WHITESPACE * shape : (2, 6) * dtype : int64 * orientation: [‘condition’, ‘voxel’] * value label: value * axes domains:‘condition’: array([‘audio’, ‘video’],dtype=’|S5’)

‘voxel’: arange(0,5,1)

>>> mask = np.zeros((4,4,4), dtype=int)
>>> mask[:3,:2,0] = 1
>>> c_expanded = c_flat.expand(mask, 'voxel', ['x','y','z'])
>>> print c_expanded.descrip()  
* shape : (2, 4, 4, 4)
* dtype : int64
* orientation: ['condition', 'x', 'y', 'z']
* value label: value
* axes domains:
  'condition': array(['audio', 'video'],
  'x': arange(0,3,1)
  'y': arange(0,3,1)
  'z': arange(0,3,1)


Explode array according to the given n-ary mask so that axes matchin those of mask are flatten into new_axis.

Parameters:mask () – n-ary mask that defines “regions” used to split datanew_axis () – target flat axis
Returns:dict of xndarray that maps a mask value to a xndarray.


Explode array according to given n-ary mask so that axes are flatten into new_axis.

Parameters:mask () – n-ary mask that defines “regions” used to split dataaxes () – list of axes in the current object that are mapped onto the masknew_axis () – target flat axis
Returns:dict of xndarray that maps a mask value to a xndarray.


flatten cudoid.

TODO: +unit testget_axes_domains()

pyhrf.ndarray module

Return domains associated to axes as a dict (axis_name:domain array)get_axes_ids(axes_names)

Return the index of all axes in given axes_namesget_axis_id(axis_name)

Return the id of an axis from the given name.get_axis_name(axis_id)

Return the name of an axis from the given index ‘axis_id’.get_domain(axis_id)

Return the domain of the axis axis_id

example: >>> from pyhrf.ndarray import xndarray >>> c = xndarray(np.random.randn(10,2), axes_names=[‘x’,’y’], axes_domains={‘y’ : [‘plop’,’plip’]}) >>> (c.get_domain(‘y’) == np.array([‘plop’, ‘plip’], dtype=’|S4’)).all() True >>> c.get_domain(‘x’) #default domain made of slice indexes array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])get_domain_idx(axisvalue)

Get slice index from domain value for axis ‘axis’.get_dshape()

Return the shape of the array as dict mapping an axis name to the corresponding sizeget_extra_info(fmt=’dict’)get_ndims()get_new_axis_name()

Return an axis label not already in use. Format is: dim%dget_orientation()get_voxel_size(axis)

Return the size of a voxel along ‘axis’, only if meta data is available.has_axes(axes)has_axis(axis)len(axis)static load(file_name)

Load cuboid from file. Supported format: nifti1. Extra axis information is retrieved from a nifti extension if available. If it’s not available, label the axes as: (sagittal, coronal, axial[, time]).

TODO: gifti.map_onto(xmapping)

Reshape the array by mapping the axis corresponding to xmapping.value_label onto the shape of xmapping. :param – xmapping: array whose attribute value_labelmatches an axis of the current array

Returns:a new array (xndarray) where values from the current arrayhave been mapped according to xmapping

Example: >>> from pyhrf.ndarray import xndarray >>> import numpy as np >>> # data with a region axis: >>> data = xndarray(np.arange(2*4).reshape(2,4).T * .1, [‘time’, ‘region’], {‘time’:np.arange(4)*.5, ‘region’:[2, 6]}) >>> data axes: [‘time’, ‘region’], array([[ 0. , 0.4],[ 0.1, 0.5], [ 0.2, 0.6], [ 0.3, 0.7]])

>>> # 2D spatial mask of regions:
>>> region_map = xndarray(np.array([[2,2,2,6], [6,6,6,0], [6,6,0,0]]),                                   ['x','y'], value_label='region')
>>> # expand region-specific data into region mask
>>> # (duplicate values)
>>> data.map_onto(region_map)
axes: ['x', 'y', 'time'], array([[[ 0. ,  0.1,  0.2,  0.3],
        [ 0. ,  0.1,  0.2,  0.3],
        [ 0. ,  0.1,  0.2,  0.3],
        [ 0.4,  0.5,  0.6,  0.7]],

       [[ 0.4,  0.5,  0.6,  0.7],
        [ 0.4,  0.5,  0.6,  0.7],
        [ 0.4,  0.5,  0.6,  0.7],
        [ 0. ,  0. ,  0. ,  0. ]],

       [[ 0.4,  0.5,  0.6,  0.7],
        [ 0.4,  0.5,  0.6,  0.7],
        [ 0. ,  0. ,  0. ,  0. ],
        [ 0. ,  0. ,  0. ,  0. ]]])


Return a cuboid with new orientation. If cuboid is already in the right orientation, then return the current cuboid. Else, create a new one.repeat(nnew_axisdomain=None)

Return a new cuboid with self’s data repeated ‘n’ times along a new axis labelled ‘new_axis’. Associated ‘domain’ can be provided.rescale_values(v_min=0.0v_max=1.0axis=None)roll(axispos=-1)

Roll xndarray by making ‘axis’ the last axis. ‘pos’ is either 0 or -1 (first or last, respectively) TODO: handle all

Save cuboid to a file. Supported format: Nifti1. ‘meta_data’ shoud be a 2-elements tuple: (affine matrix, Nifti1Header instance). If provided, the meta_data attribute of the cuboid is ignored. All extra axis information is stored as an extension.set_MRI_orientation()

Set orientation to sagittal,coronal,axial,[time|iteration|condition] Priority for the 4th axis: time > condition > iteration. The remaining axes are sorted in alphatical orderset_axis_domain(axis_iddomain)

Set the value domain mapped to axis_id as domain

Parameters:axis_id () – label of the axisdomain () – value domain


Set the cuboid orientation (inplace) according to input axes labelssplit(axis)

Split a cuboid along given axis. Return an OrderedDict of cuboids.squeeze(axis=None)

Remove all dims which have length=1. ‘axis’ selects a subset of the single-dimensional axes.squeeze_all_but(axes)std(axis=None)sub_cuboid(orientation=None**kwargs)

Return a sub cuboid. ‘kwargs’ allows argument in the form: axis=slice_value.sub_cuboid_from_slices(orientation=None**kwargs)

Return a sub cuboid. ‘kwargs’ allows argument in the form: axis=slice_index.substract(cdest=None)sum(axis=None)swapaxes(a1a2)

Swap axes a1 and a2

Parameters:a1 () – identifier of the 1st axisa2 () – identifier of the 2nd axis
Returns:A new cuboid wrapping a swapped view of the numpy array


Render the array as an html table whose column headers correspond to domain values and axis names defined by col_axes, row headers defined by row_axes and inner cell axes defined by inner_axes Data within a cell can be render as text or as a plot figure (image files are produced)

Parameters: –
Returns:html code (str)

to_latex(row_axes=Nonecol_axes=Noneinner_axes=Noneinner_separator=’ | ‘header_styles=Nonehval_fmt=Noneval_fmt=’%1.2f’col_align=None)to_tree(level_axesleaf_axes)

Convert nested dictionary mapping where each key is a domain value and each leaf is an array or a scalar value if leaf_axes is empty.

Returns:{dv_axis1 : {dv_axis2 : {… : xndarray|scalar_type}
Return type:OrderedDict such as

Example: >>> from pyhrf.ndarray import xndarray >>> import numpy as np >>> c = xndarray(np.arange(4).reshape(2,2), axes_names=[‘a1’,’ia’], axes_domains={‘a1’:[‘out_dv1’, ‘out_dv2’], ‘ia’:[‘in_dv1’, ‘in_dv2’]}) >>> c.to_tree([‘a1’], [‘ia’]) OrderedDict([(‘out_dv1’, axes: [‘ia’], array([0, 1])), (‘out_dv2’, axes: [‘ia’], array([2, 3]))])unstack(outer_axesinner_axes)

Unstack the array along outer_axes and produce a xndarray of xndarrays

Parameters:outer_axes () – list of axis names defining the target unstacked xndarrayinner_axes () – list of axis names of any given sub-array of the target unstacked xndarray
Returns:xndarray object

Example: >>> from pyhrf.ndarray import xndarray >>> import numpy as np >>> c = xndarray(np.arange(4).reshape(2,2), axes_names=[‘a1’,’ia’], axes_domains={‘a1’:[‘out_dv1’, ‘out_dv2’], ‘ia’:[‘in_dv1’, ‘in_dv2’]}) >>> c.unstack([‘a1’], [‘ia’]) axes: [‘a1’], array([axes: [‘ia’], array([0, 1]), axes: [‘ia’], array([2, 3])], dtype=object)var(axis=None)static xndarray_like(cdata=None)

Return a new cuboid from data with axes, domains and value label copied from ‘c’. If ‘data’ is provided then set it as new cuboid’s data, else a zero array like is used.

TODO: testpyhrf.ndarray.xndarray_like(cdata=None)