The internals of staircase#
A step function can be represented in a number of ways. There are two formats which staircase uses internally and it may switch between them, or use both at once. Both of these formats share a couple of common components. The first of these is a property Stairs.initial_value which indicates the value of the step function at “negative infinity”. It’s value is either numerical of numpy.nan. The second shared component is a pandas index of sorted, unique, values which indicate where the step function changes value. Each staircase.Stairs
instance has a “private” attribute ._data which is either a pandas.DataFrame
or is None. If ._data is None then the step function does not change value at any point. If .data is not None, then it is indexed by the domain values where the step function changes.
This dataframe will contain at least one column, named “delta” or “value” and may contain both of these. The delta describe the difference in step function value at each of the points in the index, while value describe the value of the step function as it approaches each point in the index from the right.
To help convey the idea we define a function called internals which prints the value of Stairs.initial_value and Stairs._data, and use it conjunction with plotting some simple examples.
In [1]: import staircase as sc
In [2]: import pandas as pd
In [3]: import matplotlib.pyplot as plt
In [4]: def internals(stairs):
...: stairs._get_values()
...: stairs._get_deltas()
...: print()
...: print(f"initial_value = {stairs.initial_value}")
...: print()
...: print(stairs._data)
...: _, ax= plt.subplots()
...: ax.set_xlim(-1,2)
...: ax.set_ylim(-1,2)
...: stairs.plot(ax, arrows="True")
...:
In [5]: internals(sc.Stairs(initial_value = -0.5, start=0, end=1, value=1.5))
initial_value = -0.5
delta value
0 1.5 1.0
1 -1.5 -0.5
In [6]: internals(sc.Stairs(start=0.5))
initial_value = 0
delta value
0.5 1.0 1.0
In [7]: internals(sc.Stairs(end=0.5))
initial_value = 1
delta value
0.5 -1 0
In [8]: internals(sc.Stairs(initial_value=1).clip(0,1))
initial_value = nan
value delta
0 1.0 1.0
1 NaN NaN
In [9]: internals(sc.Stairs(initial_value=1).clip(None,1))
initial_value = 1
value delta
1 NaN NaN
In [10]: internals(sc.Stairs(initial_value=1).mask((0,1)))
initial_value = 1
value delta
0 NaN NaN
1 1.0 0.0
In [11]: internals(sc.Stairs(initial_value=-0.5, start=-0.5, end=1.5).mask((0,1)))
initial_value = -0.5
value delta
-0.5 0.5 1.0
0.0 NaN NaN
1.0 0.5 0.0
1.5 -0.5 -1.0
The pandas.Series
which correspond to the delta and value columns are best obtained with the private methods Stairs._get_deltas and Stairs._get_values, which will create the objects if they don’t exist.
The staircase.Stairs
class is defined in staircase/core/stairs.py but many of its methods are defined elsewhere in the package, and then added to class dynamically. This is purely done to organise and separate the code into related functionality.