def concatenate(arys, axis=0): if not isinstance(arys, (list, tuple)): arys = [arys] if not arys: raise ValueError('Need at least one array to concatenate.') dtype = utils.result_type(*arys) arys = [array_ops.array(array, dtype=dtype).data for array in arys] return arrays.tensor_to_ndarray(tf.concat(arys, axis))
def array(val, dtype=None, copy=True, ndmin=0): # pylint: disable=redefined-outer-name """Creates an ndarray with the contents of val. Args: val: array_like. Could be an ndarray, a Tensor or any object that can be converted to a Tensor using `tf.convert_to_tensor`. dtype: Optional, defaults to dtype of the `val`. The type of the resulting ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`. copy: Determines whether to create a copy of the backing buffer. Since Tensors are immutable, a copy is made only if val is placed on a different device than the current one. Even if `copy` is False, a new Tensor may need to be built to satisfy `dtype` and `ndim`. This is used only if `val` is an ndarray or a Tensor. ndmin: The minimum rank of the returned array. Returns: An ndarray. """ if dtype: dtype = utils.result_type(dtype) if isinstance(val, arrays_lib.ndarray): result_t = val.data else: result_t = val if copy and isinstance(result_t, tf.Tensor): # Note: In eager mode, a copy of `result_t` is made only if it is not on # the context device. result_t = tf.identity(result_t) if not isinstance(result_t, tf.Tensor): if not dtype: dtype = utils.result_type(result_t) # We can't call `convert_to_tensor(result_t, dtype=dtype)` here because # convert_to_tensor doesn't allow incompatible arguments such as (5.5, int) # while np.array allows them. We need to convert-then-cast. def maybe_data(x): if isinstance(x, arrays_lib.ndarray): return x.data return x # Handles lists of ndarrays result_t = tf.nest.map_structure(maybe_data, result_t) result_t = arrays_lib.convert_to_tensor(result_t) result_t = tf.cast(result_t, dtype=dtype) elif dtype: result_t = tf.cast(result_t, dtype) ndims = tf.rank(result_t) def true_fn(): old_shape = tf.shape(result_t) new_shape = tf.concat([tf.ones(ndmin - ndims, tf.int32), old_shape], axis=0) return tf.reshape(result_t, new_shape) result_t = utils.cond(utils.greater(ndmin, ndims), true_fn, lambda: result_t) return arrays_lib.tensor_to_ndarray(result_t)
def tile(a, reps): a = array_ops.array(a).data reps = array_ops.array(reps, dtype=tf.int32).reshape([-1]).data a_rank = tf.rank(a) reps_size = tf.size(reps) reps = tf.pad(reps, [[tf.math.maximum(a_rank - reps_size, 0), 0]], constant_values=1) a_shape = tf.pad(tf.shape(a), [[tf.math.maximum(reps_size - a_rank, 0), 0]], constant_values=1) a = tf.reshape(a, a_shape) return arrays.tensor_to_ndarray(tf.tile(a, reps))
def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None): # pylint: disable=missing-docstring,redefined-outer-name """order, subok and shape arguments mustn't be changed.""" if order != 'K': raise ValueError('Non-standard orders are not supported.') if not subok: raise ValueError('subok being False is not supported.') if shape: raise ValueError('Overriding the shape is not supported.') a = asarray(a).data dtype = dtype or utils.result_type(a) fill_value = asarray(fill_value, dtype=dtype) return arrays_lib.tensor_to_ndarray( tf.broadcast_to(fill_value.data, tf.shape(a)))
def linspace( # pylint: disable=missing-docstring start, stop, num=50, endpoint=True, retstep=False, dtype=float, axis=0): if dtype: dtype = utils.result_type(dtype) start = array_ops.array(start, dtype=dtype).data stop = array_ops.array(stop, dtype=dtype).data if num < 0: raise ValueError( 'Number of samples {} must be non-negative.'.format(num)) step = tf.convert_to_tensor(np.nan) if endpoint: result = tf.linspace(start, stop, num, axis=axis) if num > 1: step = (stop - start) / (num - 1) else: # tf.linspace does not support endpoint=False so we manually handle it # here. if num > 1: step = ((stop - start) / num) new_stop = tf.cast(stop, step.dtype) - step start = tf.cast(start, new_stop.dtype) result = tf.linspace(start, new_stop, num, axis=axis) else: result = tf.linspace(start, stop, num, axis=axis) if dtype: result = tf.cast(result, dtype) if retstep: return arrays.tensor_to_ndarray(result), arrays.tensor_to_ndarray(step) else: return arrays.tensor_to_ndarray(result)
def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0): dtype = utils.result_type(start, stop, dtype) result = linspace(start, stop, num=num, endpoint=endpoint, dtype=dtype, axis=axis).data result = tf.pow(tf.cast(base, result.dtype), result) if dtype: result = tf.cast(result, dtype) return arrays.tensor_to_ndarray(result)
def zeros(shape, dtype=float): # pylint: disable=redefined-outer-name """Returns an ndarray with the given shape and type filled with zeros. Args: shape: A fully defined shape. Could be - NumPy array or a python scalar, list or tuple of integers, - TensorFlow tensor/ndarray of integer type and rank <=1. dtype: Optional, defaults to float. The type of the resulting ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`. Returns: An ndarray. """ if dtype: dtype = utils.result_type(dtype) if isinstance(shape, arrays_lib.ndarray): shape = shape.data return arrays_lib.tensor_to_ndarray(tf.zeros(shape, dtype=dtype))
def geomspace(start, stop, num=50, endpoint=True, dtype=float): # pylint: disable=missing-docstring if dtype: dtype = utils.result_type(dtype) if num < 0: raise ValueError('Number of samples {} must be non-negative.'.format(num)) if not num: return empty([0]) step = 1. if endpoint: if num > 1: step = tf.pow((stop / start), 1 / (num - 1)) else: step = tf.pow((stop / start), 1 / num) result = tf.cast(tf.range(num), step.dtype) result = tf.pow(step, result) result = tf.multiply(result, start) if dtype: result = tf.cast(result, dtype=dtype) return arrays_lib.tensor_to_ndarray(result)
def ones_like(a, dtype=None): """Returns an array of ones with the shape and type of the input array. Args: a: array_like. Could be an ndarray, a Tensor or any object that can be converted to a Tensor using `tf.convert_to_tensor`. dtype: Optional, defaults to dtype of the input array. The type of the resulting ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`. Returns: An ndarray. """ if isinstance(a, arrays_lib.ndarray): a = a.data if dtype is None: dtype = utils.result_type(a) else: dtype = utils.result_type(dtype) return arrays_lib.tensor_to_ndarray(tf.ones_like(a, dtype))
def full(shape, fill_value, dtype=None): # pylint: disable=redefined-outer-name """Returns an array with given shape and dtype filled with `fill_value`. Args: shape: A valid shape object. Could be a native python object or an object of type ndarray, numpy.ndarray or tf.TensorShape. fill_value: array_like. Could be an ndarray, a Tensor or any object that can be converted to a Tensor using `tf.convert_to_tensor`. dtype: Optional, defaults to dtype of the `fill_value`. The type of the resulting ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`. Returns: An ndarray. Raises: ValueError: if `fill_value` can not be broadcast to shape `shape`. """ fill_value = asarray(fill_value, dtype=dtype) if utils.isscalar(shape): shape = tf.reshape(shape, [1]) return arrays_lib.tensor_to_ndarray(tf.broadcast_to(fill_value.data, shape))
def arange(start, stop=None, step=1, dtype=None): """Returns `step`-separated values in the range [start, stop). Args: start: Start of the interval. Included in the range. stop: End of the interval. If not specified, `start` is treated as 0 and `start` value is used as `stop`. If specified, it is not included in the range if `step` is integer. When `step` is floating point, it may or may not be included. step: The difference between 2 consecutive values in the output range. It is recommended to use `linspace` instead of using non-integer values for `step`. dtype: Optional. Type of the resulting ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`. If not provided, the largest type of `start`, `stop`, `step` is used. Raises: ValueError: If step is zero. """ if not step: raise ValueError('step must be non-zero.') if dtype: dtype = utils.result_type(dtype) else: if stop is None: dtype = utils.result_type(start, step) else: dtype = utils.result_type(start, step, stop) if step > 0 and ((stop is not None and start > stop) or (stop is None and start < 0)): return array([], dtype=dtype) if step < 0 and ((stop is not None and start < stop) or (stop is None and start > 0)): return array([], dtype=dtype) # TODO(srbs): There are some bugs when start or stop is float type and dtype # is integer type. return arrays_lib.tensor_to_ndarray( tf.cast(tf.range(start, limit=stop, delta=step), dtype=dtype))
def zeros_like(a, dtype=None): """Returns an array of zeros with the shape and type of the input array. Args: a: array_like. Could be an ndarray, a Tensor or any object that can be converted to a Tensor using `tf.convert_to_tensor`. dtype: Optional, defaults to dtype of the input array. The type of the resulting ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`. Returns: An ndarray. """ if isinstance(a, arrays_lib.ndarray): a = a.data if dtype is None: # We need to let utils.result_type decide the dtype, not tf.zeros_like dtype = utils.result_type(a) else: # TF and numpy has different interpretations of Python types such as # `float`, so we let `utils.result_type` decide. dtype = utils.result_type(dtype) dtype = tf.as_dtype(dtype) # Work around b/149877262 return arrays_lib.tensor_to_ndarray(tf.zeros_like(a, dtype))
def count_nonzero(a, axis=None): return arrays.tensor_to_ndarray( tf.math.count_nonzero(array_ops.array(a).data, axis))