def tops_from_loglike(a, offset=<NUM_LIT:0>, null=None):
a = np.copy(a)<EOL>try:<EOL><INDENT>contains_nans = np.isnan(a).any()<EOL><DEDENT>except:<EOL><INDENT>contains_nans = False<EOL><DEDENT>if contains_nans:<EOL><INDENT>_null = null or -<NUM_LIT:1><EOL>while _null in a:<EOL><INDENT>_null -= <NUM_LIT:1><EOL><DEDENT>try:<EOL><INDENT>a[np.isnan(a)] = _null<EOL>transformed = True<EOL><DEDENT>except:<EOL><INDENT>transformed = False<EOL><DEDENT><DEDENT>edges = a[<NUM_LIT:1>:] == a[:-<NUM_LIT:1>]<EOL>edges = np.append(True, edges)<EOL>tops = np.where(~edges)[<NUM_LIT:0>]<EOL>tops = np.append(<NUM_LIT:0>, tops)<EOL>values = a[tops + offset]<EOL>if contains_nans and transformed:<EOL><INDENT>values[values == _null] = np.nan<EOL><DEDENT>return tops, values<EOL>
Take a log-like stream of numbers or strings, and return two arrays:
one of the tops (changes), and one of the values from the stream.

Args:
    loglike (array-like): The input stream of loglike data.
    offset (int): Offset (down) from top at which to get lithology,
        to be sure of getting 'clean' pixels.

Returns:
    ndarray: Two arrays, tops and values.