示例#1
0
    def equals(
        self,
        other: tp.Any,
        *,
        compare_name: bool = False,
        compare_dtype: bool = False,
        compare_class: bool = False,
        skipna: bool = True,
    ) -> bool:
        '''
        {doc}

        Args:
            {compare_name}
            {compare_dtype}
            {compare_class}
            {skipna}
        '''

        if id(other) == id(self):
            return True

        if compare_class and self.__class__ != other.__class__:
            return False
        elif not isinstance(other, Index):
            return False

        # defer updating cache
        if self._recache:
            self._update_array_cache()

        # same type from here
        if len(self) != len(other):
            return False
        if compare_name and self.name != other.name:
            return False
        if compare_dtype and self.dtype != other.dtype:
            return False

        eq = self.values == other.values

        # NOTE: will only be False, or an array
        if eq is False:
            return eq  #type: ignore

        if skipna:
            isna_both = (isna_array(self.values, include_none=False)
                         & isna_array(other.values, include_none=False))
            eq[isna_both] = True

        if not eq.all():
            return False
        return True
示例#2
0
    def test_isna_array(self, array: np.ndarray) -> None:

        post = util.isna_array(array)
        self.assertTrue(post.dtype == bool)

        values = np.ravel(array)
        count_na = sum(util.isna_element(x) for x in values)

        self.assertTrue(np.ravel(post).sum() == count_na)
示例#3
0
    def test_isna_array_b(self) -> None:

        a1 = np.array([[1, 2], [3, 4]])
        a2 = np.array([[False, True, False], [False, True, False]])
        a3 = np.array([['b', 'c', 'd'], ['b', 'c', 'd']])
        a4 = np.array([[2.3, 3.2, np.nan], [2.3, 3.2, np.nan]])
        a5 = np.array([['test', 'test again', np.nan],
                ['test', 'test again', np.nan]], dtype=object)
        a6 = np.array([[2.3, 5.4, np.nan], [2.3, 5.4, np.nan]], dtype='float32')

        self.assertEqual(isna_array(a1).tolist(),
                [[False, False], [False, False]])

        self.assertEqual(isna_array(a2).tolist(),
                [[False, False, False], [False, False, False]])

        self.assertEqual(isna_array(a3).tolist(),
                [[False, False, False], [False, False, False]])

        self.assertEqual(isna_array(a4).tolist(),
                [[False, False, True], [False, False, True]])

        self.assertEqual(isna_array(a5).tolist(),
                [[False, False, True], [False, False, True]])

        self.assertEqual(isna_array(a6).tolist(),
                [[False, False, True], [False, False, True]])
示例#4
0
    def test_ufunc_skipna_1d(self, array: np.ndarray) -> None:

        has_na = util.isna_array(array).any()
        for ufunc, ufunc_skipna, dtype in UFUNC_AXIS_SKIPNA.values():

            with np.errstate(over='ignore', under='ignore'):
                v1 = ufunc_skipna(array)
                # this should return a single value
                self.assertFalse(isinstance(v1, np.ndarray))

                if has_na:
                    v2 = ufunc(array)
                    self.assertFalse(isinstance(v2, np.ndarray))
示例#5
0
    def test_ufunc_axis_skipna(self, array: np.ndarray) -> None:

        has_na = util.isna_array(array).any()

        for nt in UFUNC_AXIS_SKIPNA.values():
            ufunc = nt.ufunc
            ufunc_skipna = nt.ufunc_skipna
            # dtypes = nt.dtypes
            # composable = nt.composable
            # doc = nt.doc_header
            # size_one_unity = nt.size_one_unity

            with np.errstate(over='ignore', under='ignore', divide='ignore'):

                post = util.ufunc_axis_skipna(array=array,
                                              skipna=True,
                                              axis=0,
                                              ufunc=ufunc,
                                              ufunc_skipna=ufunc_skipna)
                if array.ndim == 2:
                    self.assertTrue(post.ndim == 1)
示例#6
0
    def test_isna_array_a(self) -> None:

        a1 = np.array([1, 2, 3])
        a2 = np.array([False, True, False])
        a3 = np.array(['b', 'c', 'd'])
        a4 = np.array([2.3, 3.2])
        a5 = np.array(['test', 'test again'], dtype='S')
        a6 = np.array([2.3, 5.4], dtype='float32')

        self.assertEqual(isna_array(a1).tolist(), [False, False, False])
        self.assertEqual(isna_array(a2).tolist(), [False, False, False])
        self.assertEqual(isna_array(a3).tolist(), [False, False, False])
        self.assertEqual(isna_array(a4).tolist(), [False, False])
        self.assertEqual(isna_array(a5).tolist(), [False, False])
        self.assertEqual(isna_array(a6).tolist(), [False, False])

        a1 = np.array([1, 2, 3, None])
        a2 = np.array([False, True, False, None])
        a3 = np.array(['b', 'c', 'd', None])
        a4 = np.array([2.3, 3.2, None])
        a5 = np.array(['test', 'test again', None])
        a6 = np.array([2.3, 5.4, None])

        self.assertEqual(isna_array(a1).tolist(), [False, False, False, True])
        self.assertEqual(isna_array(a2).tolist(), [False, False, False, True])
        self.assertEqual(isna_array(a3).tolist(), [False, False, False, True])
        self.assertEqual(isna_array(a4).tolist(), [False, False, True])
        self.assertEqual(isna_array(a5).tolist(), [False, False, True])
        self.assertEqual(isna_array(a6).tolist(), [False, False, True])

        a1 = np.array([1, 2, 3, np.nan])
        a2 = np.array([False, True, False, np.nan])
        a3 = np.array(['b', 'c', 'd', np.nan], dtype=object)
        a4 = np.array([2.3, 3.2, np.nan], dtype=object)
        a5 = np.array(['test', 'test again', np.nan], dtype=object)
        a6 = np.array([2.3, 5.4, np.nan], dtype='float32')

        self.assertEqual(isna_array(a1).tolist(), [False, False, False, True])
        self.assertEqual(isna_array(a2).tolist(), [False, False, False, True])
        self.assertEqual(isna_array(a3).tolist(), [False, False, False, True])
        self.assertEqual(isna_array(a4).tolist(), [False, False, True])
        self.assertEqual(isna_array(a5).tolist(), [False, False, True])
        self.assertEqual(isna_array(a6).tolist(), [False, False, True])
示例#7
0
def _ufunc_logical_skipna(array: np.ndarray,
                          ufunc: AnyCallable,
                          skipna: bool,
                          axis: int = 0,
                          out: tp.Optional[np.ndarray] = None) -> np.ndarray:
    '''
    Given a logical (and, or) ufunc that does not support skipna, implement skipna behavior.
    '''
    if ufunc != np.all and ufunc != np.any:
        raise NotImplementedError(
            f'unsupported ufunc ({ufunc}); use np.all or np.any')

    if len(array) == 0:
        # TODO: handle if this is ndim == 2 and has no length
        # any() of an empty array is False
        return ufunc == np.all

    kind = array.dtype.kind

    #---------------------------------------------------------------------------
    # types that cannot have NA
    if kind == 'b':
        return ufunc(array, axis=axis, out=out)
    if kind in DTYPE_INT_KIND:
        return ufunc(array, axis=axis, out=out)
    if kind in DTYPE_STR_KIND:
        # only string in object arrays can be converted to bool, where the empty string will be evaluated as False; here, manually check
        return ufunc(array != '', axis=axis, out=out)

    #---------------------------------------------------------------------------
    # types that can have NA

    if kind in DTYPE_NAN_KIND:
        isna = isna_array(array)
        hasna = isna.any()  # returns single value for 1d, 2d
        if hasna and skipna:
            fill_value = 0.0 if ufunc == np.any else 1.0
            v = array.copy()
            v[isna] = fill_value
            return ufunc(v, axis=axis, out=out)
        elif hasna and not skipna:
            # if array.ndim == 1:
            #     return np.nan
            raise TypeError(
                'cannot propagate NaN without expanding to object array result'
            )
        return ufunc(array, axis=axis, out=out)

    if kind in DTYPE_NAT_KIND:
        isna = isna_array(array)
        hasna = isna.any()  # returns single value for 1d, 2d
        # all dates are truthy, special handling only to propagate NaNs
        if hasna and not skipna:
            # if array.ndim == 1:
            #     return NAT
            raise TypeError(
                'cannot propagate NaN without expanding to object array result'
            )
        # to ignore NaN, simply fall back on all-truth behavior, below

    if kind == 'O':
        # all object types: convert to boolean aray then process
        isna = isna_array(array)
        hasna = isna.any()  # returns single value for 1d, 2d
        if hasna and skipna:
            # supply True for np.all, False for np.any
            fill_value = False if ufunc == np.any else True
            v = array.copy()
            v = v.astype(bool)  # nan will be converted to True
            v[isna] = fill_value
        elif hasna and not skipna:
            # if array.ndim == 1:
            #     return np.nan
            raise TypeError(
                'cannot propagate NaN without expanding to object array result'
            )
        else:
            v = array.astype(bool)
        return ufunc(v, axis=axis, out=out)

    # all types other than strings or objects assume truthy
    if array.ndim == 1:
        return True
    return np.full(array.shape[0 if axis else 1], fill_value=True, dtype=bool)