Skip to content

Commit bbf0dda

Browse files
Licht-Tjreback
authored andcommitted
BUG: Add SparseArray.all (#17570)
1 parent 42adf7d commit bbf0dda

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed

doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ Sparse
634634
- Bug in :func:`SparseDataFrame.fillna` not filling all NaNs when frame was instantiated from SciPy sparse matrix (:issue:`16112`)
635635
- Bug in :func:`SparseSeries.unstack` and :func:`SparseDataFrame.stack` (:issue:`16614`, :issue:`15045`)
636636
- Bug in :func:`make_sparse` treating two numeric/boolean data, which have same bits, as same when array ``dtype`` is ``object`` (:issue:`17574`)
637+
- :func:`SparseArray.all` and :func:`SparseArray.any` are now implemented to handle ``SparseArray``, these were used but not implemented (:issue:`17570`)
637638

638639
Reshaping
639640
^^^^^^^^^

pandas/compat/numpy/function.py

+8
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,14 @@ def validate_cum_func_with_skipna(skipna, args, kwargs, name):
184184
return skipna
185185

186186

187+
ALLANY_DEFAULTS = OrderedDict()
188+
ALLANY_DEFAULTS['dtype'] = None
189+
ALLANY_DEFAULTS['out'] = None
190+
validate_all = CompatValidator(ALLANY_DEFAULTS, fname='all',
191+
method='both', max_fname_arg_count=1)
192+
validate_any = CompatValidator(ALLANY_DEFAULTS, fname='any',
193+
method='both', max_fname_arg_count=1)
194+
187195
LOGICAL_FUNC_DEFAULTS = dict(out=None)
188196
validate_logical_func = CompatValidator(LOGICAL_FUNC_DEFAULTS, method='kwargs')
189197

pandas/core/sparse/array.py

+42
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,48 @@ def fillna(self, value, downcast=None):
615615
return self._simple_new(new_values, self.sp_index,
616616
fill_value=fill_value)
617617

618+
def all(self, axis=0, *args, **kwargs):
619+
"""
620+
Tests whether all elements evaluate True
621+
622+
Returns
623+
-------
624+
all : bool
625+
626+
See Also
627+
--------
628+
numpy.all
629+
"""
630+
nv.validate_all(args, kwargs)
631+
632+
values = self.sp_values
633+
634+
if len(values) != len(self) and not np.all(self.fill_value):
635+
return False
636+
637+
return values.all()
638+
639+
def any(self, axis=0, *args, **kwargs):
640+
"""
641+
Tests whether at least one of elements evaluate True
642+
643+
Returns
644+
-------
645+
any : bool
646+
647+
See Also
648+
--------
649+
numpy.any
650+
"""
651+
nv.validate_any(args, kwargs)
652+
653+
values = self.sp_values
654+
655+
if len(values) != len(self) and np.any(self.fill_value):
656+
return True
657+
658+
return values.any()
659+
618660
def sum(self, axis=0, *args, **kwargs):
619661
"""
620662
Sum of non-NA/null values

pandas/tests/sparse/test_array.py

+88
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,94 @@ def test_fillna_overlap(self):
664664

665665
class TestSparseArrayAnalytics(object):
666666

667+
@pytest.mark.parametrize('data,pos,neg', [
668+
([True, True, True], True, False),
669+
([1, 2, 1], 1, 0),
670+
([1.0, 2.0, 1.0], 1.0, 0.0)
671+
])
672+
def test_all(self, data, pos, neg):
673+
# GH 17570
674+
out = SparseArray(data).all()
675+
assert out
676+
677+
out = SparseArray(data, fill_value=pos).all()
678+
assert out
679+
680+
data[1] = neg
681+
out = SparseArray(data).all()
682+
assert not out
683+
684+
out = SparseArray(data, fill_value=pos).all()
685+
assert not out
686+
687+
@pytest.mark.parametrize('data,pos,neg', [
688+
([True, True, True], True, False),
689+
([1, 2, 1], 1, 0),
690+
([1.0, 2.0, 1.0], 1.0, 0.0)
691+
])
692+
def test_numpy_all(self, data, pos, neg):
693+
# GH 17570
694+
out = np.all(SparseArray(data))
695+
assert out
696+
697+
out = np.all(SparseArray(data, fill_value=pos))
698+
assert out
699+
700+
data[1] = neg
701+
out = np.all(SparseArray(data))
702+
assert not out
703+
704+
out = np.all(SparseArray(data, fill_value=pos))
705+
assert not out
706+
707+
msg = "the 'out' parameter is not supported"
708+
tm.assert_raises_regex(ValueError, msg, np.all,
709+
SparseArray(data), out=out)
710+
711+
@pytest.mark.parametrize('data,pos,neg', [
712+
([False, True, False], True, False),
713+
([0, 2, 0], 2, 0),
714+
([0.0, 2.0, 0.0], 2.0, 0.0)
715+
])
716+
def test_any(self, data, pos, neg):
717+
# GH 17570
718+
out = SparseArray(data).any()
719+
assert out
720+
721+
out = SparseArray(data, fill_value=pos).any()
722+
assert out
723+
724+
data[1] = neg
725+
out = SparseArray(data).any()
726+
assert not out
727+
728+
out = SparseArray(data, fill_value=pos).any()
729+
assert not out
730+
731+
@pytest.mark.parametrize('data,pos,neg', [
732+
([False, True, False], True, False),
733+
([0, 2, 0], 2, 0),
734+
([0.0, 2.0, 0.0], 2.0, 0.0)
735+
])
736+
def test_numpy_any(self, data, pos, neg):
737+
# GH 17570
738+
out = np.any(SparseArray(data))
739+
assert out
740+
741+
out = np.any(SparseArray(data, fill_value=pos))
742+
assert out
743+
744+
data[1] = neg
745+
out = np.any(SparseArray(data))
746+
assert not out
747+
748+
out = np.any(SparseArray(data, fill_value=pos))
749+
assert not out
750+
751+
msg = "the 'out' parameter is not supported"
752+
tm.assert_raises_regex(ValueError, msg, np.any,
753+
SparseArray(data), out=out)
754+
667755
def test_sum(self):
668756
data = np.arange(10).astype(float)
669757
out = SparseArray(data).sum()

0 commit comments

Comments
 (0)