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.Exception
pyhrf.ndarray.
expand_array_in_mask
(flat_data, mask, flat_axis=0, dest=None, m=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
(arrays, mask, axis, fill_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:

- 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
pyhrf.ndarray.
split_and_save
(cub, axes, fn, meta_data=None, set_MRI_orientation=False, output_dir=None, format_dvalues=False)pyhrf.ndarray.
stack_cuboids
(c_list, axis, domain=None, axis_pos=’first’)
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'], dtype='|S2') 'x': arange(0,3,1) 'y': arange(0,2,1)
TODO: enable broadcasting (?)pyhrf.ndarray.
tree_to_xndarray
(tree, level_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
(narray, axes_names=None, axes_domains=None, value_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
(c, dest=None)astype
(t)cexpand
(cmask, axis, dest=None)
Same as expand but mask is a cuboid
TODO: + unit testcflatten
(cmask, new_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
(c, dest=None)expand
(mask, axis, target_axes=None, target_domains=None, dest=None, do_checks=True, m=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'], dtype='|S5') 'x': arange(0,3,1) 'y': arange(0,3,1) 'z': arange(0,3,1)
explode
(cmask, new_axis=’position’)
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_a
(mask, axes, new_axis)
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. |
fill
(c)flatten
(mask, axes, new_axis)
flatten cudoid.
TODO: +unit testget_axes_domains
()

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
(axis, value)
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. ]]])
max
(axis=None)mean
(axis=None)min
(axis=None)multiply
(c, dest=None)ptp
(axis=None)reorient
(orientation)
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
(n, new_axis, domain=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.0, v_max=1.0, axis=None)roll
(axis, pos=-1)
Roll xndarray by making ‘axis’ the last axis. ‘pos’ is either 0 or -1 (first or last, respectively) TODO: handle all pos.save
(file_name, meta_data=None, set_MRI_orientation=False)
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_id, domain)
Set the value domain mapped to axis_id as domain
Parameters: | axis_id (–) – label of the axisdomain (–) – value domain |
---|---|
Returns: | None |
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
(c, dest=None)sum
(axis=None)swapaxes
(a1, a2)
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 |
to_html_table
(row_axes, col_axes, inner_axes, cell_format=’txt’, plot_dir=None, rel_plot_dir=None, plot_fig_prefix=’xarray_’, plot_style=’image’, plot_args=None, tooltip=False, border=None)
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=None, col_axes=None, inner_axes=None, inner_separator=’ | ‘, header_styles=None, hval_fmt=None, val_fmt=’%1.2f’, col_align=None)to_tree
(level_axes, leaf_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_axes, inner_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
(c, data=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 c.data is used.
TODO: testpyhrf.ndarray.
xndarray_like
(c, data=None)