pyLife core#

class pylife.PylifeSignal(pandas_obj)[source]#

Base class for signal accessor classes.

A signal accessor wraps a pandas.Series or pandas.DataFrame and gives it domain specific methods while leaving the data itself untouched. Derived classes register themselves with pandas.api.extensions.register_dataframe_accessor() or pandas.api.extensions.register_series_accessor(), which makes them available as an attribute of any pandas object, e.g. df.woehler.basquin_cycles(...).

Parameters:

pandas_obj (pandas.DataFrame or pandas.Series) – The object the accessor is instantiated with.

Raises:

AttributeError – If pandas_obj does not fulfill the signal contract of the derived class.

See also

fail_if_key_missing

Assert mandatory keys inside _validate().

get_missing_keys

Query mandatory keys inside _validate().

register_method

Add a method to a signal class from outside.

Notes

Derived classes need to implement the method _validate(self) which checks self._obj and raises an exception (e.g. AttributeError or ValueError) if it is not a valid object for the kind of signal. The methods fail_if_key_missing() and get_missing_keys() are meant to be used for that.

For a derived class you can register methods without modifying the class’ code itself. This can be useful if you want to make signal accessor classes extendable.

fail_if_key_missing(keys_to_check, msg=None)[source]#

Raise an exception if any key is missing in the signal.

Parameters:
  • keys_to_check (list of str) – The keys that need to be available in the signal.

  • msg (str, optional) – A printf style format string for the error message taking two %s arguments: the expected keys and the missing keys. By default a message naming the signal class is generated.

Raises:

AttributeError – If the underlying object is neither a pandas.DataFrame nor a pandas.Series, or if any of keys_to_check is not provided by the signal.

See also

get_missing_keys

Return the missing keys instead of raising.

Notes

This is the canonical way to assert a signal contract in the _validate() implementation of a derived class.

classmethod from_parameters(**kwargs)[source]#

Make a signal instance from a parameter set.

This is a convenience function to instantiate a signal from individual parameters rather than from a pandas object.

Parameters:

**kwargs (scalar or array_like) – The signal keys and their values. If more than one value is given and the values are iterable, a pandas.DataFrame backed signal is created, otherwise a pandas.Series backed one.

Returns:

An instance of the signal class the method is called on.

Return type:

PylifeSignal

Examples

For a signal class like

@pd.api.extensions.register_dataframe_accessor('foo_signal')
class FooSignal(PylifeSignal):
    pass

the following two expressions are equivalent

pd.Series({'foo': 1.0, 'bar': 2.0}).foo_signal
FooSignal.from_parameters(foo=1.0, bar=2.0)
get_missing_keys(keys_to_check)[source]#

Get a list of keys that are missing in the signal.

Parameters:

keys_to_check (list of str) – The keys that need to be available in the signal.

Returns:

The keys of keys_to_check that the signal does not provide, in the order in which they were given. An empty list means that the signal is complete.

Return type:

list of str

Raises:

AttributeError – If the underlying object is neither a pandas.DataFrame nor a pandas.Series.

See also

fail_if_key_missing

Raise instead of returning the missing keys.

Notes

This method is meant to be used in the _validate() implementation of a derived class when a missing key is not necessarily an error, e.g. when a default value can be derived.

keys()[source]#

Get the keys the signal provides.

Returns:

The keys of the underlying pandas object.

Return type:

pandas.Index

Raises:

AttributeError – If the underlying object is neither a pandas.DataFrame nor a pandas.Series.

Notes

For a pandas.DataFrame backed signal the columns are returned, for a pandas.Series backed one the index.

to_pandas()[source]#

Expose the pandas object of the signal.

Returns:

The pandas object representing the signal.

Return type:

pandas.DataFrame or pandas.Series

Notes

The default implementation just returns the object given when instantiating the signal class. Derived classes may return a modified or augmented object, if they store some extra information.

By default the object is not copied. So make a copy yourself, if you intend to modify it.

class pylife.Broadcaster(pandas_obj)[source]#

Align a pandas object with an operand of a different index.

The purpose of the Broadcaster is to take two numerical objects and return two objects of the same numerical data with an aligned index. That means that mathematical operations using the two objects as operands can be implemented using numpy’s broadcasting functionality.

In most cases the Broadcaster class is not used directly. Its functionality is inherited by PylifeSignal, from which all pyLife signal accessors are derived.

Parameters:

pandas_obj (pandas.Series or pandas.DataFrame) – The object to broadcast operands to.

See also

broadcast

Align an operand with the object of self.

pylife.PylifeSignal

The signal base class using the Broadcaster.

Notes

The broadcasting is done in the following ways:

object                 parameter              returned object         returned parameter

Series                 Scalar                 Series                  Scalar
|------|-----|                                |------|-----|
| idx  |     |                                | idx  |     |
|------|-----|         5.0               ->   |------|-----|          5.0
| foo  | 1.0 |                                | foo  | 1.0 |
| bar  | 2.0 |                                | bar  | 2.0 |
|------|-----|                                |------|-----|

DataFrame              Scalar                 DataFrame               Series
|------|-----|-----|                          |------|-----|-----|    |------|-----|
| idx  | foo | bar |                          | idx  | foo | bar |    | idx  |     |
|------|-----|-----|                          |------|-----|-----|    |------|-----|
| 0    | 1.0 | 2.0 |   5.0               ->   | 0    | 1.0 | 2.0 |    | 0    | 5.0 |
| 1    | 1.0 | 2.0 |                          | 1    | 1.0 | 2.0 |    | 1    | 5.0 |
| ...  | ... | ... |                          | ...  | ... | ... |    | ...  | ... |
|------|-----|-----|                          |------|-----|-----|    |------|-----|

Series                 Series/DataFrame       DataFrame               Series/DataFrame
|------|-----|         |------|-----|         |------|-----|-----|    |------|-----|
| None |     |         | idx  |     |         | idx  | foo | bar |    | idx  |     |
|------|-----|         |------|-----|    ->   |------|-----|-----|    |------|-----|
| foo  | 1.0 |         | 0    | 5.0 |         | 0    | 1.0 | 2.0 |    | 0    | 5.0 |
| bar  | 2.0 |         | 1    | 6.0 |         | 1    | 1.0 | 2.0 |    | 1    | 6.0 |
|------|-----|         | ...  | ... |         | ...  | ... | ... |    | ...  | ... |
                       |------|-----|         |------|-----|-----|    |------|-----|

Series/DataFrame       Series/DataFrame       Series/DataFrame        Series/DataFrame
|------|-----|         |------|-----|         |------|-----|          |------|-----|
| xidx |     |         | xidx |     |         | xidx |     |          | xidx |     |
|------|-----|         |------|-----|    ->   |------|-----|          |------|-----|
| foo  | 1.0 |         | tau  | 5.0 |         | foo  | 1.0 |          | foo  | nan |
| bar  | 2.0 |         | bar  | 6.0 |         | bar  | 2.0 |          | bar  | 6.0 |
|------|-----|         |------|-----|         | tau  | nan |          | tau  | 5.0 |
                                              |------|-----|          |------|-----|

Series/DataFrame       Series/DataFrame       Series/DataFrame        Series/DataFrame
|------|-----|         |------|-----|         |------|------|-----|   |------|------|-----|
| xidx |     |         | yidx |     |         | xidx | yidx |     |   | xidx | yidx |     |
|------|-----|         |------|-----|   ->    |------|------|-----|   |------|------|-----|
| foo  | 1.0 |         | tau  | 5.0 |         | foo  | tau  | 1.0 |   | foo  | tau  | 5.0 |
| bar  | 2.0 |         | chi  | 6.0 |         |      | chi  | 1.0 |   |      | chi  | 6.0 |
|------|-----|         |------|-----|         | bar  | tau  | 2.0 |   | bar  | tau  | 5.0 |
                                              |      | chi  | 2.0 |   |      | chi  | 6.0 |
                                              |------|------|-----|   |------|------|-----|
broadcast(parameter, droplevel=None)[source]#

Broadcast the parameter to the object of self.

Parameters:
  • parameter (scalar, numpy.ndarray, pandas.Series or pandas.DataFrame) – The operand to align with the object of self.

  • droplevel (list of str, optional) – Names of index levels that are dropped from the returned parameter before it is returned. Use it when a parameter must not be resolved along those levels, e.g. when a material parameter is constant over all load steps. Default is None, which keeps all levels.

Returns:

  • parameter (scalar, pandas.Series or pandas.DataFrame) – The broadcast operand, index aligned with obj.

  • obj (pandas.Series or pandas.DataFrame) – The broadcast object of self, index aligned with parameter.

Examples

The behavior of the Broadcaster is best illustrated by examples:

  • Broadcasting pandas.Series to a scalar results in a scalar and a pandas.Series.

    obj = pd.Series([1.0, 2.0], index=pd.Index(['foo', 'bar'], name='idx'))
    obj
    
    idx
    foo    1.0
    bar    2.0
    dtype: float64
    
    parameter, obj = Broadcaster(obj).broadcast(5.0)
    
    parameter
    
    array(5.)
    
    obj
    
    idx
    foo    1.0
    bar    2.0
    dtype: float64
    
  • Broadcasting pandas.DataFrame to a scalar results in a pandas.DataFrame and a pandas.Series.

    obj = pd.DataFrame({
        'foo': [1.0, 2.0],
        'bar': [3.0, 4.0]
    }, index=pd.Index([1, 2], name='idx'))
    obj
    
    foo bar
    idx
    1 1.0 3.0
    2 2.0 4.0
    parameter, obj = Broadcaster(obj).broadcast(5.0)
    
    parameter
    
    idx
    1    5.0
    2    5.0
    dtype: float64
    
    obj
    
    foo bar
    idx
    1 1.0 3.0
    2 2.0 4.0
  • Broadcasting pandas.DataFrame to a a pandas.Series results in a pandas.DataFrame and a pandas.Series, if and only if the index name of the object is None.

    obj = pd.Series([1.0, 2.0], index=pd.Index(['tau', 'chi']))
    obj
    
    tau    1.0
    chi    2.0
    dtype: float64
    
    parameter = pd.Series([3.0, 4.0], index=pd.Index(['foo', 'bar'], name='idx'))
    parameter
    
    idx
    foo    3.0
    bar    4.0
    dtype: float64
    
    parameter, obj = Broadcaster(obj).broadcast(parameter)
    
    parameter
    
    idx
    foo    3.0
    bar    4.0
    dtype: float64
    
    obj
    
    tau chi
    idx
    foo 1.0 2.0
    bar 1.0 2.0
class pylife.DataValidator[source]#

Check pandas objects for the keys a pyLife signal requires.

The validator works on both pandas.Series and pandas.DataFrame objects and hides the difference between the two: for a DataFrame the keys are the columns, for a Series they are the index entries.

Usually you do not instantiate a DataValidator yourself. Signal accessors derived from PylifeSignal expose the same checks as fail_if_key_missing() and get_missing_keys().

See also

pylife.PylifeSignal

Signal base class using these checks in _validate().

Examples

>>> import pandas as pd
>>> from pylife import DataValidator
>>> DataValidator().get_missing_keys(pd.Series({'sigma_a': 100.0}),
...                                  ['sigma_a', 'sigma_m'])
['sigma_m']
fail_if_key_missing(signal, keys_to_check, msg=None)[source]#

Raise an exception if any key is missing in a signal object.

Parameters:
  • signal (pandas.DataFrame or pandas.Series) – The object to be checked.

  • keys_to_check (list of str) – The keys that need to be available in signal.

  • msg (str, optional) – A printf style format string for the error message taking two %s arguments: the expected keys and the missing keys. By default a message naming the calling signal class is generated.

Raises:

AttributeError – If signal is neither a pandas.DataFrame nor a pandas.Series, or if any of keys_to_check is not found in the keys of signal.

See also

get_missing_keys

Return the missing keys instead of raising.

Notes

If signal is a pandas.DataFrame, all keys of keys_to_check need to be found in signal.columns. If signal is a pandas.Series, they need to be found in signal.index.

get_missing_keys(signal, keys_to_check)[source]#

Get a list of keys that are missing in a signal object.

Parameters:
Returns:

The keys of keys_to_check that are not present in signal, in the order in which they were given. An empty list means that signal is complete.

Return type:

list of str

Raises:

AttributeError – If signal is neither a pandas.DataFrame nor a pandas.Series.

See also

fail_if_key_missing

Raise instead of returning the missing keys.

Notes

If signal is a pandas.DataFrame, the keys are looked up in signal.columns, if it is a pandas.Series, in signal.index.

keys(signal)[source]#

Get the keys a signal object provides.

Parameters:

signal (pandas.DataFrame or pandas.Series) – The object to be checked.

Returns:

The keys of signal.

Return type:

pandas.Index

Raises:

AttributeError – If signal is neither a pandas.DataFrame nor a pandas.Series.

Notes

If signal is a pandas.DataFrame, signal.columns is returned. If signal is a pandas.Series, signal.index is returned.

Examples

>>> import pandas as pd
>>> from pylife import DataValidator
>>> list(DataValidator().keys(pd.Series({'sigma_a': 100.0})))
['sigma_a']