Skip to content

Commit

Permalink
numpy doc enhancement (apache#16637)
Browse files Browse the repository at this point in the history
* Change NDArray to ndarray for npx ops

Add nonzero

boolean mask supports boolean ndarray

Add argmin op and interoperability test for nonzero

Fix vdot, inner, outter docs

Add nonzero to mx.nd.np

Add docs

Fix

* Fix lint

* Fix

* Fix

* Fix get_constant
  • Loading branch information
reminisce authored and yajiedesign committed Nov 6, 2019
1 parent c6dc4b3 commit e1e0291
Show file tree
Hide file tree
Showing 24 changed files with 1,062 additions and 102 deletions.
60 changes: 60 additions & 0 deletions python/mxnet/_numpy_op_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ def _np_ones_like(a):
-------
out : ndarray
Array of ones with the same shape and type as `a`.
Examples
--------
>>> x = np.arange(6)
>>> x = x.reshape((2, 3))
>>> x
array([[0., 1., 2.],
[3., 4., 5.]])
>>> np.ones_like(x)
array([[1., 1., 1.],
[1., 1., 1.]])
>>> y = np.arange(3, dtype=float)
>>> y
array([0., 1., 2.], dtype=float64)
>>>
>>> np.ones_like(y)
array([1., 1., 1.], dtype=float64)
"""
pass

Expand All @@ -52,6 +70,23 @@ def _np_zeros_like(a):
-------
out : ndarray
Array of zeros with the same shape and type as `a`.
Examples
--------
>>> x = np.arange(6)
>>> x = x.reshape((2, 3))
>>> x
array([[0., 1., 2.],
[3., 4., 5.]])
>>> np.zeros_like(x)
array([[0., 0., 0.],
[0., 0., 0.]])
>>> y = np.arange(3, dtype=float)
>>> y
array([0., 1., 2.], dtype=float64)
>>>
>>> np.zeros_like(y)
array([0., 0., 0.], dtype=float64)
"""
pass

Expand Down Expand Up @@ -477,6 +512,31 @@ def _np_reshape(a, newshape, order='C', out=None):
See Also
--------
ndarray.reshape : Equivalent method.
Examples
--------
>>> a = np.arange(6).reshape((3, 2))
>>> a
array([[0., 1.],
[2., 3.],
[4., 5.]])
>>> np.reshape(a, (2, 3)) # C-like index ordering
array([[0., 1., 2.],
[3., 4., 5.]])
>>> np.reshape(np.ravel(a), (2, 3)) # equivalent to C ravel then C reshape
array([[0., 1., 2.],
[3., 4., 5.]])
>>> a = np.array([[1,2,3], [4,5,6]])
>>> np.reshape(a, 6)
array([1., 2., 3., 4., 5., 6.])
>>> np.reshape(a, (3,-1)) # the unspecified value is inferred to be 2
array([[1., 2.],
[3., 4.],
[5., 6.]])
"""


Expand Down
3 changes: 3 additions & 0 deletions python/mxnet/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"""ctypes library of mxnet and helper functions."""
from __future__ import absolute_import

import re
import atexit
import ctypes
import os
Expand Down Expand Up @@ -853,3 +854,5 @@ def _init_np_op_module(root_module_name, np_module_name, mx_module_name, make_op

if hasattr(_np_op_doc, name):
function.__doc__ = getattr(_np_op_doc, name).__doc__
else:
function.__doc__ = re.sub('NDArray', 'ndarray', function.__doc__)
3 changes: 2 additions & 1 deletion python/mxnet/gluon/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,8 @@ def __init__(self, **kwargs):
"""
def __init__(self, name, value):
if not isinstance(value, ndarray.NDArray):
value = ndarray.array(value)
array_fn = _mx_np.array if is_np_array() else ndarray.array
value = array_fn(value)
self.value = value

class Init(initializer.Initializer):
Expand Down
156 changes: 152 additions & 4 deletions python/mxnet/ndarray/numpy/_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
'log1p', 'rint', 'radians', 'reciprocal', 'square', 'negative', 'fix', 'ceil', 'floor',
'trunc', 'logical_not', 'arcsinh', 'arccosh', 'arctanh', 'tensordot', 'histogram', 'eye',
'linspace', 'logspace', 'expand_dims', 'tile', 'arange', 'split', 'vsplit', 'concatenate',
'stack', 'vstack', 'dstack', 'mean', 'maximum', 'minimum', 'swapaxes', 'clip', 'argmax',
'stack', 'vstack', 'dstack', 'mean', 'maximum', 'minimum', 'swapaxes', 'clip', 'argmax', 'argmin',
'std', 'var', 'indices', 'copysign', 'ravel', 'hanning', 'hamming', 'blackman', 'flip',
'around', 'hypot', 'rad2deg', 'deg2rad', 'unique', 'lcm', 'tril', 'identity', 'take',
'ldexp', 'vdot', 'inner', 'outer', 'equal', 'not_equal', 'greater', 'less', 'greater_equal', 'less_equal',
'hsplit', 'rot90', 'einsum', 'true_divide']
'hsplit', 'rot90', 'einsum', 'true_divide', 'nonzero']


@set_module('mxnet.ndarray.numpy')
Expand Down Expand Up @@ -3165,8 +3165,6 @@ def clip(a, a_min, a_max, out=None):
@set_module('mxnet.ndarray.numpy')
def argmax(a, axis=None, out=None):
r"""
argmax(a, axis=None, out=None)
Returns the indices of the maximum values along an axis.
Parameters
Expand Down Expand Up @@ -3234,6 +3232,75 @@ def argmax(a, axis=None, out=None):
return _npi.argmax(a, axis=axis, keepdims=False, out=out)


@set_module('mxnet.ndarray.numpy')
def argmin(a, axis=None, out=None):
r"""
Returns the indices of the maximum values along an axis.
Parameters
----------
a : ndarray
Input array. Only support ndarrays of dtype `float16`, `float32`, and `float64`.
axis : int, optional
By default, the index is into the flattened array, otherwise
along the specified axis.
out : ndarray or None, optional
If provided, the result will be inserted into this array. It should
be of the appropriate shape and dtype.
Returns
-------
index_array : ndarray of indices whose dtype is same as the input ndarray.
Array of indices into the array. It has the same shape as `a.shape`
with the dimension along `axis` removed.
Notes
-----
In case of multiple occurrences of the maximum values, the indices
corresponding to the first occurrence are returned.
This function differs from the original `numpy.argmax
<https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html>`_ in
the following aspects:
- Input type does not support Python native iterables(list, tuple, ...).
- Output has dtype that is same as the input ndarray.
- ``out`` param: cannot perform auto broadcasting. ``out`` ndarray's shape must be the same as the expected output.
- ``out`` param: cannot perform auto type cast. ``out`` ndarray's dtype must be the same as the expected output.
- ``out`` param does not support scalar input case.
Examples
--------
>>> a = np.arange(6).reshape(2,3) + 10
>>> a
array([[10., 11., 12.],
[13., 14., 15.]])
>>> np.argmin(a)
array(0.)
>>> np.argmin(a, axis=0)
array([0., 0., 0.])
>>> np.argmin(a, axis=1)
array([0., 0.])
>>> b = np.arange(6)
>>> b[2] = 0
>>> b
array([0., 1., 0., 3., 4., 5.])
>>> np.argmax(b) # Only the first occurrence is returned.
array(0.)
Specify ``out`` ndarray:
>>> a = np.arange(6).reshape(2,3) + 10
>>> b = np.zeros((2,))
>>> np.argmin(a, axis=1, out=b)
array([0., 0.])
>>> b
array([0., 0.])
"""
return _npi.argmin(a, axis=axis, keepdims=False, out=out)


@set_module('mxnet.ndarray.numpy')
def mean(a, axis=None, dtype=None, out=None, keepdims=False): # pylint: disable=arguments-differ
"""
Expand Down Expand Up @@ -4761,3 +4828,84 @@ def einsum(*operands, **kwargs):
subscripts = operands[0]
operands = operands[1:]
return _npi.einsum(*operands, subscripts=subscripts, out=out, optimize=int(optimize_arg))


@set_module('mxnet.ndarray.numpy')
def nonzero(a):
"""
Return the indices of the elements that are non-zero.
Returns a tuple of arrays, one for each dimension of `a`,
containing the indices of the non-zero elements in that
dimension. The values in `a` are always returned in
row-major, C-style order.
To group the indices by element, rather than dimension, use `argwhere`,
which returns a row for each non-zero element.
Parameters
----------
a : ndarray
Input array.
Returns
-------
tuple_of_arrays : tuple
Indices of elements that are non-zero.
See Also
--------
ndarray.nonzero :
Equivalent ndarray method.
Notes
-----
While the nonzero values can be obtained with ``a[nonzero(a)]``, it is
recommended to use ``x[x.astype(bool)]`` or ``x[x != 0]`` instead, which
will correctly handle 0-d arrays.
Examples
--------
>>> x = np.array([[3, 0, 0], [0, 4, 0], [5, 6, 0]])
>>> x
array([[3, 0, 0],
[0, 4, 0],
[5, 6, 0]], dtype=int32)
>>> np.nonzero(x)
(array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64))
>>> x[np.nonzero(x)]
array([3, 4, 5, 6])
>>> np.transpose(np.stack(np.nonzero(x)))
array([[0, 0],
[1, 1],
[2, 0],
[2, 1]], dtype=int64)
A common use for ``nonzero`` is to find the indices of an array, where
a condition is True. Given an array `a`, the condition `a` > 3 is a
boolean array and since False is interpreted as 0, np.nonzero(a > 3)
yields the indices of the `a` where the condition is true.
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.int32)
>>> a > 3
array([[False, False, False],
[ True, True, True],
[ True, True, True]])
>>> np.nonzero(a > 3)
(array([1, 1, 1, 2, 2, 2], dtype=int64), array([0, 1, 2, 0, 1, 2], dtype=int64))
Using this result to index `a` is equivalent to using the mask directly:
>>> a[np.nonzero(a > 3)]
array([4, 5, 6, 7, 8, 9], dtype=int32)
>>> a[a > 3]
array([4, 5, 6, 7, 8, 9], dtype=int32)
``nonzero`` can also be called as a method of the array.
>>> (a > 3).nonzero()
(array([1, 1, 1, 2, 2, 2], dtype=int64), array([0, 1, 2, 0, 1, 2], dtype=int64))
"""
out = _npi.nonzero(a).transpose()
return tuple([out[i] for i in range(len(out))])
12 changes: 6 additions & 6 deletions python/mxnet/ndarray/numpy/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
from ..ndarray import NDArray


__all__ = ['randint', 'uniform', 'normal', "choice", "rand"]
__all__ = ['randint', 'uniform', 'normal', "choice", "rand", "multinomial"]


def randint(low, high=None, size=None, dtype=None, ctx=None, out=None):
"""Return random integers from `low` (inclusive) to `high` (exclusive).
r"""Return random integers from `low` (inclusive) to `high` (exclusive).
Return random integers from the "discrete uniform" distribution of
the specified dtype in the "half-open" interval [`low`, `high`). If
Expand Down Expand Up @@ -88,7 +88,7 @@ def randint(low, high=None, size=None, dtype=None, ctx=None, out=None):


def uniform(low=0.0, high=1.0, size=None, dtype=None, ctx=None, out=None):
"""Draw samples from a uniform distribution.
r"""Draw samples from a uniform distribution.
Samples are uniformly distributed over the half-open interval
``[low, high)`` (includes low, but excludes high). In other words,
Expand Down Expand Up @@ -143,7 +143,7 @@ def uniform(low=0.0, high=1.0, size=None, dtype=None, ctx=None, out=None):


def normal(loc=0.0, scale=1.0, size=None, dtype=None, ctx=None, out=None):
"""Draw random samples from a normal (Gaussian) distribution.
r"""Draw random samples from a normal (Gaussian) distribution.
Samples are distributed according to a normal distribution parametrized
by *loc* (mean) and *scale* (standard deviation).
Expand Down Expand Up @@ -194,7 +194,7 @@ def normal(loc=0.0, scale=1.0, size=None, dtype=None, ctx=None, out=None):


def multinomial(n, pvals, size=None):
"""multinomial(n, pvals, size=None)
r"""multinomial(n, pvals, size=None)
Draw samples from a multinomial distribution.
Expand Down Expand Up @@ -246,7 +246,7 @@ def multinomial(n, pvals, size=None):


def choice(a, size=None, replace=True, p=None, ctx=None, out=None):
"""Generates a random sample from a given 1-D array
r"""Generates a random sample from a given 1-D array
Parameters
-----------
Expand Down
25 changes: 25 additions & 0 deletions python/mxnet/numpy/linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,35 @@ def norm(x, ord=None, axis=None, keepdims=False):
n : float or ndarray
Norm of the matrix or vector(s).
Notes
-----
This operator differs from NumPy in the aspect that it always returns a
zero-dim tensor for the cases where Python float values are expected
in NumPy.
References
----------
.. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*,
Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15
Examples
--------
>>> from numpy import linalg as LA
>>> a = np.arange(9) - 4
>>> a
array([-4., -3., -2., -1., 0., 1., 2., 3., 4.])
>>> b = a.reshape((3, 3))
>>> b
array([[-4., -3., -2.],
[-1., 0., 1.],
[ 2., 3., 4.]])
>>> LA.norm(a)
array(7.745967)
>>>
>>> LA.norm(b)
array(7.745967)
>>> LA.norm(b, 'fro')
array(7.745967)
"""
return _mx_nd_np.linalg.norm(x, ord, axis, keepdims)

Expand Down
Loading

0 comments on commit e1e0291

Please sign in to comment.