def distance_factory( x: np.ndarray = None, y: np.ndarray = None, metric: Union[str, Callable[[np.ndarray, np.ndarray, dict], Callable[[np.ndarray, np.ndarray], float]], Callable[[np.ndarray, np.ndarray], float], NumbaDistance, ] = "euclidean", **kwargs: Any, ) -> DistanceCallable: """Create a no_python distance callable. Parameters ---------- x: np.ndarray (1d or 2d array), defaults = None First time series. y: np.ndarray (1d or 2d array), defaults = None Second time series. metric: str or Callable, defaults = 'euclidean' The distance metric to use. If a string is given, the value must be one of the following strings: 'euclidean', 'squared', 'dtw', 'ddtw', 'wdtw', 'wddtw', 'lcss', 'edr', 'erp' If callable then it has to be a distance factory or numba distance callable. If you want to pass custom kwargs to the distance at runtime, use a distance factory as it constructs the distance using the kwargs before distance computation. A distance callable takes the form (must be no_python compiled): Callable[[np.ndarray, np.ndarray], float] A distance factory takes the form (must return a no_python callable): Callable[[np.ndarray, np.ndarray, bool, dict], Callable[[np.ndarray, np.ndarray], float]]. kwargs: Any Arguments for metric. Refer to each metrics documentation for a list of possible arguments. Returns ------- Callable[[np.ndarray, np.ndarray], float]] No_python compiled distance callable. Raises ------ ValueError If the value of x or y provided is not a numpy array. If the value of x or y has more than 2 dimensions. If a metric string provided, and is not a defined valid string. If a metric object (instance of class) is provided and doesn't inherit from NumbaDistance. If a resolved metric is not no_python compiled. If the metric type cannot be determined. """ if x is None: x = np.zeros((10, 10)) if y is None: y = np.zeros((10, 10)) _x = to_numba_timeseries(x) _y = to_numba_timeseries(y) return _resolve_metric(metric, _x, _y, _METRIC_INFOS, **kwargs)
def pairwise_distance( x: np.ndarray, y: np.ndarray = None, metric: Union[str, Callable[[np.ndarray, np.ndarray, dict], Callable[[np.ndarray, np.ndarray], float]], Callable[[np.ndarray, np.ndarray], float], NumbaDistance, ] = "euclidean", **kwargs: Any, ) -> np.ndarray: """Compute the pairwise distance matrix between two time series. First the distance metric is 'resolved'. This means the metric that is passed is resolved to a callable. The callable is then called with x and y and the value is then returned. Then for each combination of x and y, the distance between the values are computed resulting in a 2d pairwise matrix. Parameters ---------- x: np.ndarray (1d, 2d or 3d array) First time series. y: np.ndarray (1d, 2d or 3d array), defaults = None Second time series. If not specified then y is set to the value of x. metric: str or Callable, defaults = 'euclidean' The distance metric to use. If a string is given, the value must be one of the following strings: 'euclidean', 'squared', 'dtw', 'ddtw', 'wdtw', 'wddtw', 'lcss', 'edr', 'erp' If callable then it has to be a distance factory or numba distance callable. If you want to pass custom kwargs to the distance at runtime, use a distance factory as it constructs the distance using the kwargs before distance computation. A distance callable takes the form (must be no_python compiled): Callable[[np.ndarray, np.ndarray], float] A distance factory takes the form (must return a no_python callable): Callable[[np.ndarray, np.ndarray, bool, dict], Callable[[np.ndarray, np.ndarray], float]]. kwargs: Any Extra arguments for metric. Refer to each metric documentation for a list of possible arguments. Returns ------- np.ndarray (2d of size mxn where m is len(x) and n is len(y)). Pairwise distance matrix between the two time series. Raises ------ ValueError If the value of x or y provided is not a numpy array. If the value of x or y has more than 3 dimensions. If a metric string provided, and is not a defined valid string. If a metric object (instance of class) is provided and doesn't inherit from NumbaDistance. If a resolved metric is not no_python compiled. If the metric type cannot be determined. Examples -------- >>> x_1d = np.array([1, 2, 3, 4]) # 1d array >>> y_1d = np.array([5, 6, 7, 8]) # 1d array >>> pairwise_distance(x_1d, y_1d, metric='dtw') array([[64.]]) >>> x_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) # 2d array >>> y_2d = np.array([[9, 10, 11, 12], [13, 14, 15, 16]]) # 2d array >>> pairwise_distance(x_2d, y_2d, metric='dtw') array([[256., 576.], [ 58., 256.]]) >>> x_3d = np.array([[[1], [2], [3], [4]], [[5], [6], [7], [8]]]) # 3d array >>> y_3d = np.array([[[9], [10], [11], [12]], [[13], [14], [15], [16]]]) # 3d array >>> pairwise_distance(x_3d, y_3d, metric='dtw') array([[256., 576.], [ 58., 256.]]) >>> x_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) # 2d array >>> y_2d = np.array([[9, 10, 11, 12], [13, 14, 15, 16]]) # 2d array >>> pairwise_distance(x_2d, y_2d, metric='dtw', window=0.5) array([[256., 576.], [ 58., 256.]]) """ _x = to_numba_pairwise_timeseries(x) if y is None: y = x _y = to_numba_pairwise_timeseries(y) symmetric = np.array_equal(_x, _y) _metric_callable = _resolve_metric(metric, _x[0], _y[0], _METRIC_INFOS, **kwargs) return _compute_pairwise_distance(_x, _y, symmetric, _metric_callable)
def distance( x: np.ndarray, y: np.ndarray, metric: Union[str, Callable[[np.ndarray, np.ndarray, dict], Callable[[np.ndarray, np.ndarray], float]], Callable[[np.ndarray, np.ndarray], float], NumbaDistance, ], **kwargs: Any, ) -> float: """Compute the distance between two time series. First the distance metric is 'resolved'. This means the metric that is passed is resolved to a callable. The callable is then called with x and y and the value is then returned. Parameters ---------- x: np.ndarray (1d or 2d array) First time series. y: np.ndarray (1d or 2d array) Second time series. metric: str or Callable The distance metric to use. If a string is given, the value must be one of the following strings: 'euclidean', 'squared', 'dtw', 'ddtw', 'wdtw', 'wddtw', 'lcss', 'edr', 'erp' If callable then it has to be a distance factory or numba distance callable. If you want to pass custom kwargs to the distance at runtime, use a distance factory as it constructs the distance using the kwargs before distance computation. A distance callable takes the form (must be no_python compiled): Callable[[np.ndarray, np.ndarray], float] A distance factory takes the form (must return a no_python callable): Callable[[np.ndarray, np.ndarray, bool, dict], Callable[[np.ndarray, np.ndarray], float]]. kwargs: Any Arguments for metric. Refer to each metrics documentation for a list of possible arguments. Raises ------ ValueError If the value of x or y provided is not a numpy array. If the value of x or y has more than 2 dimensions. If a metric string provided, and is not a defined valid string. If a metric object (instance of class) is provided and doesn't inherit from NumbaDistance. If a resolved metric is not no_python compiled. If the metric type cannot be determined. Examples -------- >>> x_1d = np.array([1, 2, 3, 4]) # 1d array >>> y_1d = np.array([5, 6, 7, 8]) # 1d array >>> distance(x_1d, y_1d, metric='dtw') 58.0 >>> x_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) # 2d array >>> y_2d = np.array([[9, 10, 11, 12], [13, 14, 15, 16]]) # 2d array >>> distance(x_2d, y_2d, metric='dtw') 512.0 >>> x_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) # 2d array >>> y_2d = np.array([[9, 10, 11, 12], [13, 14, 15, 16]]) # 2d array >>> distance(x_2d, y_2d, metric='dtw', window=0.5) 512.0 Returns ------- float Distance between the x and y. """ _x = to_numba_timeseries(x) _y = to_numba_timeseries(y) _metric_callable = _resolve_metric(metric, _x, _y, _METRIC_INFOS, **kwargs) return _metric_callable(_x, _y)