Skip to content

Commit c2c7c6a

Browse files
Merge pull request #182 from boschresearch/161-interval-histogram
Handle also IntervalIndex and IntervalArray as histogram bins
2 parents a058e78 + c552e5e commit c2c7c6a

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

src/pylife/stress/rainflow/recorders.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,19 @@ def histogram_numpy(self, bins=10):
7373
yedges : ndarray, shape(ny+1,)
7474
The bin edges along the second dimension.
7575
"""
76+
def is_non_continous(intervals):
77+
lefts = intervals.left
78+
rights = intervals.right
79+
return np.any(lefts[1:] != rights[:-1])
80+
81+
if isinstance(bins, pd.IntervalIndex) or isinstance(bins, pd.arrays.IntervalArray):
82+
if not bins.is_non_overlapping_monotonic or is_non_continous(bins):
83+
raise ValueError("Intervals must not overlap and must be continuous and monotonic.")
84+
new_bins = np.empty(len(bins) + 1)
85+
new_bins[:-1] = bins.left
86+
new_bins[-1] = bins.right[-1]
87+
bins = new_bins
88+
7689
return np.histogram2d(self._values_from, self._values_to, bins)
7790

7891
def histogram(self, bins=10):

tests/stress/rainflow/test_recorders.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,34 @@ def test_full_rainflow_recorder_empty_histogram_5_bins():
161161
np.testing.assert_array_equal(histogram, np.zeros((5, 5)))
162162

163163

164+
def test_full_rainflow_recorder_empty_histogram_interval_index_success():
165+
fr = RFR.FullRecorder()
166+
interval_bins = pd.interval_range(start=-10.0, end=10.0, periods=5)
167+
histogram, _, _ = fr.histogram_numpy(bins=interval_bins)
168+
np.testing.assert_array_equal(histogram, np.zeros((5, 5)))
169+
170+
171+
def test_full_rainflow_recorder_empty_histogram_interval_array_success():
172+
fr = RFR.FullRecorder()
173+
interval_bins = pd.arrays.IntervalArray.from_breaks(np.linspace(-10.0, 10.0, 6))
174+
histogram, _, _ = fr.histogram_numpy(bins=interval_bins)
175+
np.testing.assert_array_equal(histogram, np.zeros((5, 5)))
176+
177+
178+
def test_full_rainflow_recorder_empty_histogram_interval_bins_overlapping():
179+
fr = RFR.FullRecorder()
180+
interval_bins = pd.IntervalIndex.from_tuples([(0.0, 2.0), (1.0, 3.0), (2.0, 4.0)])
181+
with pytest.raises(ValueError, match="Intervals must not overlap and must be continuous and monotonic."):
182+
histogram, _, _ = fr.histogram_numpy(bins=interval_bins)
183+
184+
185+
def test_full_rainflow_recorder_empty_histogram_interval_bins_non_continous():
186+
fr = RFR.FullRecorder()
187+
interval_bins = pd.IntervalIndex.from_tuples([(0.0, 1.0), (2.0, 3.0), (4.0, 5.0)])
188+
with pytest.raises(ValueError, match="Intervals must not overlap and must be continuous and monotonic."):
189+
histogram, _, _ = fr.histogram_numpy(bins=interval_bins)
190+
191+
164192
@pytest.mark.parametrize('value_from, value_to, index_from, index_to', [
165193
(23., 42., 11, 17),
166194
(46., 84., 22, 34)

0 commit comments

Comments
 (0)