Indexing

A wc_rules.indexer.Indexer object is essentially a hashmap of keys (literals or namedtuples) to values of a particular type. Types of indexers include BooleanIndexer, NumericIndexer, StringIndexer, etc. Additionally, it maintains a reverse map from values to keys using slicers.

The most powerful use of indexers is to simultaneously filter and perform comparisons.


In [1]:
from wc_rules.indexer import NumericIndexer

In [2]:
# initialize
I = NumericIndexer()
# update using dict objects or other indexers of the same type.
I.update(dict(a=1,b=1,c=2))


Out[2]:
{'a': 1, 'b': 1, 'c': 2}

In [3]:
# use `[key]` to query the value associated with a key
I['a']


Out[3]:
1

In [4]:
# use value_cache[value] to get a slicer of keys associated with a value
I.value_cache[1]


Out[4]:
{'a': True, 'b': True}

In [5]:
type(I.value_cache[1])


Out[5]:
wc_rules.indexer.Slicer

Filtering by Comparison

When an indexer is compared with ==, it creates a slice of keys whose values satisfy that equality.


In [6]:
I = NumericIndexer().update(dict(a=1,b=1,c=2))
S = I==1
S


Out[6]:
{'b': True, 'a': True}

When an indexer is compared with another indexer, it creates a slice of keys common to both indexers whose values match.


In [7]:
J = NumericIndexer().update(dict(a=1,b=1,c=3))
S = I==J
S


Out[7]:
{'b': True, 'a': True}

When compared with !=, a negative slicer is created by inverting the results from ==.


In [8]:
S = I!=1
S


Out[8]:
{'b': False, 'a': False}

In [9]:
S = I!=J
S


Out[9]:
{'b': False, 'a': False}

Numeric indexers can be compared using numeric comparison operators also, such as >,>=,<,<=. A slicer object is returned.


In [10]:
I = NumericIndexer().update(dict(a=1,b=2,c=3,d=4))
J = NumericIndexer().update(dict(a=1,b=1,c=2,d=5))

In [11]:
S = I < J
S


Out[11]:
{'d': True}

In [12]:
S = I >= J
S


Out[12]:
{'c': True, 'b': True, 'a': True}

In [13]:
S = I > 2
S


Out[13]:
{'d': True, 'c': True}

Subsetting

A subset of an indexer can be generated by passing a slicer to [].


In [14]:
I = NumericIndexer().update(dict(a=1,b=2,c=3,d=4))
S = I > 2
I[S]


Out[14]:
{'c': 3, 'd': 4}

In [15]:
I[ I > 2 ]


Out[15]:
{'c': 3, 'd': 4}

In [16]:
I[ I!=2 ]


Out[16]:
{'a': 1, 'c': 3, 'd': 4}

Since slicers can be combined using Boolean AND, OR and NOT, one can perform complicated slicing and subsetting.


In [17]:
I[ (I>2) & (I<4) ]


Out[17]:
{'c': 3}