The module for load collectives#

Represent load collectives as explicit loops or binned histograms.

Use pylife.stress.collective.LoadCollective when every rainflow loop shall remain available as an individual row. Use pylife.stress.collective.LoadHistogram when cycles are already binned in load range and mean load classes or in from and to classes.

Both accessors expose the same engineering quantities: load amplitude, load range, mean load, upper and lower turning load, stress ratio R, and number of cycles. The tutorial at docs/tutorials/load_collective.rst explains the trade-off between retaining every loop and aggregating cycles into histogram classes.

class pylife.stress.collective.LoadCollective(pandas_obj)[source]#

Represent explicit rainflow loops as a load collective.

The accessor is registered as DataFrame.load_collective and represents one hysteresis loop per row. The input frame must contain either:

  • from and to: Load values at the two turning points of the loop, usually in MPa.

  • range and mean: Load range (peak-to-peak) and mean load, usually in MPa. The accessor converts these columns internally to lower from and upper to values.

An optional cycles column gives the number of cycles represented by each row. If it is absent, every row represents one cycle. Derived properties expose amplitude = abs(from - to) / 2, meanstress = (from + to) / 2, upper = max(from, to), lower = min(from, to), R = lower / upper with missing values filled by 0.0, and cycles.

Parameters:

pandas_obj (pandas.DataFrame) – DataFrame containing explicit load loops as described above.

Notes

The amplitude, range, and mean load are related by

\[ \begin{align}\begin{aligned}S_\mathrm{a} = \frac{|S_\mathrm{from} - S_\mathrm{to}|}{2}\\S_\mathrm{range} = 2 S_\mathrm{a}\\S_\mathrm{mean} = \frac{S_\mathrm{from} + S_\mathrm{to}}{2}\end{aligned}\end{align} \]
property R#

Calculate the stress ratio R for each loop.

Returns:

Stress ratio R = lower / upper, dimensionless. Undefined ratios are returned as 0.0.

Return type:

pandas.Series

property amplitude#

Calculate the load amplitude for each loop.

Returns:

Load amplitude in the same unit as from and to, typically MPa.

Return type:

pandas.Series

property columns: list[str]#

Return the column names that define the load axes.

Returns:

Either ["from", "to"] or ["range", "mean"] as supplied by the input signal.

Return type:

list of str

property cycles#

Return the number of cycles represented by each loop.

Returns:

Number of cycles. If the source data has no cycles column, every loop is returned as one cycle.

Return type:

pandas.Series

histogram(bins, axis=None)[source]#

Calculate a range-mean histogram of the collective.

Parameters:
  • bins (int, array_like or pandas.IntervalIndex) – Bin specification for both load range (peak-to-peak) and mean load, in the same unit as the source load values.

  • axis (str, optional) – Index level that identifies individual loops within each group. If omitted, calculate one histogram over the whole collective. Default is None.

Returns:

Histogram accessor with range and mean interval index levels and cycle counts as values.

Return type:

LoadHistogram

See also

range_histogram

Calculate a one-dimensional load-range histogram.

Notes

The range axis stores load range (peak-to-peak), not load amplitude. The mean axis stores mean load.

Examples

Calculate a range histogram of a simple load collective

>>> df = pd.DataFrame(
...     {'range': [1.0, 2.0, 1.0, 2.0, 1.0], 'mean': [0.5, 1.5, 1.0, 1.5, 0.5]},
...     columns=['range', 'mean'],
... )
>>> df.load_collective.histogram([0, 1, 2, 3]).to_pandas()
range   mean
(0, 1]  (0, 1]    0.0
        (1, 2]    0.0
        (2, 3]    0.0
(1, 2]  (0, 1]    2.0
        (1, 2]    1.0
        (2, 3]    0.0
(2, 3]  (0, 1]    0.0
        (1, 2]    2.0
        (2, 3]    0.0
Name: cycles, dtype: float64

Calculate a range histogram of a load collective collection for multiple nodes. The axis along which to aggregate the histogram is given as cycle_number.

>>> element_idx = pd.Index([10, 20], name='element_id')
>>> cycle_idx = pd.Index([0, 1, 2], name='cycle_number')
>>> index = pd.MultiIndex.from_product((element_idx, cycle_idx))
>>> df = pd.DataFrame({
...     'range': [1., 2., 2., 0., 1., 2.],
...     'mean': [0.5, 1.0, 1.0, 0.0, 1.0, 1.5]
... }, columns=['range', 'mean'], index=index)
>>> h = df.load_collective.histogram([0, 1, 2, 3], 'cycle_number')
>>> h.to_pandas()
element_id  range   mean
10          (0, 1]  (0, 1]    0.0
                    (1, 2]    0.0
                    (2, 3]    0.0
            (1, 2]  (0, 1]    1.0
                    (1, 2]    0.0
                    (2, 3]    0.0
            (2, 3]  (0, 1]    0.0
                    (1, 2]    2.0
                    (2, 3]    0.0
20          (0, 1]  (0, 1]    1.0
                    (1, 2]    0.0
                    (2, 3]    0.0
            (1, 2]  (0, 1]    0.0
                    (1, 2]    1.0
                    (2, 3]    0.0
            (2, 3]  (0, 1]    0.0
                    (1, 2]    1.0
                    (2, 3]    0.0
Name: cycles, dtype: float64
property lower#

Calculate the lower turning load for each loop.

Returns:

Lower load in the same unit as from and to, typically MPa.

Return type:

pandas.Series

property meanstress#

Calculate the mean load for each loop.

Returns:

Mean load in the same unit as from and to, typically MPa.

Return type:

pandas.Series

range_histogram(bins, axis=None)[source]#

Calculate a load-range histogram of the collective.

Parameters:
  • bins (int, array_like or pandas.IntervalIndex) – Bin specification for the load range (peak-to-peak), in the same unit as the source load values.

  • axis (str, optional) – Index level that identifies individual loops within each group. If omitted, calculate one histogram over the whole collective. Default is None.

Returns:

Histogram accessor with a range interval index and cycle counts as values.

Return type:

LoadHistogram

See also

histogram

Calculate a two-dimensional range-mean histogram.

Notes

The resulting histogram does not contain mean-load information and does not apply a mean-stress transformation. The range axis uses load range (peak-to-peak), not load amplitude.

Examples

Calculate a range histogram of a simple load collective

>>> df = pd.DataFrame(
...     {'range': [1.0, 2.0, 1.0, 2.0, 1.0], 'mean': [0, 0, 0, 0, 0]},
...     columns=['range', 'mean'],
... )
>>> df.load_collective.range_histogram([0, 1, 2, 3]).to_pandas()
range
(0, 1]    0
(1, 2]    3
(2, 3]    2
Name: cycles, dtype: int64

Calculate a range histogram of a load collective collection for multiple nodes. The axis along which to aggregate the histogram is given as cycle_number.

>>> element_idx = pd.Index([10, 20, 30], name='element_id')
>>> cycle_idx = pd.Index([0, 1, 2], name='cycle_number')
>>> index = pd.MultiIndex.from_product((element_idx, cycle_idx))
>>> df = pd.DataFrame({
...     'range': [1., 2., 2., 0., 1., 2., 1., 1., 2.],
...     'mean': [0, 0, 0, 0, 0, 0, 0, 0, 0]
... }, columns=['range', 'mean'], index=index)
>>> h = df.load_collective.range_histogram([0, 1, 2, 3], 'cycle_number')
>>> h.to_pandas()
element_id  range
10          (0, 1]    0
            (1, 2]    1
            (2, 3]    2
20          (0, 1]    1
            (1, 2]    1
            (2, 3]    1
30          (0, 1]    0
            (1, 2]    2
            (2, 3]    1
Name: cycles, dtype: int64
scale(factors)[source]#

Scale all load values of the collective.

Parameters:

factors (float or pandas.Series) – Factor or row-wise factors used to multiply the from and to load values.

Returns:

Scaled collective accessor.

Return type:

LoadCollective

shift(diffs)[source]#

Shift all load values of the collective.

Parameters:

diffs (float or pandas.Series) – Difference or row-wise differences added to the from and to load values.

Returns:

Shifted collective accessor.

Return type:

LoadCollective

property upper#

Calculate the upper turning load for each loop.

Returns:

Upper load in the same unit as from and to, typically MPa.

Return type:

pandas.Series

class pylife.stress.collective.LoadHistogram(pandas_obj)[source]#

Represent binned rainflow cycles as a load histogram.

The accessor is registered as Series.load_collective for compatibility with explicit collectives. The series values are the number of cycles in each bin. The series index must be a pandas.MultiIndex that contains one of the following interval-index structures:

  • range and optionally mean: Load range (peak-to-peak) classes and mean-load classes, usually in MPa.

  • from and to: Classes of the two loop turning loads, usually in MPa.

Every load axis listed above must be a pandas.IntervalIndex. Derived properties use the interval midpoint by default. They expose amplitude = range / 2 for range/mean histograms or amplitude = abs(from - to) / 2 for from/to histograms, meanstress, upper, lower, R = lower / upper with missing values filled by 0.0, and cycles.

Parameters:

pandas_obj (pandas.Series) – Series containing cycle counts indexed by load intervals.

property R#

Calculate the stress ratio R for each histogram bin.

Returns:

Stress ratio R = lower / upper, dimensionless. Undefined ratios are returned as 0.0.

Return type:

pandas.Series

property amplitude#

Calculate the load amplitude for each histogram bin.

Returns:

Load amplitude in the same unit as the histogram load axes, typically MPa.

Return type:

pandas.Series

property amplitude_histogram#

Return the cycle histogram indexed by load-amplitude intervals.

Returns:

Number of cycles indexed by load-amplitude intervals in the same unit as the histogram load axes, typically MPa.

Return type:

pandas.Series

cumulated_range()[source]#

Cumulate cycle counts along the load-range classes.

Returns:

Cumulative number of cycles within each range interval.

Return type:

pandas.Series

property cycles#

Return the number of cycles in each histogram bin.

Returns:

Number of cycles represented by each histogram bin.

Return type:

pandas.Series

property index_levels: list[str]#

Return the index levels that define the load axes.

Returns:

Either ["range", "mean"] or ["from", "to"].

Return type:

list of str

property lower#

Calculate the lower turning load for each histogram bin.

Returns:

Lower load in the same unit as the histogram load axes, typically MPa.

Return type:

pandas.Series

property meanstress#

Calculate the mean load for each histogram bin.

Returns:

Mean load in the same unit as the histogram load axes, typically MPa.

Return type:

pandas.Series

scale(factors)[source]#

Scale all load-axis intervals of the histogram.

Parameters:

factors (float or pandas.Series) – Factor or row-wise factors used to multiply load interval boundaries. The range axis is not scaled when shifting but is scaled here.

Returns:

Scaled histogram accessor.

Return type:

LoadHistogram

shift(diffs)[source]#

Shift all load-axis intervals of the histogram.

Parameters:

diffs (float or pandas.Series) – Difference or row-wise differences added to load interval boundaries. The range axis is not shifted because a constant offset changes mean load but not load range.

Returns:

Shifted histogram accessor.

Return type:

LoadHistogram

property upper#

Calculate the upper turning load for each histogram bin.

Returns:

Upper load in the same unit as the histogram load axes, typically MPa.

Return type:

pandas.Series

use_class_left()[source]#

Use the left interval boundary for derived load values.

Returns:

The same histogram accessor, configured to use left interval boundaries.

Return type:

LoadHistogram

use_class_right()[source]#

Use the right interval boundary for derived load values.

Returns:

The same histogram accessor, configured to use right interval boundaries.

Return type:

LoadHistogram