如何理解numpy中的c

    技术2022-07-11  83

    其实,c_并不是一个函数,它只是CClass类的一个实例,而CClass是定义了切片方法__getitem__的类,所以c_就可以使用切片,仿佛就像一个函数一样。

    源代码是这样的

    #头部声明c_变量

    __all__ = [     'ravel_multi_index', 'unravel_index', 'mgrid', 'ogrid', 'r_', 'c_',     's_', 'index_exp', 'ix_', 'ndenumerate', 'ndindex', 'fill_diagonal',     'diag_indices', 'diag_indices_from'     ]

    #CClass继承AxisConcatenator

    class CClass(AxisConcatenator):     """     Translates slice objects to concatenation along the second axis.

        This is short-hand for ``np.r_['-1,2,0', index expression]``, which is     useful because of its common occurrence. In particular, arrays will be     stacked along their last axis after being upgraded to at least 2-D with     1's post-pended to the shape (column vectors made out of 1-D arrays).          See Also     --------     column_stack : Stack 1-D arrays as columns into a 2-D array.     r_ : For more detailed documentation.

        Examples     --------     >>> np.c_[np.array([1,2,3]), np.array([4,5,6])]     array([[1, 4],            [2, 5],            [3, 6]])     >>> np.c_[np.array([[1,2,3]]), 0, 0, np.array([[4,5,6]])]     array([[1, 2, 3, ..., 4, 5, 6]])

        """

        def __init__(self):         AxisConcatenator.__init__(self, -1, ndmin=2, trans1d=0)

    #关键一句,可见c_并不是函数,而是对象 c_ = CClass()

    #AxisConcatenator中定义了切片方法__getitem__

    class AxisConcatenator(object):     """     Translates slice objects to concatenation along an axis.

        For detailed documentation on usage, see `r_`.     """     # allow ma.mr_ to override this     concatenate = staticmethod(_nx.concatenate)     makemat = staticmethod(matrixlib.matrix)

        def __init__(self, axis=0, matrix=False, ndmin=1, trans1d=-1):         self.axis = axis         self.matrix = matrix         self.trans1d = trans1d         self.ndmin = ndmin

        def __getitem__(self, key):         # handle matrix builder syntax         if isinstance(key, str):             frame = sys._getframe().f_back             mymat = matrixlib.bmat(key, frame.f_globals, frame.f_locals)             return mymat

            if not isinstance(key, tuple):             key = (key,)

            # copy attributes, since they can be overridden in the first argument         trans1d = self.trans1d         ndmin = self.ndmin         matrix = self.matrix         axis = self.axis

            objs = []         scalars = []         arraytypes = []         scalartypes = []

            for k, item in enumerate(key):             scalar = False             if isinstance(item, slice):                 step = item.step                 start = item.start                 stop = item.stop                 if start is None:                     start = 0                 if step is None:                     step = 1                 if isinstance(step, complex):                     size = int(abs(step))                     newobj = linspace(start, stop, num=size)                 else:                     newobj = _nx.arange(start, stop, step)                 if ndmin > 1:                     newobj = array(newobj, copy=False, ndmin=ndmin)                     if trans1d != -1:                         newobj = newobj.swapaxes(-1, trans1d)             elif isinstance(item, str):                 if k != 0:                     raise ValueError("special directives must be the "                             "first entry.")                 if item in ('r', 'c'):                     matrix = True                     col = (item == 'c')                     continue                 if ',' in item:                     vec = item.split(',')                     try:                         axis, ndmin = [int(x) for x in vec[:2]]                         if len(vec) == 3:                             trans1d = int(vec[2])                         continue                     except Exception:                         raise ValueError("unknown special directive")                 try:                     axis = int(item)                     continue                 except (ValueError, TypeError):                     raise ValueError("unknown special directive")             elif type(item) in ScalarType:                 newobj = array(item, ndmin=ndmin)                 scalars.append(len(objs))                 scalar = True                 scalartypes.append(newobj.dtype)             else:                 item_ndim = ndim(item)                 newobj = array(item, copy=False, subok=True, ndmin=ndmin)                 if trans1d != -1 and item_ndim < ndmin:                     k2 = ndmin - item_ndim                     k1 = trans1d                     if k1 < 0:                         k1 += k2 + 1                     defaxes = list(range(ndmin))                     axes = defaxes[:k1] + defaxes[k2:] + defaxes[k1:k2]                     newobj = newobj.transpose(axes)             objs.append(newobj)             if not scalar and isinstance(newobj, _nx.ndarray):                 arraytypes.append(newobj.dtype)

            # Ensure that scalars won't up-cast unless warranted         final_dtype = find_common_type(arraytypes, scalartypes)         if final_dtype is not None:             for k in scalars:                 objs[k] = objs[k].astype(final_dtype)

            res = self.concatenate(tuple(objs), axis=axis)

            if matrix:             oldndim = res.ndim             res = self.makemat(res)             if oldndim == 1 and col:                 res = res.T         return res

    python看起来简单,其实一点都不简单啊!numpy真是个伟大的东东。

    Processed: 0.011, SQL: 9