[Numpy-svn] r6111 - branches/1.2.x/numpy/ma

numpy-svn@scip... numpy-svn@scip...
Wed Nov 26 22:29:53 CST 2008


Author: pierregm
Date: 2008-11-26 22:29:51 -0600 (Wed, 26 Nov 2008)
New Revision: 6111

Modified:
   branches/1.2.x/numpy/ma/core.py
   branches/1.2.x/numpy/ma/extras.py
Log:
* Added get_object_signature to fix missing signatures
* Fixed .getdoc from _arraymethod, _frommethod, _convert2ma, _fromnxfunction
* Fixed the docstrings of .trace, .mean, .argsort, .sort
* Suppressed duplicated conjugate, ptp, round, expand_dims, apply_along_axis, compress_rowcols, mask_rowcols, vander, polyfit


Modified: branches/1.2.x/numpy/ma/core.py
===================================================================
--- branches/1.2.x/numpy/ma/core.py	2008-11-27 04:29:43 UTC (rev 6110)
+++ branches/1.2.x/numpy/ma/core.py	2008-11-27 04:29:51 UTC (rev 6111)
@@ -30,7 +30,7 @@
            'compressed', 'concatenate', 'conjugate', 'copy', 'cos', 'cosh',
            'count', 'cumprod', 'cumsum',
            'default_fill_value', 'diag', 'diagonal', 'divide', 'dump', 'dumps',
-           'empty', 'empty_like', 'equal', 'exp',
+           'empty', 'empty_like', 'equal', 'exp', 'expand_dims',
            'fabs', 'fmod', 'filled', 'floor', 'floor_divide','fix_invalid',
            'frombuffer', 'fromfunction',
            'getdata','getmask', 'getmaskarray', 'greater', 'greater_equal',
@@ -96,6 +96,22 @@
     """
     return newdoc % (initialdoc, note)
 
+def get_object_signature(obj):
+    """
+    Get the signature from obj
+    """
+    import inspect
+    try:
+        sig = inspect.formatargspec(*inspect.getargspec(obj))
+    except TypeError, errmsg:
+        msg = "Unable to retrieve the signature of %s '%s'\n"\
+              "(Initial error message: %s)"
+#        warnings.warn(msg % (type(obj),
+#                             getattr(obj, '__name__', '???'),
+#                             errmsg))
+        sig = ''
+    return sig
+
 #####--------------------------------------------------------------------------
 #---- --- Exceptions ---
 #####--------------------------------------------------------------------------
@@ -1209,8 +1225,8 @@
     #
     def getdoc(self):
         "Return the doc of the function (from the doc of the method)."
-        methdoc = getattr(ndarray, self.__name__, None)
-        methdoc = getattr(np, self.__name__, methdoc)
+        methdoc = getattr(ndarray, self.__name__, None) or \
+                  getattr(np, self.__name__, None)
         if methdoc is not None:
             return methdoc.__doc__
     #
@@ -2561,9 +2577,7 @@
 
     def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None):
         """
-        Return the sum along the offset diagonal of the array's
-        indicated `axis1` and `axis2`.
-
+        (this docstring should be overwritten)
         """
         #!!!: implement out + test!
         m = self._mask
@@ -2574,8 +2588,8 @@
         else:
             D = self.diagonal(offset=offset, axis1=axis1, axis2=axis2)
             return D.astype(dtype).filled(0).sum(axis=None, out=out)
+    trace.__doc__ = ndarray.trace.__doc__
 
-
     def sum(self, axis=None, dtype=None, out=None):
         """
         Return the sum of the array elements over the given axis.
@@ -2825,7 +2839,14 @@
 
 
     def mean(self, axis=None, dtype=None, out=None):
-        ""
+        """
+    Returns the average of the array elements along given axis.
+    Refer to `numpy.mean` for full documentation.
+
+    See Also
+    --------
+    numpy.mean : equivalent function'
+        """
         if self._mask is nomask:
             result = super(MaskedArray, self).mean(axis=axis, dtype=dtype)
         else:
@@ -2841,7 +2862,6 @@
                 outmask.flat = getattr(result, '_mask', nomask)
             return out
         return result
-    mean.__doc__ = ndarray.mean.__doc__
 
     def anom(self, axis=None, dtype=None):
         """
@@ -2938,48 +2958,37 @@
     #............................................
     def argsort(self, axis=None, fill_value=None, kind='quicksort',
                 order=None):
-        """Return an ndarray of indices that sort the array along the
-        specified axis.  Masked values are filled beforehand to
-        fill_value.
+        """
+    Return an ndarray of indices that sort the array along the
+    specified axis.  Masked values are filled beforehand to
+    fill_value.
 
-        Parameters
-        ----------
-        axis : int, optional
-            Axis to be indirectly sorted.
-            If not given, uses a flatten version of the array.
-        fill_value : {var}
-            Value used to fill in the masked values.
-            If not given, self.fill_value is used instead.
-        kind : {string}
-            Sorting algorithm (default 'quicksort')
-            Possible values: 'quicksort', 'mergesort', or 'heapsort'
+    Parameters
+    ----------
+    axis : int, optional
+        Axis along which to sort.  If not given, the flattened array is used.
+    kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+        Sorting algorithm.
+    order : list, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  Not all fields need be
+        specified.
+    Returns
+    -------
+    index_array : ndarray, int
+        Array of indices that sort `a` along the specified axis.
+        In other words, ``a[index_array]`` yields a sorted `a`.
+    
+    See Also
+    --------
+    sort : Describes sorting algorithms used.
+    lexsort : Indirect stable sort with multiple keys.
+    ndarray.sort : Inplace sort.
 
-        Notes
-        -----
-        This method executes an indirect sort along the given axis
-        using the algorithm specified by the kind keyword. It returns
-        an array of indices of the same shape as 'a' that index data
-        along the given axis in sorted order.
+    Notes
+    -----
+    See `sort` for notes on the different sorting algorithms.
 
-        The various sorts are characterized by average speed, worst
-        case performance need for work space, and whether they are
-        stable.  A stable sort keeps items with the same key in the
-        same relative order. The three available algorithms have the
-        following properties:
-
-        |------------------------------------------------------|
-        |    kind   | speed |  worst case | work space | stable|
-        |------------------------------------------------------|
-        |'quicksort'|   1   | O(n^2)      |     0      |   no  |
-        |'mergesort'|   2   | O(n*log(n)) |    ~n/2    |   yes |
-        |'heapsort' |   3   | O(n*log(n)) |     0      |   no  |
-        |------------------------------------------------------|
-
-        All the sort algorithms make temporary copies of the data when
-        the sort is not along the last axis. Consequently, sorts along
-        the last axis are faster and use less space than sorts along
-        other axis.
-
         """
         if fill_value is None:
             fill_value = default_fill_value(self)
@@ -3070,19 +3079,21 @@
     def sort(self, axis=-1, kind='quicksort', order=None,
              endwith=True, fill_value=None):
         """
-    Sort along the given axis.
+    Return a sorted copy of an array.
 
     Parameters
     ----------
-    axis : {int}, optional
-        Axis to be indirectly sorted.
-    kind : {'quicksort', 'mergesort', or 'heapsort'}, optional
-        Sorting algorithm (default 'quicksort')
-        Possible values: 'quicksort', 'mergesort', or 'heapsort'.
-    order : {None, var}
-        If a has fields defined, then the order keyword can be the field name
-        to sort on or a list (or tuple) of field names to indicate  the order
-        that fields should be used to define the sort.
+    a : array_like
+        Array to be sorted.
+    axis : int or None, optional
+        Axis along which to sort. If None, the array is flattened before
+        sorting. The default is -1, which sorts along the last axis.
+    kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+        Sorting algorithm. Default is 'quicksort'.
+    order : list, optional
+        When `a` is a structured array, this argument specifies which fields
+        to compare first, second, and so on.  This list does not need to
+        include all of the fields.
     endwith : {True, False}, optional
         Whether missing values (if any) should be forced in the upper indices
         (at the end of the array) (True) or lower indices (at the beginning).
@@ -3092,30 +3103,68 @@
 
     Returns
     -------
-    - When used as method, returns None.
-    - When used as a function, returns an array.
+    sorted_array : ndarray
+        Array of the same type and shape as `a`.
 
+    See Also
+    --------
+    ndarray.sort : Method to sort an array in-place.
+    argsort : Indirect sort.
+    lexsort : Indirect stable sort on multiple keys.
+    searchsorted : Find elements in a sorted array.
+
     Notes
     -----
-    This method sorts 'a' in place along the given axis using
-    the algorithm specified by the kind keyword.
+    The various sorting algorithms are characterized by their average speed,
+    worst case performance, work space size, and whether they are stable. A
+    stable sort keeps items with the same key in the same relative
+    order. The three available algorithms have the following
+    properties:
 
-    The various sorts may characterized by average speed,
-    worst case performance need for work space, and whether
-    they are stable.  A stable sort keeps items with the same
-    key in the same relative order and is most useful when
-    used w/ argsort where the key might differ from the items
-    being sorted.  The three available algorithms have the
-    following properties:
+    =========== ======= ============= ============ =======
+       kind      speed   worst case    work space  stable
+    =========== ======= ============= ============ =======
+    'quicksort'    1     O(n^2)            0          no
+    'mergesort'    2     O(n*log(n))      ~n/2        yes
+    'heapsort'     3     O(n*log(n))       0          no
+    =========== ======= ============= ============ =======
 
-    |------------------------------------------------------|
-    |    kind   | speed |  worst case | work space | stable|
-    |------------------------------------------------------|
-    |'quicksort'|   1   | O(n^2)      |     0      |   no  |
-    |'mergesort'|   2   | O(n*log(n)) |    ~n/2    |   yes |
-    |'heapsort' |   3   | O(n*log(n)) |     0      |   no  |
-    |------------------------------------------------------|
+    All the sort algorithms make temporary copies of the data when
+    sorting along any but the last axis.  Consequently, sorting along
+    the last axis is faster and uses less space than sorting along
+    any other axis.
 
+    Examples
+    --------
+    >>> a = np.array([[1,4],[3,1]])
+    >>> np.sort(a)                # sort along the last axis
+    array([[1, 4],
+           [1, 3]])
+    >>> np.sort(a, axis=None)     # sort the flattened array
+    array([1, 1, 3, 4])
+    >>> np.sort(a, axis=0)        # sort along the first axis
+    array([[1, 1],
+           [3, 4]])
+
+    Use the `order` keyword to specify a field to use when sorting a
+    structured array:
+
+    >>> dtype = [('name', 'S10'), ('height', float), ('age', int)]
+    >>> values = [('Arthur', 1.8, 41), ('Lancelot', 1.9, 38),
+    ...           ('Galahad', 1.7, 38)]
+    >>> a = np.array(values, dtype=dtype)       # create a structured array
+    >>> np.sort(a, order='height')                        # doctest: +SKIP
+    array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41),
+           ('Lancelot', 1.8999999999999999, 38)],
+          dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+
+    Sort by age, then height if ages are equal:
+
+    >>> np.sort(a, order=['age', 'height'])               # doctest: +SKIP
+    array([('Galahad', 1.7, 38), ('Lancelot', 1.8999999999999999, 38),
+           ('Arthur', 1.8, 41)],
+          dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+
         """
         if self._mask is nomask:
             ndarray.sort(self, axis=axis, kind=kind, order=order)
@@ -3634,12 +3683,16 @@
     def __init__(self, methodname):
         self.__name__ = methodname
         self.__doc__ = self.getdoc()
+    #
     def getdoc(self):
         "Return the doc of the function (from the doc of the method)."
-        try:
-            return getattr(MaskedArray, self.__name__).__doc__
-        except:
-            return getattr(np, self.__name__).__doc__
+        meth = getattr(MaskedArray, self.__name__, None) or\
+               getattr(np, self.__name__, None)
+        signature = self.__name__ + get_object_signature(meth)
+        if meth is not None:
+            doc = """    %s\n%s""" % (signature, getattr(meth, '__doc__', None))
+            return doc
+    #
     def __call__(self, a, *args, **params):
         if isinstance(a, MaskedArray):
             return getattr(a, self.__name__).__call__(*args, **params)
@@ -3672,10 +3725,8 @@
 nonzero = _frommethod('nonzero')
 prod = _frommethod('prod')
 product = _frommethod('prod')
-ptp = _frommethod('ptp')
 ravel = _frommethod('ravel')
 repeat = _frommethod('repeat')
-round = _frommethod('round')
 shrink_mask = _frommethod('shrink_mask')
 soften_mask = _frommethod('soften_mask')
 std = _frommethod('std')
@@ -4127,7 +4178,8 @@
 
 
 def round_(a, decimals=0, out=None):
-    """Return a copy of a, rounded to 'decimals' places.
+    """
+    Return a copy of a, rounded to 'decimals' places.
 
     When 'decimals' is negative, it specifies the number of positions
     to the left of the decimal point.  The real and imaginary parts of
@@ -4156,8 +4208,8 @@
         if hasattr(out, '_mask'):
             out._mask = getmask(a)
         return out
+round = round_
 
-
 def inner(a, b):
     fa = filled(a, 0)
     fb = filled(b, 0)
@@ -4374,9 +4426,18 @@
     def __init__(self, funcname):
         self._func = getattr(np, funcname)
         self.__doc__ = self.getdoc()
+    #
     def getdoc(self):
         "Return the doc of the function (from the doc of the method)."
-        return self._func.__doc__
+        doc = getattr(self._func, '__doc__', None)
+        sig = get_object_signature(self._func)
+        if doc:
+            # Add the signature of the function at the beginning of the doc
+            if sig:
+                sig = "%s%s\n" % (self._func.__name__, sig)
+            doc = sig + doc
+        return doc
+    #
     def __call__(self, a, *args, **params):
         return self._func.__call__(a, *args, **params).view(MaskedArray)
 

Modified: branches/1.2.x/numpy/ma/extras.py
===================================================================
--- branches/1.2.x/numpy/ma/extras.py	2008-11-27 04:29:43 UTC (rev 6110)
+++ branches/1.2.x/numpy/ma/extras.py	2008-11-27 04:29:51 UTC (rev 6111)
@@ -16,15 +16,15 @@
            'column_stack','compress_cols','compress_rowcols', 'compress_rows',
            'count_masked', 'corrcoef', 'cov',
            'diagflat', 'dot','dstack',
-           'ediff1d','expand_dims',
-           'flatnotmasked_contiguous','flatnotmasked_edges',
-           'hsplit','hstack',
-           'mask_cols','mask_rowcols','mask_rows','masked_all','masked_all_like',
-           'median','mr_',
-           'notmasked_contiguous','notmasked_edges',
+           'ediff1d',
+           'flatnotmasked_contiguous', 'flatnotmasked_edges',
+           'hsplit', 'hstack',
+           'mask_cols', 'mask_rowcols', 'mask_rows', 'masked_all',
+           'masked_all_like', 'median', 'mr_',
+           'notmasked_contiguous', 'notmasked_edges',
            'polyfit',
            'row_stack',
-           'vander','vstack',
+           'vander', 'vstack',
            ]
 
 from itertools import groupby
@@ -102,11 +102,13 @@
 
     def getdoc(self):
         "Retrieves the __doc__ string from the function."
-        inidoc = getattr(np, self.__name__).__doc__
-        if inidoc:
+        npfunc = getattr(np, self.__name__, None)
+        doc = getattr(npfunc, '__doc__', None)
+        if doc:
+            sig = self.__name__ + ma.get_object_signature(npfunc)
             locdoc = "Notes\n-----\nThe function is applied to both the _data"\
                      " and the _mask, if any."
-            return '\n'.join((inidoc, locdoc))
+            return '\n'.join((sig, doc, locdoc))
         return
 
 
@@ -147,16 +149,6 @@
 
 diagflat = _fromnxfunction('diagflat')
 
-def expand_dims(a, axis):
-    """Expands the shape of a by including newaxis before axis.
-    """
-    if not isinstance(a, MaskedArray):
-        return np.expand_dims(a, axis)
-    elif getmask(a) is nomask:
-        return np.expand_dims(a, axis).view(MaskedArray)
-    m = getmaskarray(a)
-    return masked_array(np.expand_dims(a, axis),
-                        mask=np.expand_dims(m, axis))
 
 #####--------------------------------------------------------------------------
 #----
@@ -172,10 +164,9 @@
 
 
 def apply_along_axis(func1d, axis, arr, *args, **kwargs):
-    """Execute func1d(arr[i],*args) where func1d takes 1-D arrays and
-    arr is an N-d array.  i varies so as to apply the function along
-    the given axis for each 1-d subarray in arr.
     """
+    (This docstring should be overwritten)
+    """
     arr = array(arr, copy=False, subok=True)
     nd = arr.ndim
     if axis < 0:
@@ -257,7 +248,9 @@
         result = asarray(outarr, dtype=max_dtypes)
         result.fill_value = ma.default_fill_value(result)
     return result
+apply_along_axis.__doc__ = np.apply_along_axis.__doc__
 
+
 def average(a, axis=None, weights=None, returned=False):
     """Average the array over the given axis.
 
@@ -446,23 +439,25 @@
 
 #..............................................................................
 def compress_rowcols(x, axis=None):
-    """Suppress the rows and/or columns of a 2D array that contains
+    """
+    Suppress the rows and/or columns of a 2D array that contains
     masked values.
 
     The suppression behavior is selected with the `axis`parameter.
+
         - If axis is None, rows and columns are suppressed.
         - If axis is 0, only rows are suppressed.
         - If axis is 1 or -1, only columns are suppressed.
 
     Parameters
     ----------
-        axis : int, optional
-            Axis along which to perform the operation.
-            If None, applies to a flattened version of the array.
+    axis : int, optional
+        Axis along which to perform the operation.
+        If None, applies to a flattened version of the array.
 
     Returns
     -------
-        compressed_array : an ndarray.
+    compressed_array : an ndarray.
 
     """
     x = asarray(x)
@@ -499,9 +494,10 @@
     return compress_rowcols(a, 1)
 
 def mask_rowcols(a, axis=None):
-    """Mask whole rows and/or columns of a 2D array that contain
+    """
+    Mask whole rows and/or columns of a 2D array that contain
     masked values.  The masking behavior is selected with the
-    `axis`parameter.
+    `axis` parameter.
 
         - If axis is None, rows and columns are masked.
         - If axis is 0, only rows are masked.
@@ -509,13 +505,13 @@
 
     Parameters
     ----------
-        axis : int, optional
-            Axis along which to perform the operation.
-            If None, applies to a flattened version of the array.
+    axis : int, optional
+        Axis along which to perform the operation.
+        If None, applies to a flattened version of the array.
 
     Returns
     -------
-         a *pure* ndarray.
+     a *pure* ndarray.
 
     """
     a = asarray(a)
@@ -996,128 +992,20 @@
 #####--------------------------------------------------------------------------
 
 def vander(x, n=None):
-    """%s
-    Notes
-    -----
-        Masked values in x will result in rows of zeros.
     """
+    Masked values in the input array result in rows of zeros.
+    """
     _vander = np.vander(x, n)
     m = getmask(x)
     if m is not nomask:
         _vander[m] = 0
     return _vander
+vander.__doc__ = ma.doc_note(np.vander.__doc__, vander.__doc__)
 
 
 def polyfit(x, y, deg, rcond=None, full=False):
     """
-    Least squares polynomial fit.
-
-    Do a best fit polynomial of degree 'deg' of 'x' to 'y'.  Return value is a
-    vector of polynomial coefficients [pk ... p1 p0].  Eg, for ``deg = 2``::
-
-        p2*x0^2 +  p1*x0 + p0 = y1
-        p2*x1^2 +  p1*x1 + p0 = y1
-        p2*x2^2 +  p1*x2 + p0 = y2
-        .....
-        p2*xk^2 +  p1*xk + p0 = yk
-
-    Parameters
-    ----------
-    x : array_like
-        1D vector of sample points.
-    y : array_like
-        1D vector or 2D array of values to fit. The values should run down the
-        columns in the 2D case.
-    deg : integer
-        Degree of the fitting polynomial
-    rcond: {None, float}, optional
-        Relative condition number of the fit. Singular values smaller than this
-        relative to the largest singular value will be ignored. The defaul value
-        is len(x)*eps, where eps is the relative precision of the float type,
-        about 2e-16 in most cases.
-    full : {False, boolean}, optional
-        Switch determining nature of return value. When it is False just the
-        coefficients are returned, when True diagnostic information from the
-        singular value decomposition is also returned.
-
-    Returns
-    -------
-    coefficients, [residuals, rank, singular_values, rcond] : variable
-        When full=False, only the coefficients are returned, running down the
-        appropriate colume when y is a 2D array. When full=True, the rank of the
-        scaled Vandermonde matrix, its effective rank in light of the rcond
-        value, its singular values, and the specified value of rcond are also
-        returned.
-
-    Warns
-    -----
-    RankWarning : if rank is reduced and not full output
-        The warnings can be turned off by:
-        >>> import warnings
-        >>> warnings.simplefilter('ignore',np.RankWarning)
-
-
-    See Also
-    --------
-    polyval : computes polynomial values.
-
-    Notes
-    -----
-    If X is a the Vandermonde Matrix computed from x (see
-    http://mathworld.wolfram.com/VandermondeMatrix.html), then the
-    polynomial least squares solution is given by the 'p' in
-
-        X*p = y
-
-    where X.shape is a matrix of dimensions (len(x), deg + 1), p is a vector of
-    dimensions (deg + 1, 1), and y is a vector of dimensions (len(x), 1).
-
-    This equation can be solved as
-
-        p = (XT*X)^-1 * XT * y
-
-    where XT is the transpose of X and -1 denotes the inverse. However, this
-    method is susceptible to rounding errors and generally the singular value
-    decomposition of the matrix X is preferred and that is what is done here.
-    The singular value method takes a paramenter, 'rcond', which sets a limit on
-    the relative size of the smallest singular value to be used in solving the
-    equation. This may result in lowering the rank of the Vandermonde matrix, in
-    which case a RankWarning is issued. If polyfit issues a RankWarning, try a
-    fit of lower degree or replace x by x - x.mean(), both of which will
-    generally improve the condition number. The routine already normalizes the
-    vector x by its maximum absolute value to help in this regard. The rcond
-    parameter can be set to a value smaller than its default, but the resulting
-    fit may be spurious. The current default value of rcond is len(x)*eps, where
-    eps is the relative precision of the floating type being used, generally
-    around 1e-7 and 2e-16 for IEEE single and double precision respectively.
-    This value of rcond is fairly conservative but works pretty well when x -
-    x.mean() is used in place of x.
-
-
-    DISCLAIMER: Power series fits are full of pitfalls for the unwary once the
-    degree of the fit becomes large or the interval of sample points is badly
-    centered. The problem is that the powers x**n are generally a poor basis for
-    the polynomial functions on the sample interval, resulting in a Vandermonde
-    matrix is ill conditioned and coefficients sensitive to rounding erros. The
-    computation of the polynomial values will also sensitive to rounding errors.
-    Consequently, the quality of the polynomial fit should be checked against
-    the data whenever the condition number is large.  The quality of polynomial
-    fits *can not* be taken for granted. If all you want to do is draw a smooth
-    curve through the y values and polyfit is not doing the job, try centering
-    the sample range or look into scipy.interpolate, which includes some nice
-    spline fitting functions that may be of use.
-
-    For more info, see
-    http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html,
-    but note that the k's and n's in the superscripts and subscripts
-    on that page.  The linear algebra is correct, however.
-
-
-
-    Notes
-    -----
-        Any masked values in x is propagated in y, and vice-versa.
-
+    Any masked values in x is propagated in y, and vice-versa.
     """
     order = int(deg) + 1
     x = asarray(x)
@@ -1159,5 +1047,6 @@
         return c, resids, rank, s, rcond
     else :
         return c
+polyfit.__doc__ = ma.doc_note(np.polyfit.__doc__, polyfit.__doc__)
 
 ################################################################################



More information about the Numpy-svn mailing list