The histogram module#

Provide helpers for interval-indexed histograms.

pylife.utils.histogram.combine_histogram(hist_list, method='sum')[source]#

Combine several interval-indexed histograms into one histogram.

Histograms are represented by pandas.Series objects whose index is either a pandas.IntervalIndex or a pandas.MultiIndex with interval-valued histogram dimensions. Equal bins are grouped and aggregated; bins that do not occur in an input histogram are not filled before aggregation.

Parameters:
  • hist_list (list of pandas.Series) – Histograms to combine. Each non-empty series must use compatible interval-indexed dimensions.

  • method (str or callable, optional) – Aggregation passed to pandas group-by aggregation, for example 'sum', 'min', 'max', 'mean', 'std' or a callable accepting a pandas.Series. Default is 'sum'.

Returns:

Combined histogram with the grouped interval bins as its index.

Return type:

pandas.Series

Raises:

ValueError – Raised if the index levels of the histograms do not match.

See also

pylife.utils.histogram.rebin_histogram

Rebin a histogram before or after combining histograms.

Notes

For every unique bin \(b\), the combined value is computed from all values with that exact bin:

\[h_\mathrm{combined}(b) = \operatorname{agg}\{h_k(b) \mid b \in \operatorname{index}(h_k)\}\]

No rebinning is performed before or after the aggregation. Rebin the inputs explicitly with pylife.utils.histogram.rebin_histogram() when histograms use different but geometrically overlapping bins.

Limitations: additional dimensions that are not histogram bins are only valid if their index level names and values are compatible with pandas grouping. This operation does not align values onto missing combinations of non-histogram dimensions.

Examples

>>> from pylife.utils.histogram import combine_histogram
>>> h1 = pd.Series([5., 10.], index=pd.interval_range(start=0, end=2))
>>> h2 = pd.Series([12., 3., 20.], index=pd.interval_range(start=1, periods=3))
>>> combine_histogram([h1, h2])
(0, 1]     5.0
(1, 2]    22.0
(2, 3]     3.0
(3, 4]    20.0
dtype: float64
>>> combine_histogram([h1, h2], method='min')
(0, 1]     5.0
(1, 2]    10.0
(2, 3]     3.0
(3, 4]    20.0
dtype: float64
>>> combine_histogram([h1, h2], method='max')
(0, 1]     5.0
(1, 2]    12.0
(2, 3]     3.0
(3, 4]    20.0
dtype: float64
>>> combine_histogram([h1, h2], method='mean')
(0, 1]     5.0
(1, 2]    11.0
(2, 3]     3.0
(3, 4]    20.0
dtype: float64
pylife.utils.histogram.rebin_histogram(histogram, binning, nan_default=False)[source]#

Rebin an interval-indexed histogram to a target binning.

The function redistributes bin contents by geometric overlap. It works with a one-dimensional pandas.IntervalIndex and with pandas.MultiIndex histograms that contain interval-valued dimensions.

Parameters:
  • histogram (pandas.Series) – Histogram data to rebin. The index must be a pandas.IntervalIndex or a pandas.MultiIndex that contains interval-valued histogram dimensions.

  • binning (pandas.IntervalIndex or pandas.MultiIndex or int) – Target binning. If an integer is given, equally spaced bins spanning the original histogram range are created for each rebinned interval dimension.

  • nan_default (bool, optional) – Fill unoccupied target bins with numpy.nan instead of 0.0. Default is False.

Returns:

Rebinned histogram with the target interval bins as its index.

Return type:

pandas.Series

Raises:
  • TypeError – Raised if histogram does not use an interval-indexed histogram dimension or if binning is not an interval index when explicit bins are supplied.

  • ValueError – Raised if the target binning is not monotonic increasing, overlaps, or has gaps.

Warns:

RuntimeWarning – Raised if the target binning does not cover the full histogram range and values outside the target range are discarded.

See also

pylife.utils.histogram.combine_histogram

Combine histograms that already share compatible bins.

Notes

Each source bin value is distributed proportionally to its overlap with a target bin. For source bins \(s_i\), target bins \(t_j\), source values \(h_i\), and interval length \(|s_i|\), the rebinned value is

\[h'_j = \sum_i h_i \frac{|s_i \cap t_j|}{|s_i|}\]

This preserves the total sum when the target bins cover the complete source range and have no gaps.

Limitations: additional non-interval index levels are preserved and the operation is applied independently for their combinations. The function does not interpolate within those non-histogram dimensions.

Examples

>>> from pylife.utils.histogram import rebin_histogram
>>> h = pd.Series([10.0, 20.0, 30.0, 40.0], index=pd.interval_range(0.0, 4.0, 4))
>>> h
(0.0, 1.0]    10.0
(1.0, 2.0]    20.0
(2.0, 3.0]    30.0
(3.0, 4.0]    40.0
dtype: float64

Rebin to a finer binning:

>>> target_binning = pd.interval_range(0.0, 4.0, 8)
>>> rebin_histogram(h, target_binning)
(0.0, 0.5]     5.0
(0.5, 1.0]     5.0
(1.0, 1.5]    10.0
(1.5, 2.0]    10.0
(2.0, 2.5]    15.0
(2.5, 3.0]    15.0
(3.0, 3.5]    20.0
(3.5, 4.0]    20.0
dtype: float64

Rebin to a coarser binning:

>>> target_binning = pd.interval_range(0.0, 4.0, 2)
>>> rebin_histogram(h, target_binning)
(0.0, 2.0]    30.0
(2.0, 4.0]    70.0
dtype: float64

Define the target bin just by an int:

>>> rebin_histogram(h, 8)
(0.0, 0.5]     5.0
(0.5, 1.0]     5.0
(1.0, 1.5]    10.0
(1.5, 2.0]    10.0
(2.0, 2.5]    15.0
(2.5, 3.0]    15.0
(3.0, 3.5]    20.0
(3.5, 4.0]    20.0
dtype: float64