diff --git a/tests/pipeline/test_classifier.py b/tests/pipeline/test_classifier.py new file mode 100644 index 00000000..6e36ce30 --- /dev/null +++ b/tests/pipeline/test_classifier.py @@ -0,0 +1,43 @@ +import numpy as np + +from zipline.pipeline import Classifier, TermGraph +from zipline.testing import check_arrays, parameter_space +from zipline.utils.numpy_utils import int64_dtype + +from .base import BasePipelineTestCase + + +class ClassifierTestCase(BasePipelineTestCase): + + @parameter_space(mv=[-1, 0, 1, 999]) + def test_isnull(self, mv): + + class C(Classifier): + dtype = int64_dtype + missing_value = mv + inputs = () + window_length = 0 + + # There's no significance to the values here other than that they + # contain a mix of missing and non-missing values. + data = np.array([[-1, 1, 0, 2], + [3, 0, 1, 0], + [-5, 0, -1, 0], + [-3, 1, 2, 2]], dtype=int) + + c = C() + graph = TermGraph( + { + 'isnull': c.isnull(), + 'notnull': c.notnull() + } + ) + + results = self.run_graph( + graph, + initial_workspace={c: data}, + mask=self.build_mask(self.ones_mask(shape=data.shape)), + ) + + check_arrays(results['isnull'], (data == mv)) + check_arrays(results['notnull'], (data != mv)) diff --git a/zipline/pipeline/classifiers/classifier.py b/zipline/pipeline/classifiers/classifier.py index 0d6db642..7a584eaa 100644 --- a/zipline/pipeline/classifiers/classifier.py +++ b/zipline/pipeline/classifiers/classifier.py @@ -7,6 +7,7 @@ from zipline.lib.quantiles import quantiles from zipline.pipeline.term import ComputableTerm from zipline.utils.numpy_utils import int64_dtype +from ..filters import NullFilter from ..mixins import ( CustomTermMixin, LatestMixin, @@ -28,6 +29,18 @@ class Classifier(RestrictedDTypeMixin, ComputableTerm): """ ALLOWED_DTYPES = (int64_dtype,) # Used by RestrictedDTypeMixin + def isnull(self): + """ + A Filter producing True for values where this term has missing data. + """ + return NullFilter(self) + + def notnull(self): + """ + A Filter producing True for values where this term has complete data. + """ + return ~self.isnull() + class Everything(Classifier): """