scipp.Bins#
- class scipp.Bins(obj)#
Proxy for access to bin contents and operations on bins of a variable.
This class is returned from the bins property of variables and should generally not be created directly.
Binsis generic over the parent type, not the event type. That is,Variable.binsalways returnsBins[Variable]regardless of whether the event list is a variable or data array.- __init__(obj)#
Methods
__init__(obj)all()Logical AND of events in each bin ignoring NaN's.
any()Logical OR of events in each bin ignoring NaN's.
assign(data)Assign data variable to bins, if content is a DataArray.
assign_coords([coords])Return a new object with coords assigned to bin content.
assign_masks([masks])Return a new object with masks assigned to bin content.
concat([dim])Concatenate bins element-wise by concatenating bin contents along their internal bin dimension.
concatenate(other, *[, out])Concatenate bins element-wise by concatenating bin contents along their internal bin dimension.
drop_coords(coords)Return a new object with coords dropped from bin content.
drop_masks(masks)Return a new object with masks dropped from bin content.
max()Maximum of events in each bin.
mean()Arithmetic mean of events in each bin.
min()Minimum of events in each bin.
nanmax()Maximum of events in each bin ignoring NaN's.
nanmean()Arithmetic mean of events in each bin ignoring NaN's.
nanmin()Minimum of events in each bin ignoring NaN's.
nansum()Sum of events in each bin ignoring NaN's.
size()Number of events or elements in a bin.
sum()Sum of events in each bin.
Attributes
Alignment flag for coordinates of bin elements.
Constituents of binned data, as supported by
sc.bins().Coords of the bins.
Data of the bins.
Data type of the bin elements.
Masks of the bins.
Unit of the bin elements.
- __getitem__(key)#
Extract events from bins based on labels or label ranges and return a copy.
This is similar to regular label-based indexing, but considers the event-coords, i.e., the coord values of individual bin entries. Unlike normal label-based indexing this returns a copy, as a subset of events is extracted.
- Parameters:
key (
tuple[str,Variable|slice]) –A tuple of (dimension label, selection). The selection can be:
A 0-D Variable: selects events matching that exact label value
A slice with Variable start/stop: selects events in that range
- Returns:
DataArray– DataArray with events matching the selection.
Examples
Slice events by coordinate range:
>>> import scipp as sc >>> binned = sc.data.binned_x(100, 4) >>> binned.bins.size() <scipp.DataArray> Dimensions: Sizes[x:4, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.250414, ..., 0.744977, 0.992259] Data: int64 <no unit> (x) [25, 28, 18, 29]
Extract events where x is between 0.2 and 0.5 m:
>>> start = sc.scalar(0.2, unit='m') >>> stop = sc.scalar(0.5, unit='m') >>> sliced = binned.bins['x', start:stop] >>> sliced.bins.size() <scipp.DataArray> Dimensions: Sizes[] Coordinates: x float64 [m] (x [bin-edge]) [0.2, 0.5] Data: int64 <no unit> () 35
- all()#
Logical AND of events in each bin ignoring NaN’s.
- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – The AND of each of the input bins without NaN’s.
See also
scipp.allFor performing an AND of non-bin data or across bins.
Examples
Check if all events in each bin satisfy a condition:
>>> import scipp as sc >>> x = sc.array(dims=['row'], values=[0.1, 0.15, 0.2, 0.4, 0.5, 0.6, ... 0.7, 0.8, 0.9], unit='m') >>> data = sc.array(dims=['row'], values=[True, True, True, ... True, False, True, ... False, False, False]) >>> table = sc.DataArray(data, coords={'x': x}) >>> binned = table.bin(x=3) >>> binned.bins.all() <scipp.DataArray> Dimensions: Sizes[x:3, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.1, 0.366667, 0.633333, 0.9] Data: bool <no unit> (x) [True, False, False]
- any()#
Logical OR of events in each bin ignoring NaN’s.
- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – The OR of each of the input bins without NaN’s.
See also
scipp.anyFor performing an OR of non-bin data or across bins.
Examples
Check if any event in each bin satisfies a condition:
>>> import scipp as sc >>> x = sc.array(dims=['row'], values=[0.1, 0.15, 0.2, 0.4, 0.5, 0.6, ... 0.7, 0.8, 0.9], unit='m') >>> data = sc.array(dims=['row'], values=[True, True, True, ... True, False, True, ... False, False, False]) >>> table = sc.DataArray(data, coords={'x': x}) >>> binned = table.bin(x=3) >>> binned.bins.any() <scipp.DataArray> Dimensions: Sizes[x:3, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.1, 0.366667, 0.633333, 0.9] Data: bool <no unit> (x) [True, True, False]
- assign(data)#
Assign data variable to bins, if content is a DataArray.
- Parameters:
data (
Variable) – Data to assign to the bins content.- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – The input with the new data assigned.
Examples
Replace the data in bins with new values:
>>> import scipp as sc >>> var = sc.array(dims=['event'], values=[1.0, 2.0, 3.0, 4.0], unit='K') >>> table = sc.DataArray(var, coords={'x': sc.array(dims=['event'], values=[0.1, 0.3, 0.5, 0.9], unit='m')}) >>> binned = table.bin(x=2) >>> binned.bins.sum().data <scipp.Variable> (x: 2) float64 [K] [6, 4]
Assign scaled data:
>>> new_data = binned.bins.data * 10.0 >>> result = binned.bins.assign(new_data) >>> result.bins.sum().data <scipp.Variable> (x: 2) float64 [K] [60, 40]
- assign_coords(coords=None, /, **coords_kwargs)#
Return a new object with coords assigned to bin content.
- Parameters:
- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – New object with the coordinates assigned.
Examples
Add a derived coordinate to event data:
>>> import scipp as sc >>> var = sc.array(dims=['event'], values=[1.0, 2.0, 3.0, 4.0], unit='K') >>> table = sc.DataArray(var, coords={'x': sc.array(dims=['event'], values=[0.1, 0.3, 0.5, 0.9], unit='m')}) >>> binned = table.bin(x=2) >>> new_coord = binned.bins.coords['x'] * 2.0 >>> result = binned.bins.assign_coords(x_doubled=new_coord) >>> result.bins.coords <scipp.Dict> x: <scipp.Variable> (event: 4) float64 [m] [0.1, 0.3, 0.5, 0.9] x_doubled: <scipp.Variable> (event: 4) float64 [m] [0.2, 0.6, 1, 1.8]
- assign_masks(masks=None, /, **masks_kwargs)#
Return a new object with masks assigned to bin content.
- Parameters:
- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – New object with the masks assigned.
Examples
Add a mask to event data based on coordinate values:
>>> import scipp as sc >>> var = sc.array(dims=['event'], values=[1.0, 2.0, 3.0, 4.0], unit='K') >>> table = sc.DataArray(var, coords={'x': sc.array(dims=['event'], values=[0.1, 0.3, 0.5, 0.9], unit='m')}) >>> binned = table.bin(x=2) >>> mask = binned.bins.coords['x'] > sc.scalar(0.5, unit='m') >>> result = binned.bins.assign_masks(high_x=mask) >>> result.bins.masks <scipp.Dict> high_x: <scipp.Variable> (event: 4) bool <no unit> [False, False, False, True]
- concat(dim=None)#
Concatenate bins element-wise by concatenating bin contents along their internal bin dimension.
This is a reduction operation similar to
scipp.sum()but operates on binned data. Elements (bins) are concatenated along their internal dimension.- Parameters:
dim (
Union[str,Iterable[str],None], default:None) – Reduction dimension.- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – All bins along dim concatenated into a single bin.
Examples
Concatenate all bins along a dimension:
>>> import scipp as sc >>> binned = sc.data.binned_x(100, 4) >>> binned.bins.size() <scipp.DataArray> Dimensions: Sizes[x:4, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.250414, ..., 0.744977, 0.992259] Data: int64 <no unit> (x) [25, 28, 18, 29]
>>> concatenated = binned.bins.concat('x') >>> concatenated.bins.size() <scipp.DataArray> Dimensions: Sizes[] Data: int64 <no unit> () 100
This produces a scalar result with all events in a single bin.
- concatenate(other, *, out=None)#
Concatenate bins element-wise by concatenating bin contents along their internal bin dimension.
The bins to concatenate are obtained element-wise from self and other.
- Parameters:
- Returns:
- Raises:
scipp.DTypeError – If other is not binned data.
Examples
Concatenate corresponding bins from two arrays element-wise:
>>> import scipp as sc >>> table1 = sc.data.table_xyz(30) >>> table2 = sc.data.table_xyz(20) >>> x_edges = sc.linspace('x', 0.0, 1.0, 3, unit='m') >>> binned1 = table1.bin(x=x_edges) >>> binned2 = table2.bin(x=x_edges) >>> binned1.bins.size().values array([15, 15]) >>> binned2.bins.size().values array([10, 10])
Merge bins element-wise:
>>> result = binned1.bins.concatenate(binned2) >>> result.bins.size().values array([25, 25])
Each bin in the result contains events from the corresponding bins in both inputs.
- property constituents: Constituents#
Constituents of binned data, as supported by
sc.bins().Returns a dict containing: - ‘data’: The underlying event data (Variable/DataArray) - ‘begin’: Variable with bin start indices - ‘end’: Variable with bin end indices - ‘dim’: Dimension name that the binning applies to
Examples
Access the underlying structure of binned data:
>>> import scipp as sc >>> var = sc.array(dims=['event'], values=[1.0, 2.0, 3.0, 4.0], unit='K') >>> table = sc.DataArray(var, coords={'x': sc.array(dims=['event'], values=[0.1, 0.3, 0.5, 0.9], unit='m')}) >>> binned = table.bin(x=2) >>> parts = binned.bins.constituents >>> parts['dim'] 'event' >>> parts['begin'] <scipp.Variable> (x: 2) int64 <no unit> [0, 3] >>> parts['end'] <scipp.Variable> (x: 2) int64 <no unit> [3, 4] >>> parts['data'] <scipp.DataArray> Dimensions: Sizes[event:4, ] Coordinates: * x float64 [m] (event) [0.1, 0.3, 0.5, 0.9] Data: float64 [K] (event) [1, 2, 3, 4]
Reconstruct binned data from constituents:
>>> reconstructed = sc.bins(**parts) >>> sc.identical(binned.data, reconstructed) True
- property coords: Coords#
Coords of the bins.
Examples
Access event coordinates from binned data:
>>> import scipp as sc >>> table = sc.data.table_xyz(20) >>> binned = table.bin(x=3) >>> binned.bins.coords <scipp.Dict> x: <scipp.Variable> (row: 20) float64 [m] [...] y: <scipp.Variable> (row: 20) float64 [m] [...] z: <scipp.Variable> (row: 20) float64 [m] [...]
Access a specific event coordinate:
>>> 'x' in binned.bins.coords True
- property data: Variable#
Data of the bins.
Examples
Access event data from binned data:
>>> import scipp as sc >>> binned = sc.data.binned_x(50, 3) >>> binned.bins.data <scipp.Variable> (x: 3) VariableView <no unit> binned data: dim='row', content=Variable(dims=(row: 50), dtype=float64, unit=K)
Modify event data:
>>> modified = binned.copy() >>> modified.bins.data = modified.bins.data * 2.0 >>> modified.bins.sum() <scipp.DataArray> Dimensions: Sizes[x:3, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.332841, 0.66255, 0.992259] Data: float64 [K] (x) [37.8384, 25.3648, 41.7971]
- drop_coords(coords)#
Return a new object with coords dropped from bin content.
- Parameters:
coords (
Union[str,Sequence[str]]) – Name or names of coordinates to drop.- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – New object with the coordinates dropped.
Examples
Remove an event coordinate:
>>> import scipp as sc >>> var = sc.array(dims=['event'], values=[1.0, 2.0, 3.0, 4.0], unit='K') >>> table = sc.DataArray(var, coords={'x': sc.array(dims=['event'], values=[0.1, 0.3, 0.5, 0.9], unit='m')}) >>> binned = table.bin(x=2) >>> 'x' in binned.bins.coords True
>>> result = binned.bins.drop_coords('x') >>> 'x' in result.bins.coords False
- drop_masks(masks)#
Return a new object with masks dropped from bin content.
- Parameters:
masks (
Union[str,Sequence[str]]) – Name or names of masks to drop.- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – New object with the masks dropped.
Examples
Remove an event mask:
>>> import scipp as sc >>> var = sc.array(dims=['event'], values=[1.0, 2.0, 3.0, 4.0], unit='K') >>> table = sc.DataArray(var, coords={'x': sc.array(dims=['event'], values=[0.1, 0.3, 0.5, 0.9], unit='m')}) >>> table.masks['quality'] = sc.array(dims=['event'], values=[False, True, False, False]) >>> binned = table.bin(x=2) >>> binned.bins.masks <scipp.Dict> quality: <scipp.Variable> (event: 4) bool <no unit> [False, True, False, False]
>>> result = binned.bins.drop_masks('quality') >>> result.bins.masks <scipp.Dict>
- property dtype: DType#
Data type of the bin elements.
Examples
Get the data type of the bin contents:
>>> import scipp as sc >>> var = sc.array(dims=['event'], values=[1.0, 2.0, 3.0, 4.0], unit='K') >>> table = sc.DataArray(var, coords={'x': sc.array(dims=['event'], values=[0.1, 0.3, 0.5, 0.9], unit='m')}) >>> binned = table.bin(x=2) >>> binned.bins.dtype DType('float64')
Integer data:
>>> int_var = sc.array(dims=['event'], values=[1, 2, 3, 4]) >>> int_table = sc.DataArray(int_var, coords={'x': sc.array(dims=['event'], values=[0.1, 0.3, 0.5, 0.9], unit='m')}) >>> int_binned = int_table.bin(x=2) >>> int_binned.bins.dtype DType('int64')
- property masks: MetaDataMap#
Masks of the bins.
Examples
Access event masks from binned data:
>>> import scipp as sc >>> var = sc.array(dims=['event'], values=[1.0, 2.0, 3.0, 4.0], unit='K') >>> table = sc.DataArray(var, coords={'x': sc.array(dims=['event'], values=[0.1, 0.3, 0.5, 0.9], unit='m')}) >>> table.masks['quality'] = sc.array(dims=['event'], values=[False, True, False, False]) >>> binned = table.bin(x=2) >>> binned.bins.masks <scipp.Dict> quality: <scipp.Variable> (event: 4) bool <no unit> [False, True, False, False]
Check if an event mask exists:
>>> 'quality' in binned.bins.masks True
- max()#
Maximum of events in each bin.
See also
scipp.maxFor calculating the maximum of non-bin data or across bins.
Examples
Find the maximum event value within each bin:
>>> import scipp as sc >>> binned = sc.data.binned_x(100, 4) >>> binned.bins.max() <scipp.DataArray> Dimensions: Sizes[x:4, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.250414, ..., 0.744977, 0.992259] Data: float64 [K] (x) [1.09436, 1.09533, 1.09236, 1.09963]
- mean()#
Arithmetic mean of events in each bin.
See also
scipp.meanFor calculating the mean of non-bin data or across bins.
Examples
Compute the mean of events within each bin:
>>> import scipp as sc >>> binned = sc.data.binned_x(100, 4) >>> binned.bins.mean() <scipp.DataArray> Dimensions: Sizes[x:4, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.250414, ..., 0.744977, 0.992259] Data: float64 [K] (x) [1.04866, 1.05916, 1.04813, 1.04679]
- min()#
Minimum of events in each bin.
See also
scipp.minFor calculating the minimum of non-bin data or across bins.
Examples
Find the minimum event value within each bin:
>>> import scipp as sc >>> binned = sc.data.binned_x(100, 4) >>> binned.bins.min() <scipp.DataArray> Dimensions: Sizes[x:4, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.250414, ..., 0.744977, 0.992259] Data: float64 [K] (x) [1.00044, 1.00706, 1.00387, 1.00136]
- nanmax()#
Maximum of events in each bin ignoring NaN’s.
- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – The maximum of each of the input bins without NaN’s.
See also
scipp.nanmaxFor calculating the maximum of non-bin data or across bins.
Examples
With NaN values,
maxpropagates NaN whilenanmaxignores them:>>> import scipp as sc >>> import numpy as np >>> from numpy.random import default_rng >>> rng = default_rng(seed=1234) >>> x = sc.array(dims=['row'], values=rng.random(50), unit='m') >>> data = sc.array(dims=['row'], values=rng.random(50), unit='K') >>> data.values[0] = np.nan >>> table = sc.DataArray(data, coords={'x': x}) >>> binned = table.bin(x=3) >>> binned.bins.nanmax() <scipp.DataArray> Dimensions: Sizes[x:3, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.332841, 0.66255, 0.992259] Data: float64 [K] (x) [0.988635, 0.873824, 0.893008]
- nanmean()#
Arithmetic mean of events in each bin ignoring NaN’s.
- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – The mean of each of the input bins without NaN’s.
See also
scipp.nanmeanFor calculating the mean of non-bin data or across bins.
Examples
With NaN values in the data,
meanpropagates NaN whilenanmeanignores them:>>> import scipp as sc >>> import numpy as np >>> from numpy.random import default_rng >>> rng = default_rng(seed=1234) >>> x = sc.array(dims=['row'], values=rng.random(50), unit='m') >>> data = sc.array(dims=['row'], values=rng.random(50), unit='K') >>> data.values[0] = np.nan # inject NaN values >>> data.values[10] = np.nan >>> table = sc.DataArray(data, coords={'x': x}) >>> binned = table.bin(x=3)
Regular mean produces NaN where bins contain NaN values:
>>> binned.bins.mean() <scipp.DataArray> Dimensions: Sizes[x:3, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.332841, 0.66255, 0.992259] Data: float64 [K] (x) [0.598195, nan, nan]
Using nanmean ignores NaN values:
>>> binned.bins.nanmean() <scipp.DataArray> Dimensions: Sizes[x:3, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.332841, 0.66255, 0.992259] Data: float64 [K] (x) [0.598195, 0.478468, 0.38531]
- nanmin()#
Minimum of events in each bin ignoring NaN’s.
- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – The minimum of each of the input bins without NaN’s.
See also
scipp.nanminFor calculating the minimum of non-bin data or across bins.
Examples
With NaN values,
minpropagates NaN whilenanminignores them:>>> import scipp as sc >>> import numpy as np >>> from numpy.random import default_rng >>> rng = default_rng(seed=1234) >>> x = sc.array(dims=['row'], values=rng.random(50), unit='m') >>> data = sc.array(dims=['row'], values=rng.random(50), unit='K') >>> data.values[0] = np.nan >>> table = sc.DataArray(data, coords={'x': x}) >>> binned = table.bin(x=3) >>> binned.bins.nanmin() <scipp.DataArray> Dimensions: Sizes[x:3, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.332841, 0.66255, 0.992259] Data: float64 [K] (x) [0.0670407, 0.198358, 0.00597817]
- nansum()#
Sum of events in each bin ignoring NaN’s.
- Returns:
TypeVar(_O,Variable,DataArray,Dataset) – The sum of each of the input bins without NaN’s.
See also
scipp.nansumFor summing non-bin data or summing bins.
Examples
With NaN values in the data,
sumpropagates NaN whilenansumignores them:>>> import scipp as sc >>> import numpy as np >>> from numpy.random import default_rng >>> rng = default_rng(seed=1234) >>> x = sc.array(dims=['row'], values=rng.random(50), unit='m') >>> data = sc.array(dims=['row'], values=rng.random(50), unit='K') >>> data.values[0] = np.nan # inject NaN values >>> data.values[10] = np.nan >>> table = sc.DataArray(data, coords={'x': x}) >>> binned = table.bin(x=3)
Regular sum produces NaN where bins contain NaN values:
>>> binned.bins.sum() <scipp.DataArray> Dimensions: Sizes[x:3, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.332841, 0.66255, 0.992259] Data: float64 [K] (x) [10.7675, nan, nan]
Using nansum ignores NaN values:
>>> binned.bins.nansum() <scipp.DataArray> Dimensions: Sizes[x:3, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.332841, 0.66255, 0.992259] Data: float64 [K] (x) [10.7675, 5.26314, 7.32089]
- size()#
Number of events or elements in a bin.
- Returns:
Variable– The number of elements in each of the input bins.
Examples
Count the number of events in each bin:
>>> import scipp as sc >>> binned = sc.data.binned_x(100, 4) >>> sizes = binned.bins.size() >>> sizes.dims ('x',) >>> sizes.data.dtype == sc.DType.int64 True
This is useful for checking bin populations, for example to filter empty bins:
>>> mask = sc.array(dims=sizes.dims, values=sizes.values > 0) >>> non_empty = binned[mask]
- sum()#
Sum of events in each bin.
See also
scipp.sumFor summing non-bin data or summing bins.
Examples
Sum events within each bin:
>>> import scipp as sc >>> binned = sc.data.binned_x(100, 4) >>> binned.bins.sum() <scipp.DataArray> Dimensions: Sizes[x:4, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.250414, ..., 0.744977, 0.992259] Data: float64 [K] (x) [26.2165, 29.6565, 18.8663, 30.3569]
Works with multidimensional binned data:
>>> binned_2d = sc.data.binned_xy(100, 3, 2) >>> binned_2d.bins.sum() <scipp.DataArray> Dimensions: Sizes[x:3, y:2, ] Coordinates: * x float64 [m] (x [bin-edge]) [0.00313229, 0.332841, 0.66255, 0.992259] * y float64 [m] (y [bin-edge]) [0.00675377, 0.499126, 0.991499] Data: float64 [K] (x, y) [15.8201, 23.0968, ..., 17.8679, 20.8697]
- property unit: Unit | None#
Unit of the bin elements.
Examples
Get the unit of the data in the bins:
>>> import scipp as sc >>> var = sc.array(dims=['event'], values=[1.0, 2.0, 3.0, 4.0], unit='K') >>> table = sc.DataArray(var, coords={'x': sc.array(dims=['event'], values=[0.1, 0.3, 0.5, 0.9], unit='m')}) >>> binned = table.bin(x=2) >>> binned.bins.unit Unit(K)