Instruction:
Can you generate a brief explanation for the following Python 3 code
def take_nd(arr, indexer, axis=0, out=None, fill_value=np.nan, mask_info=None,
            allow_fill=True):
    """
    Specialized Cython take which sets NaN values in one pass

    This dispatches to ``take`` defined on ExtensionArrays. It does not
    currently dispatch to ``SparseArray.take`` for sparse ``arr``.

    Parameters
    ----------
    arr : array-like
        Input array.
    indexer : ndarray
        1-D array of indices to take, subarrays corresponding to -1 value
        indices are filed with fill_value
    axis : int, default 0
        Axis to take from
    out : ndarray or None, default None
        Optional output array, must be appropriate type to hold input and
        fill_value together, if indexer has any -1 value entries; call
        _maybe_promote to determine this type for any fill_value
    fill_value : any, default np.nan
        Fill value to replace -1 values with
    mask_info : tuple of (ndarray, boolean)
        If provided, value should correspond to:
            (indexer != -1, (indexer != -1).any())
        If not provided, it will be computed internally if necessary
    allow_fill : boolean, default True
        If False, indexer is assumed to contain no -1 values so no filling
        will be done.  This short-circuits computation of a mask.  Result is
        undefined if allow_fill == False and -1 is present in indexer.

    Returns
    -------
    subarray : array-like
        May be the same type as the input, or cast to an ndarray.
    """

    # TODO(EA): Remove these if / elifs as datetimeTZ, interval, become EAs
    # dispatch to internal type takes
    if is_extension_array_dtype(arr):
        return arr.take(indexer, fill_value=fill_value, allow_fill=allow_fill)
    elif is_datetime64tz_dtype(arr):
        return arr.take(indexer, fill_value=fill_value, allow_fill=allow_fill)
    elif is_interval_dtype(arr):
        return arr.take(indexer, fill_value=fill_value, allow_fill=allow_fill)

    if is_sparse(arr):
        arr = arr.get_values()
    elif isinstance(arr, (ABCIndexClass, ABCSeries)):
        arr = arr.values

    arr = np.asarray(arr)

    if indexer is None:
        indexer = np.arange(arr.shape[axis], dtype=np.int64)
        dtype, fill_value = arr.dtype, arr.dtype.type()
    else:
        indexer = ensure_int64(indexer, copy=False)
        if not allow_fill:
            dtype, fill_value = arr.dtype, arr.dtype.type()
            mask_info = None, False
        else:
            # check for promotion based on types only (do this first because
            # it's faster than computing a mask)
            dtype, fill_value = maybe_promote(arr.dtype, fill_value)
            if dtype != arr.dtype and (out is None or out.dtype != dtype):
                # check if promotion is actually required based on indexer
                if mask_info is not None:
                    mask, needs_masking = mask_info
                else:
                    mask = indexer == -1
                    needs_masking = mask.any()
                    mask_info = mask, needs_masking
                if needs_masking:
                    if out is not None and out.dtype != dtype:
                        raise TypeError('Incompatible type for fill_value')
                else:
                    # if not, then depromote, set fill_value to dummy
                    # (it won't be used but we don't want the cython code
                    # to crash when trying to cast it to dtype)
                    dtype, fill_value = arr.dtype, arr.dtype.type()

    flip_order = False
    if arr.ndim == 2:
        if arr.flags.f_contiguous:
            flip_order = True

    if flip_order:
        arr = arr.T
        axis = arr.ndim - axis - 1
        if out is not None:
            out = out.T

    # at this point, it's guaranteed that dtype can hold both the arr values
    # and the fill_value
    if out is None:
        out_shape = list(arr.shape)
        out_shape[axis] = len(indexer)
        out_shape = tuple(out_shape)
        if arr.flags.f_contiguous and axis == arr.ndim - 1:
            # minor tweak that can make an order-of-magnitude difference
            # for dataframes initialized directly from 2-d ndarrays
            # (s.t. df.values is c-contiguous and df._data.blocks[0] is its
            # f-contiguous transpose)
            out = np.empty(out_shape, dtype=dtype, order='F')
        else:
            out = np.empty(out_shape, dtype=dtype)

    func = _get_take_nd_function(arr.ndim, arr.dtype, out.dtype, axis=axis,
                                 mask_info=mask_info)
    func(arr, indexer, out, fill_value)

    if flip_order:
        out = out.T
    return out

Response: This function handles the take operation for the base - level numpy array and returns the result as a new array.


Instruction:
Explain what the following Python 3 code does
def take_2d_multi(arr, indexer, out=None, fill_value=np.nan, mask_info=None,
                  allow_fill=True):
    """
    Specialized Cython take which sets NaN values in one pass
    """
    if indexer is None or (indexer[0] is None and indexer[1] is None):
        row_idx = np.arange(arr.shape[0], dtype=np.int64)
        col_idx = np.arange(arr.shape[1], dtype=np.int64)
        indexer = row_idx, col_idx
        dtype, fill_value = arr.dtype, arr.dtype.type()
    else:
        row_idx, col_idx = indexer
        if row_idx is None:
            row_idx = np.arange(arr.shape[0], dtype=np.int64)
        else:
            row_idx = ensure_int64(row_idx)
        if col_idx is None:
            col_idx = np.arange(arr.shape[1], dtype=np.int64)
        else:
            col_idx = ensure_int64(col_idx)
        indexer = row_idx, col_idx
        if not allow_fill:
            dtype, fill_value = arr.dtype, arr.dtype.type()
            mask_info = None, False
        else:
            # check for promotion based on types only (do this first because
            # it's faster than computing a mask)
            dtype, fill_value = maybe_promote(arr.dtype, fill_value)
            if dtype != arr.dtype and (out is None or out.dtype != dtype):
                # check if promotion is actually required based on indexer
                if mask_info is not None:
                    (row_mask, col_mask), (row_needs, col_needs) = mask_info
                else:
                    row_mask = row_idx == -1
                    col_mask = col_idx == -1
                    row_needs = row_mask.any()
                    col_needs = col_mask.any()
                    mask_info = (row_mask, col_mask), (row_needs, col_needs)
                if row_needs or col_needs:
                    if out is not None and out.dtype != dtype:
                        raise TypeError('Incompatible type for fill_value')
                else:
                    # if not, then depromote, set fill_value to dummy
                    # (it won't be used but we don't want the cython code
                    # to crash when trying to cast it to dtype)
                    dtype, fill_value = arr.dtype, arr.dtype.type()

    # at this point, it's guaranteed that dtype can hold both the arr values
    # and the fill_value
    if out is None:
        out_shape = len(row_idx), len(col_idx)
        out = np.empty(out_shape, dtype=dtype)

    func = _take_2d_multi_dict.get((arr.dtype.name, out.dtype.name), None)
    if func is None and arr.dtype != out.dtype:
        func = _take_2d_multi_dict.get((out.dtype.name, out.dtype.name), None)
        if func is not None:
            func = _convert_wrapper(func, out.dtype)
    if func is None:

        def func(arr, indexer, out, fill_value=np.nan):
            _take_2d_multi_object(arr, indexer, out, fill_value=fill_value,
                                  mask_info=mask_info)

    func(arr, indexer, out=out, fill_value=fill_value)
    return out

Response: Take a 2D array of items from a 2D array.


Instruction:
Given the following Python 3 function, write the documentation
def searchsorted(arr, value, side="left", sorter=None):
    if sorter is not None:
        sorter = ensure_platform_int(sorter)

    if isinstance(arr, np.ndarray) and is_integer_dtype(arr) and (
            is_integer(value) or is_integer_dtype(value)):
        from .arrays.array_ import array
        # if `arr` and `value` have different dtypes, `arr` would be
        # recast by numpy, causing a slow search.
        # Before searching below, we therefore try to give `value` the
        # same dtype as `arr`, while guarding against integer overflows.
        iinfo = np.iinfo(arr.dtype.type)
        value_arr = np.array([value]) if is_scalar(value) else np.array(value)
        if (value_arr >= iinfo.min).all() and (value_arr <= iinfo.max).all():
            # value within bounds, so no overflow, so can convert value dtype
            # to dtype of arr
            dtype = arr.dtype
        else:
            dtype = value_arr.dtype

        if is_scalar(value):
            value = dtype.type(value)
        else:
            value = array(value, dtype=dtype)
    elif not (is_object_dtype(arr) or is_numeric_dtype(arr) or
              is_categorical_dtype(arr)):
        from pandas.core.series import Series
        # E.g. if `arr` is an array with dtype='datetime64[ns]'
        # and `value` is a pd.Timestamp, we may need to convert value
        value_ser = Series(value)._values
        value = value_ser[0] if is_scalar(value) else value_ser

    result = arr.searchsorted(value, side=side, sorter=sorter)
    return result

Response: Searchsorted implementation of numpy. searchsorted.


Instruction:
Can you generate the documentation for the following Python 3 function
def diff(arr, n, axis=0):

    n = int(n)
    na = np.nan
    dtype = arr.dtype

    is_timedelta = False
    if needs_i8_conversion(arr):
        dtype = np.float64
        arr = arr.view('i8')
        na = iNaT
        is_timedelta = True

    elif is_bool_dtype(dtype):
        dtype = np.object_

    elif is_integer_dtype(dtype):
        dtype = np.float64

    dtype = np.dtype(dtype)
    out_arr = np.empty(arr.shape, dtype=dtype)

    na_indexer = [slice(None)] * arr.ndim
    na_indexer[axis] = slice(None, n) if n >= 0 else slice(n, None)
    out_arr[tuple(na_indexer)] = na

    if arr.ndim == 2 and arr.dtype.name in _diff_special:
        f = _diff_special[arr.dtype.name]
        f(arr, out_arr, n, axis)
    else:
        res_indexer = [slice(None)] * arr.ndim
        res_indexer[axis] = slice(n, None) if n >= 0 else slice(None, n)
        res_indexer = tuple(res_indexer)

        lag_indexer = [slice(None)] * arr.ndim
        lag_indexer[axis] = slice(None, -n) if n > 0 else slice(-n, None)
        lag_indexer = tuple(lag_indexer)

        # need to make sure that we account for na for datelike/timedelta
        # we don't actually want to subtract these i8 numbers
        if is_timedelta:
            res = arr[res_indexer]
            lag = arr[lag_indexer]

            mask = (arr[res_indexer] == na) | (arr[lag_indexer] == na)
            if mask.any():
                res = res.copy()
                res[mask] = 0
                lag = lag.copy()
                lag[mask] = 0

            result = res - lag
            result[mask] = na
            out_arr[res_indexer] = result
        else:
            out_arr[res_indexer] = arr[res_indexer] - arr[lag_indexer]

    if is_timedelta:
        from pandas import TimedeltaIndex
        out_arr = TimedeltaIndex(out_arr.ravel().astype('int64')).asi8.reshape(
            out_arr.shape).astype('timedelta64[ns]')

    return out_arr

Response: Diff of n between self and s - s. shift


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _to_ijv(ss, row_levels=(0, ), column_levels=(1, ), sort_labels=False):
    # index and column levels must be a partition of the index
    _check_is_partition([row_levels, column_levels], range(ss.index.nlevels))

    # from the SparseSeries: get the labels and data for non-null entries
    values = ss._data.internal_values()._valid_sp_values

    nonnull_labels = ss.dropna()

    def get_indexers(levels):
        """ Return sparse coords and dense labels for subset levels """

        # TODO: how to do this better? cleanly slice nonnull_labels given the
        # coord
        values_ilabels = [tuple(x[i] for i in levels)
                          for x in nonnull_labels.index]
        if len(levels) == 1:
            values_ilabels = [x[0] for x in values_ilabels]

        # # performance issues with groupby ###################################
        # TODO: these two lines can rejplace the code below but
        # groupby is too slow (in some cases at least)
        # labels_to_i = ss.groupby(level=levels, sort=sort_labels).first()
        # labels_to_i[:] = np.arange(labels_to_i.shape[0])

        def _get_label_to_i_dict(labels, sort_labels=False):
            """ Return OrderedDict of unique labels to number.
            Optionally sort by label.
            """
            labels = Index(lmap(tuple, labels)).unique().tolist()  # squish
            if sort_labels:
                labels = sorted(list(labels))
            d = OrderedDict((k, i) for i, k in enumerate(labels))
            return (d)

        def _get_index_subset_to_coord_dict(index, subset, sort_labels=False):
            ilabels = list(zip(*[index._get_level_values(i) for i in subset]))
            labels_to_i = _get_label_to_i_dict(ilabels,
                                               sort_labels=sort_labels)
            labels_to_i = Series(labels_to_i)
            if len(subset) > 1:
                labels_to_i.index = MultiIndex.from_tuples(labels_to_i.index)
                labels_to_i.index.names = [index.names[i] for i in subset]
            else:
                labels_to_i.index = Index(x[0] for x in labels_to_i.index)
                labels_to_i.index.name = index.names[subset[0]]

            labels_to_i.name = 'value'
            return (labels_to_i)

        labels_to_i = _get_index_subset_to_coord_dict(ss.index, levels,
                                                      sort_labels=sort_labels)
        # #####################################################################
        # #####################################################################

        i_coord = labels_to_i[values_ilabels].tolist()
        i_labels = labels_to_i.index.tolist()

        return i_coord, i_labels

    i_coord, i_labels = get_indexers(row_levels)
    j_coord, j_labels = get_indexers(column_levels)

    return values, i_coord, j_coord, i_labels, j_labels

Response: Convert a SparseSeries to an internal IJV.


Instruction:
Can you implement a function in Python 3 that
converts a SparseSeries to a scipy. sparse. coo_matrix using index levels row_levels column_levels as the row and column labels respectively. Returns the sparse_matrix row and column labels respectively.

Response:
def _sparse_series_to_coo(ss, row_levels=(0, ), column_levels=(1, ),
                          sort_labels=False):
    """
    Convert a SparseSeries to a scipy.sparse.coo_matrix using index
    levels row_levels, column_levels as the row and column
    labels respectively. Returns the sparse_matrix, row and column labels.
    """

    import scipy.sparse

    if ss.index.nlevels < 2:
        raise ValueError('to_coo requires MultiIndex with nlevels > 2')
    if not ss.index.is_unique:
        raise ValueError('Duplicate index entries are not allowed in to_coo '
                         'transformation.')

    # to keep things simple, only rely on integer indexing (not labels)
    row_levels = [ss.index._get_level_number(x) for x in row_levels]
    column_levels = [ss.index._get_level_number(x) for x in column_levels]

    v, i, j, rows, columns = _to_ijv(ss, row_levels=row_levels,
                                     column_levels=column_levels,
                                     sort_labels=sort_labels)
    sparse_matrix = scipy.sparse.coo_matrix(
        (v, (i, j)), shape=(len(rows), len(columns)))
    return sparse_matrix, rows, columns


Instruction:
Implement a function in Python 3 to
convert a scipy. sparse. coo_matrix to a SparseSeries.

Response:
def _coo_to_sparse_series(A, dense_index=False):
    """
    Convert a scipy.sparse.coo_matrix to a SparseSeries.
    Use the defaults given in the SparseSeries constructor.
    """
    s = Series(A.data, MultiIndex.from_arrays((A.row, A.col)))
    s = s.sort_index()
    s = s.to_sparse()  # TODO: specify kind?
    if dense_index:
        # is there a better constructor method to use here?
        i = range(A.shape[0])
        j = range(A.shape[1])
        ind = MultiIndex.from_product([i, j])
        s = s.reindex(ind)
    return s


Instruction:
Implement a function in Python 3 to
convert a datetime - like object to a numpy array of M8 values.

Response:
def _to_M8(key, tz=None):
    """
    Timestamp-like => dt64
    """
    if not isinstance(key, Timestamp):
        # this also converts strings
        key = Timestamp(key)
        if key.tzinfo is not None and tz is not None:
            # Don't tz_localize(None) if key is already tz-aware
            key = key.tz_convert(tz)
        else:
            key = key.tz_localize(tz)

    return np.int64(conversion.pydt_to_i8(key)).view(_NS_DTYPE)


Instruction:
Can you write a function in Python 3 where it
wraps comparison operations to convert datetime - like to datetime64 - like

Response:
def _dt_array_cmp(cls, op):
    """
    Wrap comparison operations to convert datetime-like to datetime64
    """
    opname = '__{name}__'.format(name=op.__name__)
    nat_result = opname == '__ne__'

    def wrapper(self, other):
        if isinstance(other, (ABCDataFrame, ABCSeries, ABCIndexClass)):
            return NotImplemented

        other = lib.item_from_zerodim(other)

        if isinstance(other, (datetime, np.datetime64, str)):
            if isinstance(other, (datetime, np.datetime64)):
                # GH#18435 strings get a pass from tzawareness compat
                self._assert_tzawareness_compat(other)

            try:
                other = _to_M8(other, tz=self.tz)
            except ValueError:
                # string that cannot be parsed to Timestamp
                return ops.invalid_comparison(self, other, op)

            result = op(self.asi8, other.view('i8'))
            if isna(other):
                result.fill(nat_result)
        elif lib.is_scalar(other) or np.ndim(other) == 0:
            return ops.invalid_comparison(self, other, op)
        elif len(other) != len(self):
            raise ValueError("Lengths must match")
        else:
            if isinstance(other, list):
                try:
                    other = type(self)._from_sequence(other)
                except ValueError:
                    other = np.array(other, dtype=np.object_)
            elif not isinstance(other, (np.ndarray, ABCIndexClass, ABCSeries,
                                        DatetimeArray)):
                # Following Timestamp convention, __eq__ is all-False
                # and __ne__ is all True, others raise TypeError.
                return ops.invalid_comparison(self, other, op)

            if is_object_dtype(other):
                # We have to use _comp_method_OBJECT_ARRAY instead of numpy
                #  comparison otherwise it would fail to raise when
                #  comparing tz-aware and tz-naive
                with np.errstate(all='ignore'):
                    result = ops._comp_method_OBJECT_ARRAY(op,
                                                           self.astype(object),
                                                           other)
                o_mask = isna(other)
            elif not (is_datetime64_dtype(other) or
                      is_datetime64tz_dtype(other)):
                # e.g. is_timedelta64_dtype(other)
                return ops.invalid_comparison(self, other, op)
            else:
                self._assert_tzawareness_compat(other)
                if isinstance(other, (ABCIndexClass, ABCSeries)):
                    other = other.array

                if (is_datetime64_dtype(other) and
                        not is_datetime64_ns_dtype(other) or
                        not hasattr(other, 'asi8')):
                    # e.g. other.dtype == 'datetime64[s]'
                    # or an object-dtype ndarray
                    other = type(self)._from_sequence(other)

                result = op(self.view('i8'), other.view('i8'))
                o_mask = other._isnan

            result = com.values_from_object(result)

            if o_mask.any():
                result[o_mask] = nat_result

        if self._hasnans:
            result[self._isnan] = nat_result

        return result

    return compat.set_function_name(wrapper, opname, cls)


Instruction:
How would you implement a function in Python 3 that
converts a list - like object to a numpy array with dtype datetime64 [ ns ].

Response:
def sequence_to_dt64ns(data, dtype=None, copy=False,
                       tz=None,
                       dayfirst=False, yearfirst=False, ambiguous='raise',
                       int_as_wall_time=False):
    """
    Parameters
    ----------
    data : list-like
    dtype : dtype, str, or None, default None
    copy : bool, default False
    tz : tzinfo, str, or None, default None
    dayfirst : bool, default False
    yearfirst : bool, default False
    ambiguous : str, bool, or arraylike, default 'raise'
        See pandas._libs.tslibs.conversion.tz_localize_to_utc
    int_as_wall_time : bool, default False
        Whether to treat ints as wall time in specified timezone, or as
        nanosecond-precision UNIX epoch (wall time in UTC).
        This is used in DatetimeIndex.__init__ to deprecate the wall-time
        behaviour.

        ..versionadded:: 0.24.0

    Returns
    -------
    result : numpy.ndarray
        The sequence converted to a numpy array with dtype ``datetime64[ns]``.
    tz : tzinfo or None
        Either the user-provided tzinfo or one inferred from the data.
    inferred_freq : Tick or None
        The inferred frequency of the sequence.

    Raises
    ------
    TypeError : PeriodDType data is passed
    """

    inferred_freq = None

    dtype = _validate_dt64_dtype(dtype)

    if not hasattr(data, "dtype"):
        # e.g. list, tuple
        if np.ndim(data) == 0:
            # i.e. generator
            data = list(data)
        data = np.asarray(data)
        copy = False
    elif isinstance(data, ABCSeries):
        data = data._values
    if isinstance(data, ABCPandasArray):
        data = data.to_numpy()

    if hasattr(data, "freq"):
        # i.e. DatetimeArray/Index
        inferred_freq = data.freq

    # if dtype has an embedded tz, capture it
    tz = validate_tz_from_dtype(dtype, tz)

    if isinstance(data, ABCIndexClass):
        data = data._data

    # By this point we are assured to have either a numpy array or Index
    data, copy = maybe_convert_dtype(data, copy)

    if is_object_dtype(data) or is_string_dtype(data):
        # TODO: We do not have tests specific to string-dtypes,
        #  also complex or categorical or other extension
        copy = False
        if lib.infer_dtype(data, skipna=False) == 'integer':
            data = data.astype(np.int64)
        else:
            # data comes back here as either i8 to denote UTC timestamps
            #  or M8[ns] to denote wall times
            data, inferred_tz = objects_to_datetime64ns(
                data, dayfirst=dayfirst, yearfirst=yearfirst)
            tz = maybe_infer_tz(tz, inferred_tz)
            # When a sequence of timestamp objects is passed, we always
            # want to treat the (now i8-valued) data as UTC timestamps,
            # not wall times.
            int_as_wall_time = False

    # `data` may have originally been a Categorical[datetime64[ns, tz]],
    # so we need to handle these types.
    if is_datetime64tz_dtype(data):
        # DatetimeArray -> ndarray
        tz = maybe_infer_tz(tz, data.tz)
        result = data._data

    elif is_datetime64_dtype(data):
        # tz-naive DatetimeArray or ndarray[datetime64]
        data = getattr(data, "_data", data)
        if data.dtype != _NS_DTYPE:
            data = conversion.ensure_datetime64ns(data)

        if tz is not None:
            # Convert tz-naive to UTC
            tz = timezones.maybe_get_tz(tz)
            data = conversion.tz_localize_to_utc(data.view('i8'), tz,
                                                 ambiguous=ambiguous)
            data = data.view(_NS_DTYPE)

        assert data.dtype == _NS_DTYPE, data.dtype
        result = data

    else:
        # must be integer dtype otherwise
        # assume this data are epoch timestamps
        if tz:
            tz = timezones.maybe_get_tz(tz)

        if data.dtype != _INT64_DTYPE:
            data = data.astype(np.int64, copy=False)
        if int_as_wall_time and tz is not None and not timezones.is_utc(tz):
            warnings.warn(_i8_message, FutureWarning, stacklevel=4)
            data = conversion.tz_localize_to_utc(data.view('i8'), tz,
                                                 ambiguous=ambiguous)
            data = data.view(_NS_DTYPE)
        result = data.view(_NS_DTYPE)

    if copy:
        # TODO: should this be deepcopy?
        result = result.copy()

    assert isinstance(result, np.ndarray), type(result)
    assert result.dtype == 'M8[ns]', result.dtype

    # We have to call this again after possibly inferring a tz above
    validate_tz_from_dtype(dtype, tz)

    return result, tz, inferred_freq


Instruction:
Given the following Python 3 function, write the documentation
def objects_to_datetime64ns(data, dayfirst, yearfirst,
                            utc=False, errors="raise",
                            require_iso8601=False, allow_object=False):
    """
    Convert data to array of timestamps.

    Parameters
    ----------
    data : np.ndarray[object]
    dayfirst : bool
    yearfirst : bool
    utc : bool, default False
        Whether to convert timezone-aware timestamps to UTC
    errors : {'raise', 'ignore', 'coerce'}
    allow_object : bool
        Whether to return an object-dtype ndarray instead of raising if the
        data contains more than one timezone.

    Returns
    -------
    result : ndarray
        np.int64 dtype if returned values represent UTC timestamps
        np.datetime64[ns] if returned values represent wall times
        object if mixed timezones
    inferred_tz : tzinfo or None

    Raises
    ------
    ValueError : if data cannot be converted to datetimes
    """
    assert errors in ["raise", "ignore", "coerce"]

    # if str-dtype, convert
    data = np.array(data, copy=False, dtype=np.object_)

    try:
        result, tz_parsed = tslib.array_to_datetime(
            data,
            errors=errors,
            utc=utc,
            dayfirst=dayfirst,
            yearfirst=yearfirst,
            require_iso8601=require_iso8601
        )
    except ValueError as e:
        try:
            values, tz_parsed = conversion.datetime_to_datetime64(data)
            # If tzaware, these values represent unix timestamps, so we
            #  return them as i8 to distinguish from wall times
            return values.view('i8'), tz_parsed
        except (ValueError, TypeError):
            raise e

    if tz_parsed is not None:
        # We can take a shortcut since the datetime64 numpy array
        #  is in UTC
        # Return i8 values to denote unix timestamps
        return result.view('i8'), tz_parsed
    elif is_datetime64_dtype(result):
        # returning M8[ns] denotes wall-times; since tz is None
        #  the distinction is a thin one
        return result, tz_parsed
    elif is_object_dtype(result):
        # GH#23675 when called via `pd.to_datetime`, returning an object-dtype
        #  array is allowed.  When called via `pd.DatetimeIndex`, we can
        #  only accept datetime64 dtype, so raise TypeError if object-dtype
        #  is returned, as that indicates the values can be recognized as
        #  datetimes but they have conflicting timezones/awareness
        if allow_object:
            return result, tz_parsed
        raise TypeError(result)
    else:  # pragma: no cover
        # GH#23675 this TypeError should never be hit, whereas the TypeError
        #  in the object-dtype branch above is reachable.
        raise TypeError(result)

Response: Convert a numpy array of timestamps to a datetime64 array of timestamps.


Instruction:
Write a Python 3 script for
converting data based on dtype conventions.

Response:
def maybe_convert_dtype(data, copy):
    """
    Convert data based on dtype conventions, issuing deprecation warnings
    or errors where appropriate.

    Parameters
    ----------
    data : np.ndarray or pd.Index
    copy : bool

    Returns
    -------
    data : np.ndarray or pd.Index
    copy : bool

    Raises
    ------
    TypeError : PeriodDType data is passed
    """
    if is_float_dtype(data):
        # Note: we must cast to datetime64[ns] here in order to treat these
        #  as wall-times instead of UTC timestamps.
        data = data.astype(_NS_DTYPE)
        copy = False
        # TODO: deprecate this behavior to instead treat symmetrically
        #  with integer dtypes.  See discussion in GH#23675

    elif is_timedelta64_dtype(data):
        warnings.warn("Passing timedelta64-dtype data is deprecated, will "
                      "raise a TypeError in a future version",
                      FutureWarning, stacklevel=5)
        data = data.view(_NS_DTYPE)

    elif is_period_dtype(data):
        # Note: without explicitly raising here, PeriodIndex
        #  test_setops.test_join_does_not_recur fails
        raise TypeError("Passing PeriodDtype data is invalid.  "
                        "Use `data.to_timestamp()` instead")

    elif is_categorical_dtype(data):
        # GH#18664 preserve tz in going DTI->Categorical->DTI
        # TODO: cases where we need to do another pass through this func,
        #  e.g. the categories are timedelta64s
        data = data.categories.take(data.codes, fill_value=NaT)._values
        copy = False

    elif is_extension_type(data) and not is_datetime64tz_dtype(data):
        # Includes categorical
        # TODO: We have no tests for these
        data = np.array(data, dtype=np.object_)
        copy = False

    return data, copy


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _validate_dt64_dtype(dtype):
    if dtype is not None:
        dtype = pandas_dtype(dtype)
        if is_dtype_equal(dtype, np.dtype("M8")):
            # no precision, warn
            dtype = _NS_DTYPE
            msg = textwrap.dedent("""\
                Passing in 'datetime64' dtype with no precision is deprecated
                and will raise in a future version. Please pass in
                'datetime64[ns]' instead.""")
            warnings.warn(msg, FutureWarning, stacklevel=5)

        if ((isinstance(dtype, np.dtype) and dtype != _NS_DTYPE)
                or not isinstance(dtype, (np.dtype, DatetimeTZDtype))):
            raise ValueError("Unexpected value for 'dtype': '{dtype}'. "
                             "Must be 'datetime64[ns]' or DatetimeTZDtype'."
                             .format(dtype=dtype))
    return dtype

Response: Validate that a dtype is either a numpy datetime64 [ ns ] or DatetimeTZDtype.


Instruction:
How would you explain what the following Python 3 function does
def validate_tz_from_dtype(dtype, tz):
    if dtype is not None:
        if isinstance(dtype, str):
            try:
                dtype = DatetimeTZDtype.construct_from_string(dtype)
            except TypeError:
                # Things like `datetime64[ns]`, which is OK for the
                # constructors, but also nonsense, which should be validated
                # but not by us. We *do* allow non-existent tz errors to
                # go through
                pass
        dtz = getattr(dtype, 'tz', None)
        if dtz is not None:
            if tz is not None and not timezones.tz_compare(tz, dtz):
                raise ValueError("cannot supply both a tz and a dtype"
                                 " with a tz")
            tz = dtz

        if tz is not None and is_datetime64_dtype(dtype):
            # We also need to check for the case where the user passed a
            #  tz-naive dtype (i.e. datetime64[ns])
            if tz is not None and not timezones.tz_compare(tz, dtz):
                raise ValueError("cannot supply both a tz and a "
                                 "timezone-naive dtype (i.e. datetime64[ns])")

    return tz

Response: Validate that the given dtype is a DatetimeTZDtype and that it does not conflict with the given tz.


Instruction:
Write a Python 3 script for
inferring a timezone from start and end time points.

Response:
def _infer_tz_from_endpoints(start, end, tz):
    """
    If a timezone is not explicitly given via `tz`, see if one can
    be inferred from the `start` and `end` endpoints.  If more than one
    of these inputs provides a timezone, require that they all agree.

    Parameters
    ----------
    start : Timestamp
    end : Timestamp
    tz : tzinfo or None

    Returns
    -------
    tz : tzinfo or None

    Raises
    ------
    TypeError : if start and end timezones do not agree
    """
    try:
        inferred_tz = timezones.infer_tzinfo(start, end)
    except Exception:
        raise TypeError('Start and end cannot both be tz-aware with '
                        'different timezones')

    inferred_tz = timezones.maybe_get_tz(inferred_tz)
    tz = timezones.maybe_get_tz(tz)

    if tz is not None and inferred_tz is not None:
        if not timezones.tz_compare(inferred_tz, tz):
            raise AssertionError("Inferred time zone not equal to passed "
                                 "time zone")

    elif inferred_tz is not None:
        tz = inferred_tz

    return tz


Instruction:
Given the following Python 3 function, write the documentation
def _maybe_localize_point(ts, is_none, is_not_none, freq, tz):
    # Make sure start and end are timezone localized if:
    # 1) freq = a Timedelta-like frequency (Tick)
    # 2) freq = None i.e. generating a linspaced range
    if isinstance(freq, Tick) or freq is None:
        localize_args = {'tz': tz, 'ambiguous': False}
    else:
        localize_args = {'tz': None}
    if is_none is None and is_not_none is not None:
        ts = ts.tz_localize(**localize_args)
    return ts

Response:
Localize a start or end Timestamp to the timezone of the corresponding
   .


Instruction:
How would you implement a function in Python 3 that
subtracts DatetimeArray or ndarray [ datetime64 ]

Response:
def _sub_datetime_arraylike(self, other):
        """subtract DatetimeArray/Index or ndarray[datetime64]"""
        if len(self) != len(other):
            raise ValueError("cannot add indices of unequal length")

        if isinstance(other, np.ndarray):
            assert is_datetime64_dtype(other)
            other = type(self)(other)

        if not self._has_same_tz(other):
            # require tz compat
            raise TypeError("{cls} subtraction must have the same "
                            "timezones or no timezones"
                            .format(cls=type(self).__name__))

        self_i8 = self.asi8
        other_i8 = other.asi8
        arr_mask = self._isnan | other._isnan
        new_values = checked_add_with_arr(self_i8, -other_i8,
                                          arr_mask=arr_mask)
        if self._hasnans or other._hasnans:
            new_values[arr_mask] = iNaT
        return new_values.view('timedelta64[ns]')


Instruction:
Create a Python 3 function to
add a timedelta - like Tick or TimedeltaIndex - like object to self yielding a new DatetimeArray

Response:
def _add_delta(self, delta):
        """
        Add a timedelta-like, Tick, or TimedeltaIndex-like object
        to self, yielding a new DatetimeArray

        Parameters
        ----------
        other : {timedelta, np.timedelta64, Tick,
                 TimedeltaIndex, ndarray[timedelta64]}

        Returns
        -------
        result : DatetimeArray
        """
        new_values = super()._add_delta(delta)
        return type(self)._from_sequence(new_values, tz=self.tz, freq='infer')


Instruction:
Make a summary of the following Python 3 code
def tz_convert(self, tz):
        tz = timezones.maybe_get_tz(tz)

        if self.tz is None:
            # tz naive, use tz_localize
            raise TypeError('Cannot convert tz-naive timestamps, use '
                            'tz_localize to localize')

        # No conversion since timestamps are all UTC to begin with
        dtype = tz_to_dtype(tz)
        return self._simple_new(self.asi8, dtype=dtype, freq=self.freq)

Response: Convert tz - aware Datetime Array or Index from one time zone to another time zone.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def tz_localize(self, tz, ambiguous='raise', nonexistent='raise',
                    errors=None):
        """
        Localize tz-naive Datetime Array/Index to tz-aware
        Datetime Array/Index.

        This method takes a time zone (tz) naive Datetime Array/Index object
        and makes this time zone aware. It does not move the time to another
        time zone.
        Time zone localization helps to switch from time zone aware to time
        zone unaware objects.

        Parameters
        ----------
        tz : str, pytz.timezone, dateutil.tz.tzfile or None
            Time zone to convert timestamps to. Passing ``None`` will
            remove the time zone information preserving local time.
        ambiguous : 'infer', 'NaT', bool array, default 'raise'
            When clocks moved backward due to DST, ambiguous times may arise.
            For example in Central European Time (UTC+01), when going from
            03:00 DST to 02:00 non-DST, 02:30:00 local time occurs both at
            00:30:00 UTC and at 01:30:00 UTC. In such a situation, the
            `ambiguous` parameter dictates how ambiguous times should be
            handled.

            - 'infer' will attempt to infer fall dst-transition hours based on
              order
            - bool-ndarray where True signifies a DST time, False signifies a
              non-DST time (note that this flag is only applicable for
              ambiguous times)
            - 'NaT' will return NaT where there are ambiguous times
            - 'raise' will raise an AmbiguousTimeError if there are ambiguous
              times

        nonexistent : 'shift_forward', 'shift_backward, 'NaT', timedelta, \
default 'raise'
            A nonexistent time does not exist in a particular timezone
            where clocks moved forward due to DST.

            - 'shift_forward' will shift the nonexistent time forward to the
              closest existing time
            - 'shift_backward' will shift the nonexistent time backward to the
              closest existing time
            - 'NaT' will return NaT where there are nonexistent times
            - timedelta objects will shift nonexistent times by the timedelta
            - 'raise' will raise an NonExistentTimeError if there are
              nonexistent times

            .. versionadded:: 0.24.0

        errors : {'raise', 'coerce'}, default None

            - 'raise' will raise a NonExistentTimeError if a timestamp is not
              valid in the specified time zone (e.g. due to a transition from
              or to DST time). Use ``nonexistent='raise'`` instead.
            - 'coerce' will return NaT if the timestamp can not be converted
              to the specified time zone. Use ``nonexistent='NaT'`` instead.

            .. deprecated:: 0.24.0

        Returns
        -------
        Same type as self
            Array/Index converted to the specified time zone.

        Raises
        ------
        TypeError
            If the Datetime Array/Index is tz-aware and tz is not None.

        See Also
        --------
        DatetimeIndex.tz_convert : Convert tz-aware DatetimeIndex from
            one time zone to another.

        Examples
        --------
        >>> tz_naive = pd.date_range('2018-03-01 09:00', periods=3)
        >>> tz_naive
        DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00',
                       '2018-03-03 09:00:00'],
                      dtype='datetime64[ns]', freq='D')

        Localize DatetimeIndex in US/Eastern time zone:

        >>> tz_aware = tz_naive.tz_localize(tz='US/Eastern')
        >>> tz_aware
        DatetimeIndex(['2018-03-01 09:00:00-05:00',
                       '2018-03-02 09:00:00-05:00',
                       '2018-03-03 09:00:00-05:00'],
                      dtype='datetime64[ns, US/Eastern]', freq='D')

        With the ``tz=None``, we can remove the time zone information
        while keeping the local time (not converted to UTC):

        >>> tz_aware.tz_localize(None)
        DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00',
                       '2018-03-03 09:00:00'],
                      dtype='datetime64[ns]', freq='D')

        Be careful with DST changes. When there is sequential data, pandas can
        infer the DST time:
        >>> s = pd.to_datetime(pd.Series(['2018-10-28 01:30:00',
        ...                               '2018-10-28 02:00:00',
        ...                               '2018-10-28 02:30:00',
        ...                               '2018-10-28 02:00:00',
        ...                               '2018-10-28 02:30:00',
        ...                               '2018-10-28 03:00:00',
        ...                               '2018-10-28 03:30:00']))
        >>> s.dt.tz_localize('CET', ambiguous='infer')
        0   2018-10-28 01:30:00+02:00
        1   2018-10-28 02:00:00+02:00
        2   2018-10-28 02:30:00+02:00
        3   2018-10-28 02:00:00+01:00
        4   2018-10-28 02:30:00+01:00
        5   2018-10-28 03:00:00+01:00
        6   2018-10-28 03:30:00+01:00
        dtype: datetime64[ns, CET]

        In some cases, inferring the DST is impossible. In such cases, you can
        pass an ndarray to the ambiguous parameter to set the DST explicitly

        >>> s = pd.to_datetime(pd.Series(['2018-10-28 01:20:00',
        ...                               '2018-10-28 02:36:00',
        ...                               '2018-10-28 03:46:00']))
        >>> s.dt.tz_localize('CET', ambiguous=np.array([True, True, False]))
        0   2015-03-29 03:00:00+02:00
        1   2015-03-29 03:30:00+02:00
        dtype: datetime64[ns, Europe/Warsaw]

        If the DST transition causes nonexistent times, you can shift these
        dates forward or backwards with a timedelta object or `'shift_forward'`
        or `'shift_backwards'`.
        >>> s = pd.to_datetime(pd.Series(['2015-03-29 02:30:00',
        ...                               '2015-03-29 03:30:00']))
        >>> s.dt.tz_localize('Europe/Warsaw', nonexistent='shift_forward')
        0   2015-03-29 03:00:00+02:00
        1   2015-03-29 03:30:00+02:00
        dtype: datetime64[ns, 'Europe/Warsaw']
        >>> s.dt.tz_localize('Europe/Warsaw', nonexistent='shift_backward')
        0   2015-03-29 01:59:59.999999999+01:00
        1   2015-03-29 03:30:00+02:00
        dtype: datetime64[ns, 'Europe/Warsaw']
        >>> s.dt.tz_localize('Europe/Warsaw', nonexistent=pd.Timedelta('1H'))
        0   2015-03-29 03:30:00+02:00
        1   2015-03-29 03:30:00+02:00
        dtype: datetime64[ns, 'Europe/Warsaw']
        """
        if errors is not None:
            warnings.warn("The errors argument is deprecated and will be "
                          "removed in a future release. Use "
                          "nonexistent='NaT' or nonexistent='raise' "
                          "instead.", FutureWarning)
            if errors == 'coerce':
                nonexistent = 'NaT'
            elif errors == 'raise':
                nonexistent = 'raise'
            else:
                raise ValueError("The errors argument must be either 'coerce' "
                                 "or 'raise'.")

        nonexistent_options = ('raise', 'NaT', 'shift_forward',
                               'shift_backward')
        if nonexistent not in nonexistent_options and not isinstance(
                nonexistent, timedelta):
            raise ValueError("The nonexistent argument must be one of 'raise',"
                             " 'NaT', 'shift_forward', 'shift_backward' or"
                             " a timedelta object")

        if self.tz is not None:
            if tz is None:
                new_dates = tzconversion.tz_convert(self.asi8, timezones.UTC,
                                                    self.tz)
            else:
                raise TypeError("Already tz-aware, use tz_convert to convert.")
        else:
            tz = timezones.maybe_get_tz(tz)
            # Convert to UTC

            new_dates = conversion.tz_localize_to_utc(
                self.asi8, tz, ambiguous=ambiguous, nonexistent=nonexistent,
            )
        new_dates = new_dates.view(_NS_DTYPE)
        dtype = tz_to_dtype(tz)
        return self._simple_new(new_dates, dtype=dtype, freq=self.freq)

Response: This method will translate the time zone of the object to the specified time zone.


Instruction:
Implement a function in Python 3 to
normalize the date - time to midnight.

Response:
def normalize(self):
        """
        Convert times to midnight.

        The time component of the date-time is converted to midnight i.e.
        00:00:00. This is useful in cases, when the time does not matter.
        Length is unaltered. The timezones are unaffected.

        This method is available on Series with datetime values under
        the ``.dt`` accessor, and directly on Datetime Array/Index.

        Returns
        -------
        DatetimeArray, DatetimeIndex or Series
            The same type as the original data. Series will have the same
            name and index. DatetimeIndex will have the same name.

        See Also
        --------
        floor : Floor the datetimes to the specified freq.
        ceil : Ceil the datetimes to the specified freq.
        round : Round the datetimes to the specified freq.

        Examples
        --------
        >>> idx = pd.date_range(start='2014-08-01 10:00', freq='H',
        ...                     periods=3, tz='Asia/Calcutta')
        >>> idx
        DatetimeIndex(['2014-08-01 10:00:00+05:30',
                       '2014-08-01 11:00:00+05:30',
                       '2014-08-01 12:00:00+05:30'],
                        dtype='datetime64[ns, Asia/Calcutta]', freq='H')
        >>> idx.normalize()
        DatetimeIndex(['2014-08-01 00:00:00+05:30',
                       '2014-08-01 00:00:00+05:30',
                       '2014-08-01 00:00:00+05:30'],
                       dtype='datetime64[ns, Asia/Calcutta]', freq=None)
        """
        if self.tz is None or timezones.is_utc(self.tz):
            not_null = ~self.isna()
            DAY_NS = ccalendar.DAY_SECONDS * 1000000000
            new_values = self.asi8.copy()
            adjustment = (new_values[not_null] % DAY_NS)
            new_values[not_null] = new_values[not_null] - adjustment
        else:
            new_values = conversion.normalize_i8_timestamps(self.asi8, self.tz)
        return type(self)._from_sequence(new_values,
                                         freq='infer').tz_localize(self.tz)


Instruction:
How would you explain what the following Python 3 function does
def to_period(self, freq=None):
        from pandas.core.arrays import PeriodArray

        if self.tz is not None:
            warnings.warn("Converting to PeriodArray/Index representation "
                          "will drop timezone information.", UserWarning)

        if freq is None:
            freq = self.freqstr or self.inferred_freq

            if freq is None:
                raise ValueError("You must pass a freq argument as "
                                 "current index has none.")

            freq = get_period_alias(freq)

        return PeriodArray._from_datetime64(self._data, freq, tz=self.tz)

Response: Converts the internal datetime - like object to PeriodArray or Index.


Instruction:
Can you tell what is the following Python 3 function doing
def to_perioddelta(self, freq):
        # TODO: consider privatizing (discussion in GH#23113)
        from pandas.core.arrays.timedeltas import TimedeltaArray
        i8delta = self.asi8 - self.to_period(freq).to_timestamp().asi8
        m8delta = i8delta.view('m8[ns]')
        return TimedeltaArray(m8delta)

Response:
Calculates the TimedeltaArray of difference between index
        values and index converted to PeriodArray at specified frequency


Instruction:
Explain what the following Python 3 code does
def month_name(self, locale=None):
        if self.tz is not None and not timezones.is_utc(self.tz):
            values = self._local_timestamps()
        else:
            values = self.asi8

        result = fields.get_date_name_field(values, 'month_name',
                                            locale=locale)
        result = self._maybe_mask_results(result, fill_value=None)
        return result

Response: Return the month names of the DateTimeIndex with specified locale.


Instruction:
Explain what the following Python 3 code does
def time(self):
        # If the Timestamps have a timezone that is not UTC,
        # convert them into their i8 representation while
        # keeping their timezone and not using UTC
        if self.tz is not None and not timezones.is_utc(self.tz):
            timestamps = self._local_timestamps()
        else:
            timestamps = self.asi8

        return tslib.ints_to_pydatetime(timestamps, box="time")

Response: Returns numpy array of datetime. time. The time part of the Timestamps.


Instruction:
How would you explain what the following Python 3 function does
def to_julian_date(self):

        # http://mysite.verizon.net/aesir_research/date/jdalg2.htm
        year = np.asarray(self.year)
        month = np.asarray(self.month)
        day = np.asarray(self.day)
        testarr = month < 3
        year[testarr] -= 1
        month[testarr] += 12
        return (day +
                np.fix((153 * month - 457) / 5) +
                365 * year +
                np.floor(year / 4) -
                np.floor(year / 100) +
                np.floor(year / 400) +
                1721118.5 +
                (self.hour +
                 self.minute / 60.0 +
                 self.second / 3600.0 +
                 self.microsecond / 3600.0 / 1e+6 +
                 self.nanosecond / 3600.0 / 1e+9
                 ) / 24.0)

Response: Convert Datetime Array to float64 ndarray of Julian Dates.


Instruction:
Create a Python 3 function to
parse the API documentation file and yield information about all public API items.

Response:
def get_api_items(api_doc_fd):
    """
    Yield information about all public API items.

    Parse api.rst file from the documentation, and extract all the functions,
    methods, classes, attributes... This should include all pandas public API.

    Parameters
    ----------
    api_doc_fd : file descriptor
        A file descriptor of the API documentation page, containing the table
        of contents with all the public API.

    Yields
    ------
    name : str
        The name of the object (e.g. 'pandas.Series.str.upper).
    func : function
        The object itself. In most cases this will be a function or method,
        but it can also be classes, properties, cython objects...
    section : str
        The name of the section in the API page where the object item is
        located.
    subsection : str
        The name of the subsection in the API page where the object item is
        located.
    """
    current_module = 'pandas'
    previous_line = current_section = current_subsection = ''
    position = None
    for line in api_doc_fd:
        line = line.strip()
        if len(line) == len(previous_line):
            if set(line) == set('-'):
                current_section = previous_line
                continue
            if set(line) == set('~'):
                current_subsection = previous_line
                continue

        if line.startswith('.. currentmodule::'):
            current_module = line.replace('.. currentmodule::', '').strip()
            continue

        if line == '.. autosummary::':
            position = 'autosummary'
            continue

        if position == 'autosummary':
            if line == '':
                position = 'items'
                continue

        if position == 'items':
            if line == '':
                position = None
                continue
            item = line.strip()
            func = importlib.import_module(current_module)
            for part in item.split('.'):
                func = getattr(func, part)

            yield ('.'.join([current_module, item]), func,
                   current_section, current_subsection)

        previous_line = line


Instruction:
Can you generate the documentation for the following Python 3 function
def get_validation_data(doc):

    errs = []
    wrns = []
    if not doc.raw_doc:
        errs.append(error('GL08'))
        return errs, wrns, ''

    if doc.start_blank_lines != 1:
        errs.append(error('GL01'))
    if doc.end_blank_lines != 1:
        errs.append(error('GL02'))
    if doc.double_blank_lines:
        errs.append(error('GL03'))
    mentioned_errs = doc.mentioned_private_classes
    if mentioned_errs:
        errs.append(error('GL04',
                          mentioned_private_classes=', '.join(mentioned_errs)))
    for line in doc.raw_doc.splitlines():
        if re.match("^ *\t", line):
            errs.append(error('GL05', line_with_tabs=line.lstrip()))

    unexpected_sections = [section for section in doc.section_titles
                           if section not in ALLOWED_SECTIONS]
    for section in unexpected_sections:
        errs.append(error('GL06',
                          section=section,
                          allowed_sections=', '.join(ALLOWED_SECTIONS)))

    correct_order = [section for section in ALLOWED_SECTIONS
                     if section in doc.section_titles]
    if correct_order != doc.section_titles:
        errs.append(error('GL07',
                          correct_sections=', '.join(correct_order)))

    if (doc.deprecated_with_directive
            and not doc.extended_summary.startswith('.. deprecated:: ')):
        errs.append(error('GL09'))

    if not doc.summary:
        errs.append(error('SS01'))
    else:
        if not doc.summary[0].isupper():
            errs.append(error('SS02'))
        if doc.summary[-1] != '.':
            errs.append(error('SS03'))
        if doc.summary != doc.summary.lstrip():
            errs.append(error('SS04'))
        elif (doc.is_function_or_method
                and doc.summary.split(' ')[0][-1] == 's'):
            errs.append(error('SS05'))
        if doc.num_summary_lines > 1:
            errs.append(error('SS06'))

    if not doc.extended_summary:
        wrns.append(('ES01', 'No extended summary found'))

    # PR01: Parameters not documented
    # PR02: Unknown parameters
    # PR03: Wrong parameters order
    errs += doc.parameter_mismatches

    for param in doc.doc_parameters:
        if not param.startswith("*"):  # Check can ignore var / kwargs
            if not doc.parameter_type(param):
                if ':' in param:
                    errs.append(error('PR10',
                                      param_name=param.split(':')[0]))
                else:
                    errs.append(error('PR04', param_name=param))
            else:
                if doc.parameter_type(param)[-1] == '.':
                    errs.append(error('PR05', param_name=param))
                common_type_errors = [('integer', 'int'),
                                      ('boolean', 'bool'),
                                      ('string', 'str')]
                for wrong_type, right_type in common_type_errors:
                    if wrong_type in doc.parameter_type(param):
                        errs.append(error('PR06',
                                          param_name=param,
                                          right_type=right_type,
                                          wrong_type=wrong_type))
        if not doc.parameter_desc(param):
            errs.append(error('PR07', param_name=param))
        else:
            if not doc.parameter_desc(param)[0].isupper():
                errs.append(error('PR08', param_name=param))
            if doc.parameter_desc(param)[-1] != '.':
                errs.append(error('PR09', param_name=param))

    if doc.is_function_or_method:
        if not doc.returns:
            if doc.method_returns_something:
                errs.append(error('RT01'))
        else:
            if len(doc.returns) == 1 and doc.returns[0].name:
                errs.append(error('RT02'))
            for name_or_type, type_, desc in doc.returns:
                if not desc:
                    errs.append(error('RT03'))
                else:
                    desc = ' '.join(desc)
                    if not desc[0].isupper():
                        errs.append(error('RT04'))
                    if not desc.endswith('.'):
                        errs.append(error('RT05'))

        if not doc.yields and 'yield' in doc.method_source:
            errs.append(error('YD01'))

    if not doc.see_also:
        wrns.append(error('SA01'))
    else:
        for rel_name, rel_desc in doc.see_also.items():
            if rel_desc:
                if not rel_desc.endswith('.'):
                    errs.append(error('SA02', reference_name=rel_name))
                if not rel_desc[0].isupper():
                    errs.append(error('SA03', reference_name=rel_name))
            else:
                errs.append(error('SA04', reference_name=rel_name))
            if rel_name.startswith('pandas.'):
                errs.append(error('SA05',
                                  reference_name=rel_name,
                                  right_reference=rel_name[len('pandas.'):]))

    examples_errs = ''
    if not doc.examples:
        wrns.append(error('EX01'))
    else:
        examples_errs = doc.examples_errors
        if examples_errs:
            errs.append(error('EX02', doctest_log=examples_errs))
        for err in doc.validate_pep8():
            errs.append(error('EX03',
                              error_code=err.error_code,
                              error_message=err.message,
                              times_happening=' ({} times)'.format(err.count)
                                              if err.count > 1 else ''))
        examples_source_code = ''.join(doc.examples_source_code)
        for wrong_import in ('numpy', 'pandas'):
            if 'import {}'.format(wrong_import) in examples_source_code:
                errs.append(error('EX04', imported_library=wrong_import))
    return errs, wrns, examples_errs

Response: Validate the docstring and return the validation data.


Instruction:
Can you create a Python 3 function that
validates the docstring for the given function_name and return a dictionary containing all the information obtained from validating .

Response:
def validate_one(func_name):
    """
    Validate the docstring for the given func_name

    Parameters
    ----------
    func_name : function
        Function whose docstring will be evaluated (e.g. pandas.read_csv).

    Returns
    -------
    dict
        A dictionary containing all the information obtained from validating
        the docstring.
    """
    doc = Docstring(func_name)
    errs, wrns, examples_errs = get_validation_data(doc)
    return {'type': doc.type,
            'docstring': doc.clean_doc,
            'deprecated': doc.deprecated,
            'file': doc.source_file_name,
            'file_line': doc.source_file_def_line,
            'github_link': doc.github_url,
            'errors': errs,
            'warnings': wrns,
            'examples_errors': examples_errs}


Instruction:
Can you write a function in Python 3 where it
executes the validation of all docstrings and return a dictionary with the results.

Response:
def validate_all(prefix, ignore_deprecated=False):
    """
    Execute the validation of all docstrings, and return a dict with the
    results.

    Parameters
    ----------
    prefix : str or None
        If provided, only the docstrings that start with this pattern will be
        validated. If None, all docstrings will be validated.
    ignore_deprecated: bool, default False
        If True, deprecated objects are ignored when validating docstrings.

    Returns
    -------
    dict
        A dictionary with an item for every function/method... containing
        all the validation information.
    """
    result = {}
    seen = {}

    # functions from the API docs
    api_doc_fnames = os.path.join(
        BASE_PATH, 'doc', 'source', 'reference', '*.rst')
    api_items = []
    for api_doc_fname in glob.glob(api_doc_fnames):
        with open(api_doc_fname) as f:
            api_items += list(get_api_items(f))
    for func_name, func_obj, section, subsection in api_items:
        if prefix and not func_name.startswith(prefix):
            continue
        doc_info = validate_one(func_name)
        if ignore_deprecated and doc_info['deprecated']:
            continue
        result[func_name] = doc_info

        shared_code_key = doc_info['file'], doc_info['file_line']
        shared_code = seen.get(shared_code_key, '')
        result[func_name].update({'in_api': True,
                                  'section': section,
                                  'subsection': subsection,
                                  'shared_code_with': shared_code})

        seen[shared_code_key] = func_name

    # functions from introspecting Series, DataFrame and Panel
    api_item_names = set(list(zip(*api_items))[0])
    for class_ in (pandas.Series, pandas.DataFrame, pandas.Panel):
        for member in inspect.getmembers(class_):
            func_name = 'pandas.{}.{}'.format(class_.__name__, member[0])
            if (not member[0].startswith('_')
                    and func_name not in api_item_names):
                if prefix and not func_name.startswith(prefix):
                    continue
                doc_info = validate_one(func_name)
                if ignore_deprecated and doc_info['deprecated']:
                    continue
                result[func_name] = doc_info
                result[func_name]['in_api'] = False

    return result


Instruction:
How would you implement a function in Python 3 that
imports a Python object from its name as string.

Response:
def _load_obj(name):
        """
        Import Python object from its name as string.

        Parameters
        ----------
        name : str
            Object name to import (e.g. pandas.Series.str.upper)

        Returns
        -------
        object
            Python object that can be a class, method, function...

        Examples
        --------
        >>> Docstring._load_obj('pandas.Series')
        <class 'pandas.core.series.Series'>
        """
        for maxsplit in range(1, name.count('.') + 1):
            # TODO when py3 only replace by: module, *func_parts = ...
            func_name_split = name.rsplit('.', maxsplit)
            module = func_name_split[0]
            func_parts = func_name_split[1:]
            try:
                obj = importlib.import_module(module)
            except ImportError:
                pass
            else:
                continue

        if 'obj' not in locals():
            raise ImportError('No module can be imported '
                              'from "{}"'.format(name))

        for part in func_parts:
            obj = getattr(obj, part)
        return obj


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _to_original_callable(obj):
        while True:
            if inspect.isfunction(obj) or inspect.isclass(obj):
                f = inspect.getfile(obj)
                if f.startswith('<') and f.endswith('>'):
                    return None
                return obj
            if inspect.ismethod(obj):
                obj = obj.__func__
            elif isinstance(obj, functools.partial):
                obj = obj.func
            elif isinstance(obj, property):
                obj = obj.fget
            else:
                return None

Response: Find the original callable that is the object that contains the source code of the object.


Instruction:
How would you explain what the following Python 3 function does
def source_file_name(self):
        try:
            fname = inspect.getsourcefile(self.code_obj)
        except TypeError:
            # In some cases the object is something complex like a cython
            # object that can't be easily introspected. An it's better to
            # return the source code file of the object as None, than crash
            pass
        else:
            if fname:
                fname = os.path.relpath(fname, BASE_PATH)
                return fname

Response: Returns the source file name of the object.


Instruction:
Given the following Python 3 function, write the documentation
def method_returns_something(self):
        '''
        Check if the docstrings method can return something.

        Bare returns, returns valued None and returns from nested functions are
        disconsidered.

        Returns
        -------
        bool
            Whether the docstrings method can return something.
        '''

        def get_returns_not_on_nested_functions(node):
            returns = [node] if isinstance(node, ast.Return) else []
            for child in ast.iter_child_nodes(node):
                # Ignore nested functions and its subtrees.
                if not isinstance(child, ast.FunctionDef):
                    child_returns = get_returns_not_on_nested_functions(child)
                    returns.extend(child_returns)
            return returns

        tree = ast.parse(self.method_source).body
        if tree:
            returns = get_returns_not_on_nested_functions(tree[0])
            return_values = [r.value for r in returns]
            # Replace NameConstant nodes valued None for None.
            for i, v in enumerate(return_values):
                if isinstance(v, ast.NameConstant) and v.value is None:
                    return_values[i] = None
            return any(return_values)
        else:
            return False

Response: Check if the docstrings method can return something.


Instruction:
How would you code a function in Python 3 to
convert numpy types to Python types and return the converted value and the optional format string.

Response:
def _value_with_fmt(self, val):
        """Convert numpy types to Python types for the Excel writers.

        Parameters
        ----------
        val : object
            Value to be written into cells

        Returns
        -------
        Tuple with the first element being the converted value and the second
            being an optional format
        """
        fmt = None

        if is_integer(val):
            val = int(val)
        elif is_float(val):
            val = float(val)
        elif is_bool(val):
            val = bool(val)
        elif isinstance(val, datetime):
            fmt = self.datetime_format
        elif isinstance(val, date):
            fmt = self.date_format
        elif isinstance(val, timedelta):
            val = val.total_seconds() / float(86400)
            fmt = '0'
        else:
            val = compat.to_str(val)

        return val, fmt


Instruction:
Create a Python 3 function for
checking that the path s extension against the Writer s supported Taxonomy extensions. If it isn t supported raises UnsupportedFiletypeError.

Response:
def check_extension(cls, ext):
        """checks that path's extension against the Writer's supported
        extensions.  If it isn't supported, raises UnsupportedFiletypeError."""
        if ext.startswith('.'):
            ext = ext[1:]
        if not any(ext in extension for extension in cls.supported_extensions):
            msg = ("Invalid extension for engine '{engine}': '{ext}'"
                   .format(engine=pprint_thing(cls.engine),
                           ext=pprint_thing(ext)))
            raise ValueError(msg)
        else:
            return True


Instruction:
Given the following Python 3 function, write the documentation
def parse(self,
              sheet_name=0,
              header=0,
              names=None,
              index_col=None,
              usecols=None,
              squeeze=False,
              converters=None,
              true_values=None,
              false_values=None,
              skiprows=None,
              nrows=None,
              na_values=None,
              parse_dates=False,
              date_parser=None,
              thousands=None,
              comment=None,
              skipfooter=0,
              convert_float=True,
              mangle_dupe_cols=True,
              **kwds):
        """
        Parse specified sheet(s) into a DataFrame

        Equivalent to read_excel(ExcelFile, ...)  See the read_excel
        docstring for more info on accepted parameters
        """

        # Can't use _deprecate_kwarg since sheetname=None has a special meaning
        if is_integer(sheet_name) and sheet_name == 0 and 'sheetname' in kwds:
            warnings.warn("The `sheetname` keyword is deprecated, use "
                          "`sheet_name` instead", FutureWarning, stacklevel=2)
            sheet_name = kwds.pop("sheetname")
        elif 'sheetname' in kwds:
            raise TypeError("Cannot specify both `sheet_name` "
                            "and `sheetname`. Use just `sheet_name`")

        if 'chunksize' in kwds:
            raise NotImplementedError("chunksize keyword of read_excel "
                                      "is not implemented")

        return self._reader.parse(sheet_name=sheet_name,
                                  header=header,
                                  names=names,
                                  index_col=index_col,
                                  usecols=usecols,
                                  squeeze=squeeze,
                                  converters=converters,
                                  true_values=true_values,
                                  false_values=false_values,
                                  skiprows=skiprows,
                                  nrows=nrows,
                                  na_values=na_values,
                                  parse_dates=parse_dates,
                                  date_parser=date_parser,
                                  thousands=thousands,
                                  comment=comment,
                                  skipfooter=skipfooter,
                                  convert_float=convert_float,
                                  mangle_dupe_cols=mangle_dupe_cols,
                                  **kwds)

Response: Parse an Excel file into a DataFrame.


Instruction:
Write a Python 3 function that can
validate that the where clause is of the right type.

Response:
def _validate_where(w):
    """
    Validate that the where statement is of the right type.

    The type may either be String, Expr, or list-like of Exprs.

    Parameters
    ----------
    w : String term expression, Expr, or list-like of Exprs.

    Returns
    -------
    where : The original where clause if the check was successful.

    Raises
    ------
    TypeError : An invalid data type was passed in for w (e.g. dict).
    """

    if not (isinstance(w, (Expr, str)) or is_list_like(w)):
        raise TypeError("where must be passed as a string, Expr, "
                        "or list-like of Exprs")

    return w


Instruction:
Make a summary of the following Python 3 code
def maybe_expression(s):
    if not isinstance(s, str):
        return False
    ops = ExprVisitor.binary_ops + ExprVisitor.unary_ops + ('=',)

    # make sure we have an op at least
    return any(op in s for op in ops)

Response: loose checking if s is a pytables - acceptable expression


Instruction:
Can you tell what is the following Python 3 function doing
def generate(self, v):
        val = v.tostring(self.encoding)
        return "({lhs} {op} {val})".format(lhs=self.lhs, op=self.op, val=val)

Response: create and return the op string for this TermValue


Instruction:
Can you generate a brief explanation for the following Python 3 code
def convert_value(self, v):

        def stringify(value):
            if self.encoding is not None:
                encoder = partial(pprint_thing_encoded,
                                  encoding=self.encoding)
            else:
                encoder = pprint_thing
            return encoder(value)

        kind = _ensure_decoded(self.kind)
        meta = _ensure_decoded(self.meta)
        if kind == 'datetime64' or kind == 'datetime':
            if isinstance(v, (int, float)):
                v = stringify(v)
            v = _ensure_decoded(v)
            v = Timestamp(v)
            if v.tz is not None:
                v = v.tz_convert('UTC')
            return TermValue(v, v.value, kind)
        elif kind == 'timedelta64' or kind == 'timedelta':
            v = Timedelta(v, unit='s').value
            return TermValue(int(v), v, kind)
        elif meta == 'category':
            metadata = com.values_from_object(self.metadata)
            result = metadata.searchsorted(v, side='left')

            # result returns 0 if v is first element or if v is not in metadata
            # check that metadata contains v
            if not result and v not in metadata:
                result = -1
            return TermValue(result, result, 'integer')
        elif kind == 'integer':
            v = int(float(v))
            return TermValue(v, v, kind)
        elif kind == 'float':
            v = float(v)
            return TermValue(v, v, kind)
        elif kind == 'bool':
            if isinstance(v, str):
                v = not v.strip().lower() in ['false', 'f', 'no',
                                              'n', 'none', '0',
                                              '[]', '{}', '']
            else:
                v = bool(v)
            return TermValue(v, v, kind)
        elif isinstance(v, str):
            # string quoting
            return TermValue(v, stringify(v), 'string')
        else:
            raise TypeError("Cannot compare {v} of type {typ} to {kind} column"
                            .format(v=v, typ=type(v), kind=kind))

Response: convert the expression that is in the term to something that is in the term


Instruction:
Can you generate the documentation for the following Python 3 function
def evaluate(self):

        try:
            self.condition = self.terms.prune(ConditionBinOp)
        except AttributeError:
            raise ValueError("cannot process expression [{expr}], [{slf}] "
                             "is not a valid condition".format(expr=self.expr,
                                                               slf=self))
        try:
            self.filter = self.terms.prune(FilterBinOp)
        except AttributeError:
            raise ValueError("cannot process expression [{expr}], [{slf}] "
                             "is not a valid filter".format(expr=self.expr,
                                                            slf=self))

        return self.condition, self.filter

Response: create and return the numexpr condition and filter


Instruction:
Can you create a Python 3 function that
quotes the string if not encoded and return

Response:
def tostring(self, encoding):
        """ quote the string if not encoded
            else encode and return """
        if self.kind == 'string':
            if encoding is not None:
                return self.converted
            return '"{converted}"'.format(converted=self.converted)
        elif self.kind == 'float':
            # python 2 str(float) is not always
            # round-trippable so use repr()
            return repr(self.converted)
        return self.converted


Instruction:
Explain what the following Python 3 code does
def _ensure_decoded(s):
    if isinstance(s, (np.bytes_, bytes)):
        s = s.decode(pd.get_option('display.encoding'))
    return s

Response: Ensure that the given string is decoded.


Instruction:
Write a Python 3 script for
wrapping around numpy. result_type which overcomes the NPY_MAXARGS argument limit

Response:
def _result_type_many(*arrays_and_dtypes):
    """ wrapper around numpy.result_type which overcomes the NPY_MAXARGS (32)
    argument limit """
    try:
        return np.result_type(*arrays_and_dtypes)
    except ValueError:
        # we have > NPY_MAXARGS terms in our expression
        return reduce(np.result_type, arrays_and_dtypes)


Instruction:
Can you write a function in Python 3 where it
validates that the minimum value of the series is not None.

Response:
def validate_argmin_with_skipna(skipna, args, kwargs):
    """
    If 'Series.argmin' is called via the 'numpy' library,
    the third parameter in its signature is 'out', which
    takes either an ndarray or 'None', so check if the
    'skipna' parameter is either an instance of ndarray or
    is None, since 'skipna' itself should be a boolean
    """

    skipna, args = process_skipna(skipna, args)
    validate_argmin(args, kwargs)
    return skipna


Instruction:
Write a Python 3 function that can
validate the maximum argument of a series.

Response:
def validate_argmax_with_skipna(skipna, args, kwargs):
    """
    If 'Series.argmax' is called via the 'numpy' library,
    the third parameter in its signature is 'out', which
    takes either an ndarray or 'None', so check if the
    'skipna' parameter is either an instance of ndarray or
    is None, since 'skipna' itself should be a boolean
    """

    skipna, args = process_skipna(skipna, args)
    validate_argmax(args, kwargs)
    return skipna


Instruction:
Make a summary of the following Python 3 code
def validate_argsort_with_ascending(ascending, args, kwargs):

    if is_integer(ascending) or ascending is None:
        args = (ascending,) + args
        ascending = True

    validate_argsort_kind(args, kwargs, max_fname_arg_count=3)
    return ascending

Response: Validate that the passed arguments are valid for the order of the categories in the current node.


Instruction:
Explain what the following Python 3 code does
def validate_clip_with_axis(axis, args, kwargs):

    if isinstance(axis, ndarray):
        args = (axis,) + args
        axis = None

    validate_clip(args, kwargs)
    return axis

Response: Validate that the first argument to NDFrame. clip is valid.


Instruction:
Here you have a function in Python 3, explain what it does
def validate_cum_func_with_skipna(skipna, args, kwargs, name):
    if not is_bool(skipna):
        args = (skipna,) + args
        skipna = True

    validate_cum_func(args, kwargs, fname=name)
    return skipna

Response: This function is called by the numpy library to check if the skipna parameter is a boolean or not.


Instruction:
Make a summary of the following Python 3 code
def validate_take_with_convert(convert, args, kwargs):

    if isinstance(convert, ndarray) or convert is None:
        args = (convert,) + args
        convert = True

    validate_take(args, kwargs, max_fname_arg_count=3, method='both')
    return convert

Response: This function is used to validate that the take function is called with the correct arguments.


Instruction:
How would you explain what the following Python 3 function does
def validate_groupby_func(name, args, kwargs, allowed=None):
    if allowed is None:
        allowed = []

    kwargs = set(kwargs) - set(allowed)

    if len(args) + len(kwargs) > 0:
        raise UnsupportedFunctionCall((
            "numpy operations are not valid "
            "with groupby. Use .groupby(...)."
            "{func}() instead".format(func=name)))

Response: Validate that the function name is a group by function.


Instruction:
Write a Python 3 function that can
validate that the function passed in is valid for the resampler.

Response:
def validate_resampler_func(method, args, kwargs):
    """
    'args' and 'kwargs' should be empty because all of
    their necessary parameters are explicitly listed in
    the function signature
    """
    if len(args) + len(kwargs) > 0:
        if method in RESAMPLER_NUMPY_OPS:
            raise UnsupportedFunctionCall((
                "numpy operations are not valid "
                "with resample. Use .resample(...)."
                "{func}() instead".format(func=method)))
        else:
            raise TypeError("too many arguments passed in")


Instruction:
Explain what the following Python 3 code does
def validate_minmax_axis(axis):
    ndim = 1  # hard-coded for Index
    if axis is None:
        return
    if axis >= ndim or (axis < 0 and ndim + axis < 0):
        raise ValueError("`axis` must be fewer than the number of "
                         "dimensions ({ndim})".format(ndim=ndim))

Response: Validate that the axis argument passed to min max argmin or argmax is not None.


Instruction:
How would you implement a function in Python 3 that
serializes a msgpack object to a file path.

Response:
def to_msgpack(path_or_buf, *args, **kwargs):
    """
    msgpack (serialize) object to input file path

    THIS IS AN EXPERIMENTAL LIBRARY and the storage format
    may not be stable until a future release.

    Parameters
    ----------
    path_or_buf : string File path, buffer-like, or None
                  if None, return generated string
    args : an object or objects to serialize
    encoding : encoding for unicode objects
    append : boolean whether to append to an existing msgpack
             (default is False)
    compress : type of compressor (zlib or blosc), default to None (no
               compression)
    """
    global compressor
    compressor = kwargs.pop('compress', None)
    append = kwargs.pop('append', None)
    if append:
        mode = 'a+b'
    else:
        mode = 'wb'

    def writer(fh):
        for a in args:
            fh.write(pack(a, **kwargs))

    path_or_buf = _stringify_path(path_or_buf)
    if isinstance(path_or_buf, str):
        with open(path_or_buf, mode) as fh:
            writer(fh)
    elif path_or_buf is None:
        buf = BytesIO()
        writer(buf)
        return buf.getvalue()
    else:
        writer(path_or_buf)


Instruction:
Implement a Python 3 function for
loading a msgpack object from a file path.

Response:
def read_msgpack(path_or_buf, encoding='utf-8', iterator=False, **kwargs):
    """
    Load msgpack pandas object from the specified
    file path

    THIS IS AN EXPERIMENTAL LIBRARY and the storage format
    may not be stable until a future release.

    Parameters
    ----------
    path_or_buf : string File path, BytesIO like or string
    encoding : Encoding for decoding msgpack str type
    iterator : boolean, if True, return an iterator to the unpacker
               (default is False)

    Returns
    -------
    obj : same type as object stored in file
    """
    path_or_buf, _, _, should_close = get_filepath_or_buffer(path_or_buf)
    if iterator:
        return Iterator(path_or_buf)

    def read(fh):
        unpacked_obj = list(unpack(fh, encoding=encoding, **kwargs))
        if len(unpacked_obj) == 1:
            return unpacked_obj[0]

        if should_close:
            try:
                path_or_buf.close()
            except IOError:
                pass
        return unpacked_obj

    # see if we have an actual file
    if isinstance(path_or_buf, str):
        try:
            exists = os.path.exists(path_or_buf)
        except (TypeError, ValueError):
            exists = False

        if exists:
            with open(path_or_buf, 'rb') as fh:
                return read(fh)

    if isinstance(path_or_buf, bytes):
        # treat as a binary-like
        fh = None
        try:
            fh = BytesIO(path_or_buf)
            return read(fh)
        finally:
            if fh is not None:
                fh.close()
    elif hasattr(path_or_buf, 'read') and callable(path_or_buf.read):
        # treat as a buffer like
        return read(path_or_buf)

    raise ValueError('path_or_buf needs to be a string file path or file-like')


Instruction:
Can you write a function in Python 3 where it
returns my dtype mapping whether number or name

Response:
def dtype_for(t):
    """ return my dtype mapping, whether number or name """
    if t in dtype_dict:
        return dtype_dict[t]
    return np.typeDict.get(t, t)


Instruction:
Can you write a function in Python 3 where it
converts strings to complex number instance with specified numpy type.

Response:
def c2f(r, i, ctype_name):
    """
    Convert strings to complex number instance with specified numpy type.
    """

    ftype = c2f_dict[ctype_name]
    return np.typeDict[ctype_name](ftype(r) + 1j * ftype(i))


Instruction:
Create a Python 3 function to
convert the numpy values to a list

Response:
def convert(values):
    """ convert the numpy values to a list """

    dtype = values.dtype

    if is_categorical_dtype(values):
        return values

    elif is_object_dtype(dtype):
        return values.ravel().tolist()

    if needs_i8_conversion(dtype):
        values = values.view('i8')
    v = values.ravel()

    if compressor == 'zlib':
        _check_zlib()

        # return string arrays like they are
        if dtype == np.object_:
            return v.tolist()

        # convert to a bytes array
        v = v.tostring()
        return ExtType(0, zlib.compress(v))

    elif compressor == 'blosc':
        _check_blosc()

        # return string arrays like they are
        if dtype == np.object_:
            return v.tolist()

        # convert to a bytes array
        v = v.tostring()
        return ExtType(0, blosc.compress(v, typesize=dtype.itemsize))

    # ndarray (on original dtype)
    return ExtType(0, v.tostring())


Instruction:
Explain what the following Python 3 code does
def encode(obj):
    tobj = type(obj)
    if isinstance(obj, Index):
        if isinstance(obj, RangeIndex):
            return {'typ': 'range_index',
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'start': getattr(obj, '_start', None),
                    'stop': getattr(obj, '_stop', None),
                    'step': getattr(obj, '_step', None)}
        elif isinstance(obj, PeriodIndex):
            return {'typ': 'period_index',
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'freq': getattr(obj, 'freqstr', None),
                    'dtype': obj.dtype.name,
                    'data': convert(obj.asi8),
                    'compress': compressor}
        elif isinstance(obj, DatetimeIndex):
            tz = getattr(obj, 'tz', None)

            # store tz info and data as UTC
            if tz is not None:
                tz = tz.zone
                obj = obj.tz_convert('UTC')
            return {'typ': 'datetime_index',
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'dtype': obj.dtype.name,
                    'data': convert(obj.asi8),
                    'freq': getattr(obj, 'freqstr', None),
                    'tz': tz,
                    'compress': compressor}
        elif isinstance(obj, (IntervalIndex, IntervalArray)):
            if isinstance(obj, IntervalIndex):
                typ = 'interval_index'
            else:
                typ = 'interval_array'
            return {'typ': typ,
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'left': getattr(obj, 'left', None),
                    'right': getattr(obj, 'right', None),
                    'closed': getattr(obj, 'closed', None)}
        elif isinstance(obj, MultiIndex):
            return {'typ': 'multi_index',
                    'klass': obj.__class__.__name__,
                    'names': getattr(obj, 'names', None),
                    'dtype': obj.dtype.name,
                    'data': convert(obj.values),
                    'compress': compressor}
        else:
            return {'typ': 'index',
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'dtype': obj.dtype.name,
                    'data': convert(obj.values),
                    'compress': compressor}

    elif isinstance(obj, Categorical):
        return {'typ': 'category',
                'klass': obj.__class__.__name__,
                'name': getattr(obj, 'name', None),
                'codes': obj.codes,
                'categories': obj.categories,
                'ordered': obj.ordered,
                'compress': compressor}

    elif isinstance(obj, Series):
        if isinstance(obj, SparseSeries):
            raise NotImplementedError(
                'msgpack sparse series is not implemented'
            )
            # d = {'typ': 'sparse_series',
            #     'klass': obj.__class__.__name__,
            #     'dtype': obj.dtype.name,
            #     'index': obj.index,
            #     'sp_index': obj.sp_index,
            #     'sp_values': convert(obj.sp_values),
            #     'compress': compressor}
            # for f in ['name', 'fill_value', 'kind']:
            #    d[f] = getattr(obj, f, None)
            # return d
        else:
            return {'typ': 'series',
                    'klass': obj.__class__.__name__,
                    'name': getattr(obj, 'name', None),
                    'index': obj.index,
                    'dtype': obj.dtype.name,
                    'data': convert(obj.values),
                    'compress': compressor}
    elif issubclass(tobj, NDFrame):
        if isinstance(obj, SparseDataFrame):
            raise NotImplementedError(
                'msgpack sparse frame is not implemented'
            )
            # d = {'typ': 'sparse_dataframe',
            #     'klass': obj.__class__.__name__,
            #     'columns': obj.columns}
            # for f in ['default_fill_value', 'default_kind']:
            #    d[f] = getattr(obj, f, None)
            # d['data'] = dict([(name, ss)
            #                 for name, ss in obj.items()])
            # return d
        else:

            data = obj._data
            if not data.is_consolidated():
                data = data.consolidate()

            # the block manager
            return {'typ': 'block_manager',
                    'klass': obj.__class__.__name__,
                    'axes': data.axes,
                    'blocks': [{'locs': b.mgr_locs.as_array,
                                'values': convert(b.values),
                                'shape': b.values.shape,
                                'dtype': b.dtype.name,
                                'klass': b.__class__.__name__,
                                'compress': compressor} for b in data.blocks]
                    }

    elif isinstance(obj, (datetime, date, np.datetime64, timedelta,
                          np.timedelta64)) or obj is NaT:
        if isinstance(obj, Timestamp):
            tz = obj.tzinfo
            if tz is not None:
                tz = tz.zone
            freq = obj.freq
            if freq is not None:
                freq = freq.freqstr
            return {'typ': 'timestamp',
                    'value': obj.value,
                    'freq': freq,
                    'tz': tz}
        if obj is NaT:
            return {'typ': 'nat'}
        elif isinstance(obj, np.timedelta64):
            return {'typ': 'timedelta64',
                    'data': obj.view('i8')}
        elif isinstance(obj, timedelta):
            return {'typ': 'timedelta',
                    'data': (obj.days, obj.seconds, obj.microseconds)}
        elif isinstance(obj, np.datetime64):
            return {'typ': 'datetime64',
                    'data': str(obj)}
        elif isinstance(obj, datetime):
            return {'typ': 'datetime',
                    'data': obj.isoformat()}
        elif isinstance(obj, date):
            return {'typ': 'date',
                    'data': obj.isoformat()}
        raise Exception(
            "cannot encode this datetimelike object: {obj}".format(obj=obj))
    elif isinstance(obj, Period):
        return {'typ': 'period',
                'ordinal': obj.ordinal,
                'freq': obj.freqstr}
    elif isinstance(obj, Interval):
        return {'typ': 'interval',
                'left': obj.left,
                'right': obj.right,
                'closed': obj.closed}
    elif isinstance(obj, BlockIndex):
        return {'typ': 'block_index',
                'klass': obj.__class__.__name__,
                'blocs': obj.blocs,
                'blengths': obj.blengths,
                'length': obj.length}
    elif isinstance(obj, IntIndex):
        return {'typ': 'int_index',
                'klass': obj.__class__.__name__,
                'indices': obj.indices,
                'length': obj.length}
    elif isinstance(obj, np.ndarray):
        return {'typ': 'ndarray',
                'shape': obj.shape,
                'ndim': obj.ndim,
                'dtype': obj.dtype.name,
                'data': convert(obj),
                'compress': compressor}
    elif isinstance(obj, np.number):
        if np.iscomplexobj(obj):
            return {'typ': 'np_scalar',
                    'sub_typ': 'np_complex',
                    'dtype': obj.dtype.name,
                    'real': obj.real.__repr__(),
                    'imag': obj.imag.__repr__()}
        else:
            return {'typ': 'np_scalar',
                    'dtype': obj.dtype.name,
                    'data': obj.__repr__()}
    elif isinstance(obj, complex):
        return {'typ': 'np_complex',
                'real': obj.real.__repr__(),
                'imag': obj.imag.__repr__()}

    return obj

Response: Encodes an object into a sequence of data structures.