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]:
In [3]:
# use `[key]` to query the value associated with a key
I['a']
Out[3]:
In [4]:
# use value_cache[value] to get a slicer of keys associated with a value
I.value_cache[1]
Out[4]:
In [5]:
type(I.value_cache[1])
Out[5]:
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]:
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]:
When compared with !=, a negative slicer is created by inverting the results from ==.
In [8]:
S = I!=1
S
Out[8]:
In [9]:
S = I!=J
S
Out[9]:
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]:
In [12]:
S = I >= J
S
Out[12]:
In [13]:
S = I > 2
S
Out[13]:
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]:
In [15]:
I[ I > 2 ]
Out[15]:
In [16]:
I[ I!=2 ]
Out[16]:
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]: