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?)
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.
Notes
m is the result of np.where(mask) -> can be passed to speed up if already done before.
Examples
>>> 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]])
>>> 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]],
[[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.
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.
Examples
>>> 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: |
|
---|---|
Returns: | |
Return type: | xndarray object |
Examples
>>> 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]],
[[1, 2],
[3, 4]]])
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.
Examples
>>> 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
add
(c, dest=None)¶astype
(t)¶cexpand
(cmask, axis, dest=None)¶Same as expand but mask is a cuboid
TODO: + unit test
cflatten
(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.
Examples
>>> 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()
* 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: |
|
---|---|
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: |
|
---|---|
Returns: | dict of xndarray that maps a mask value to a xndarray. |
fill
(c)¶flatten
(mask, axes, new_axis)¶flatten cudoid.
TODO: +unit test
get_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_names
get_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
Examples
>>> 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 size
get_extra_info
(fmt='dict')¶get_ndims
()¶get_new_axis_name
()¶Return an axis label not already in use. Format is: dim%d
get_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)¶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.
Parameters: | xmapping (xndarray) – array whose attribute value_label matches an axis of the current array |
---|---|
Returns: | |
Return type: | a new array (xndarray) where values from the current array have been mapped according to xmapping |
Examples
>>> 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 order
set_axis_domain
(axis_id, domain)¶Set the value domain mapped to axis_id as domain
Parameters: |
|
---|---|
Returns: | None |
set_orientation
(axes)¶Set the cuboid orientation (inplace) according to input axes labels
split
(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: |
|
---|---|
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: |
|
---|---|
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)¶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: test
pyhrf.ndarray.
xndarray_like
(c, data=None)¶