diff --git a/.gitignore b/.gitignore index 0bd31ff95..589230564 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,13 @@ doc/notebooks/.ipynb_checkpoints +doc/source/_generated/ doc/build/ -.idea +experiments/ +build/ +dist/ +.ipynb_checkpoints/ +.cache/ +.eggs/ +.idea/ *.pyc *.pyd -larray.egg-info \ No newline at end of file +*.egg-info diff --git a/.travis.yml b/.travis.yml index 354453d56..8c412503d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,8 @@ language: python python: - "2.7" - - "3.4" - "3.5" + - "3.6" branches: only: @@ -28,6 +28,7 @@ before_install: - bash miniconda.sh -b -p $HOME/miniconda - export PATH="$HOME/miniconda/bin:$PATH" - hash -r + - conda config --add channels conda-forge - conda config --set always_yes yes --set changeps1 no - conda update -q conda @@ -45,17 +46,16 @@ install: # might want to avoid the later by installing all dependencies manually # except scipy and install pandas with --no-deps - conda create -n travisci --yes python=${TRAVIS_PYTHON_VERSION:0:3} - numpy pandas pytables pyqt matplotlib xlrd openpyxl xlsxwriter nose + numpy pandas pytables pyqt qtpy matplotlib xlrd openpyxl + xlsxwriter pytest pytest-pep8 - source activate travisci script: - # exclude (doc)tests from ufuncs (because docstrings are copied from numpy - # and many of those doctests are failing - - nosetests -v --with-doctest --exclude=larray.ufuncs + - pytest notifications: on_success: "change" on_failure: "always" # use container-based infrastructure -sudo: false \ No newline at end of file +sudo: false diff --git a/README.rst b/README.rst index d644ef6ad..ec9ffa48d 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,157 @@ -larray -====== +LArray: N-dimensional labelled arrays +===================================== -larray provides a Labelled Array class +|build-status| |docs| -.. image:: https://travis-ci.org/liam2/larray.svg?branch=master - :target: https://travis-ci.org/liam2/larray +.. _start-intro: + +LArray is open source Python library that aims to provide tools for easy exploration and manipulation of +N-dimensional labelled data structures. + +Library Highlights +------------------ + +* N-dimensional labelled array objects to store and manipulate multi-dimensional data + +* I/O functions for reading and writing arrays in different formats: + CSV, Microsoft Excel, HDF5, pickle + +* Arrays can be grouped into Session objects and loaded/dumped at once + +* User interface with an IPython console for rapid exploration of data + +* Compatible with the pandas library: LArray objects can be converted into pandas DataFrame and vice versa. + +.. _start-install: + +Installation +============ + +Pre-built binaries +------------------ + +The easiest route to installing larray is through +`Conda `_. +For all platforms installing larray can be done with:: + + conda install -c gdementen larray + +This will install a lightweight version of larray +depending only on Numpy and Pandas libraries only. +Additional libraries are required to use the included +graphical user interface, make plots or use special +I/O functions for easy dump/load from Excel or +HDF files. Optional dependencies are described +below. + +Installing larray with all optional dependencies +can be done with :: + + conda install -c gdementen larrayenv + +You can also first add the channel `gdementen` to +your channel list :: + + conda config --add channels gdementen + +and then install larray (or larrayenv) as :: + + conda install larray + + +Building from source +-------------------- + +The latest release of LArray is available from +https://github.com/larray-project/larray.git + +Once you have satisfied the requirements detailed below, simply run:: + + python setup.py install + + +Required Dependencies +--------------------- + +- Python 2.7, 3.4, 3.5, or 3.6 +- `numpy `__ (1.10.0 or later) +- `pandas `__ (0.13.1 or later) + + +Optional Dependencies +--------------------- + +For IO (HDF, Excel) +~~~~~~~~~~~~~~~~~~~ + +- `pytables `__: + for working with files in HDF5 format. +- `xlrd `__: + for reading data and formatting information from older Excel files (ie: .xls) +- `openpyxl `__: + recommended package for reading and writing + Excel 2010 files (ie: .xlsx) +- `xlsxwriter `__: + alternative package for writing data, formatting + information and, in particular, charts in the + Excel 2010 format (ie: .xlsx) +- `larray_eurostat `__: + provides functions to easily download EUROSTAT files as larray objects. + Currently limited to TSV files. + +.. _start-dependencies-gui: + +For Graphical User Interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +LArray includes a graphical user interface to view, edit and compare arrays. + +- `pyqt `__ (4 or 5): + required by `larray-editor` (see below). +- `pyside `__: + alternative to PyQt. +- `qtpy `__: + required by `larray-editor`. + Provides support for PyQt5, PyQt4 and PySide using the PyQt5 layout. +- `larray-editor `__: + required to use the graphical user interface associated with larray. + It assumes that `qtpy` and `pyqt` or `pyside` are installed. + On windows, creates also a menu ``LArray`` in the Windows Start Menu. + +For plotting +~~~~~~~~~~~~ + +- `matplotlib `__: + required for plotting. + +.. _start-documentation: + +Documentation +============= + +The official documentation is hosted on ReadTheDocs at http://larray.readthedocs.io/en/stable/ + +.. _start-get-in-touch: + +Get in touch +============ + +- To be informed of each new release, please subscribe to the announce `mailing list`_. +- For questions, ideas or general discussion, please use the `Google Users Group`_. +- To report bugs, suggest features or view the source code, please go to our `GitHub website`_. + +.. _mailing list: https://groups.google.com/d/forum/larray-announce +.. _Google Users Group: https://groups.google.com/d/forum/larray-users +.. _GitHub website: http://github.com/larray-project/larray + +.. end-readme-file + +.. |build-status| image:: https://travis-ci.org/larray-project/larray.svg?branch=master + :alt: build status + :scale: 100% + :target: https://travis-ci.org/larray-project/larray + +.. |docs| image:: https://readthedocs.org/projects/larray/badge/?version=stable + :alt: Documentation Status + :scale: 100% + :target: https://larray.readthedocs.io/en/latest/?badge=stable diff --git a/binder/environment.yml b/binder/environment.yml new file mode 100644 index 000000000..b15f592c8 --- /dev/null +++ b/binder/environment.yml @@ -0,0 +1,13 @@ +name: larray-binder +channels: + - damianavila82 # rise + - conda-forge + - defaults +dependencies: + - numpy + - pandas + - matplotlib + - pytables + - bokeh + - rise + - larray diff --git a/condarecipe/larray/bld.bat b/condarecipe/larray/bld.bat index 87b1481d7..cf4f34d8e 100644 --- a/condarecipe/larray/bld.bat +++ b/condarecipe/larray/bld.bat @@ -1,6 +1,5 @@ "%PYTHON%" setup.py install if errorlevel 1 exit 1 - :: Add more build steps here, if they are necessary. :: See diff --git a/condarecipe/larray/meta.yaml b/condarecipe/larray/meta.yaml index 764191cf1..3fe795002 100644 --- a/condarecipe/larray/meta.yaml +++ b/condarecipe/larray/meta.yaml @@ -1,10 +1,10 @@ package: name: larray - version: 0.12 + version: 0.28 source: - git_tag: 0.12 - git_url: https://github.com/liam2/larray.git + git_tag: 0.28 + git_url: https://github.com/larray-project/larray.git # git_tag: master # git_url: file://c:/Users/gdm/devel/larray/.git @@ -18,17 +18,26 @@ requirements: - python - setuptools - numpy >=1.10 - - pandas + - pandas >=0.13.1 + - pytest-runner run: - python - numpy >=1.10 - - pandas + - pandas >=0.13.1 + - pytest-runner test: +# requires: +# - pytest +# - pytest-runner + imports: - larray +# commands: +# - pytest + # commands: # You can put test commands to be run here. Use this to test that the # entry points work. @@ -41,7 +50,7 @@ test: # - nose about: - home: http://github.com/liam2/larray + home: http://github.com/larray-project/larray license: GPL summary: "Labeled N-dimensional array." diff --git a/design.txt b/design.txt new file mode 100644 index 000000000..3bd221c9d --- /dev/null +++ b/design.txt @@ -0,0 +1,1058 @@ + +a(sex, age) +age_limit(sex) + +step 1: + +a[age > age_limit] +a[age + clength < age_limit] +b = a * (age > age_limit) + +step 2: + +a[x.age > age_limit] +# this is also possible ("x.age > age_limit" return an Expr, expr is evaluated +# during the binop (axes ref replace by real axe) +b = a * (x.age > age_limit) + +============== +in general: +1) match axes by Axis object => No axis.id because we need to be able to share + the same axis in several collections/arrays. + => this is slightly annoying for Group.__repr__ which uses axis.id + => we cannot have twice the same axis object in a collection + (we can have the same name twice though) +2) match axes by name if any, by position otherwise +3) match axes by position +""" +# TODO +# * axes with no name should display as (or even have their name assigned to?) +# their position. Assigning does not work because after aggregating axis 0, +# we get the first axis named "1" which is a no-go. +# it would be much easier to have a .id attribute/property on axis with +# either the name or position in it, but this requires that axes know about +# their AxisCollection. id might not be defined when axis is not attached +# to a Collection + +# * add check there is no duplicate label in axes! + +# * for NDGroups, we have two options: cross product or intersection. +# Technically, this is easy, we just need to store a boolean and in getitem +# act accordingly (use ix_ or not), but what is the best API for users? +# a different class or a flag? In fact, the same question applies to +# positional vs label (in total, we got 4 different possibilities). + +# ? how do you combine a cross-product group with an intersection group? +# a[cpgroup, igroup] +# -> no problem if they are on different dimensions: the igroup +# dimension(s) are collapsed into one, pgroup dimension(s) stay. +# The index need to be constructed carefully, but it can be done. See +# np_indexing.py +# -> if they are on the same dimensions, we have two options: +# * apply one then the other (left to right) +# * fail <-- I think this is safer at least to implement. One after the +# other can still be achieved by a[pgroup][igroup] + +# API for ND groups (my example is mixing label with positional): + +# union (bands): x.axis1[5:10] | x.axis2.i[3:4] +# intersection/cross/default: x.axis1[5:10] & x.axis2.i[3:4] +# points: x.axis1[5:10] ^ x.axis2.i[1:6] +# ----> this prevents symetric difference. this is little used but... +# ----> Points(x.axis[5:10], x.axis2.i[1:6]) + +# this is very nice and would have orderedset-like semantics + +# it does not seem to conflict with the axis methods (even though that might be +# confusing): + +# x.axis1 | x.axis2 would have a very different meaning than +# x.axis1[:] | x.axis2[:] + +# Note that cross sections is the default and it is useless to introduce +# another API **except to give a name**, so the & syntax is useless unless +# we allow naming groups after the fact + +# => NDGroup((x.axis1[5:10], x.axis2.i[2.5]), 'exports') +# => Group((x.axis1[5:10], x.axis2.i[2.5]), 'exports') +# => (x.axis1[5:10] & x.axis2.i[2.5]).named('exports') + +# generalizing "named" and suppressing .group seems like a good idea! +# => x.axis1.group([5, 7, 10], name='brussels') +# => x.axis1[5, 7, 10].named('brussels') + +# http://xarray.pydata.org/en/stable/indexing.html#pointwise-indexing +# http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.lookup.html#pandas.DataFrame.lookup + +# I think I would go for +# ARRAY.points[dim0_labels, ..., dimX_labels] +# and +# ARRAY.ipoints[dim0_indices, ..., dimX_indices] +# so that we can have a symmetrical API for get and set. + +# I wonder if, for axes subscripting, I could not allow tuples as sequences, +# which would make it a bit nicer: +# x.axis1[5, 7, 10].named('brussels') +# instead of +# x.axis1[[5, 7, 10]].named('brussels') +# since axes are always 1D, this is not a direct problem. However the +# question is whether this would lead to an inconsistent API/confuse users +# because they would still have to write the brackets when no axis is present +# a[[5, 7, 9]] +# a[x.axis1[5, 7, 9]] +# in practice, this syntax is little used anyway + +# options + +# 1) multiple range in same [] create multiple groups +# ===================================================== + +# G.age[5, 7, 9] == G.age[5], G.age[7], G.age[9] +# G.age[:9, 10:14, 15:25] == G.age[:9], G.age[10:14], G.age[15:25] +# G[2:7, 'M', ['P01', 'P05']] == G[2:7], G['M'], G['P01', 'PO5'] +# a[G[2:7, 'M', ['P01', 'P05']]] == a[2:7, 'M', ['P01', 'P05']] +# a[G[2:7, 'M', ['P01', 'P05']]] == a[2:7, 'M', ['P01', 'P05']] +# a[G[5, 7, 9]] == a[5, 7, 9] => key has several values for axis: age +# a[G[[5, 7, 9]]] == a[[5, 7, 9]] +# a[G.union[5, 7, 9]] == a[[5, 7, 9]] +# a[G.union[5, 7:10, 12]] == a[[5, 7, 8, 9, 10, 12]] + +# a[G.age[2:7, 5:10], 'M', ['P01', 'P05']]] +# == a[2:7, 5:10, 'M', ['P01', 'P05']] +# OR rather +# == a[(G[2:7], G[5:10]), 'M', ['P01', 'P05']] +# == a[2:7, 'M', ['P01', 'P05']], a[5:10, 'M', ['P01', 'P05']] +# OR? +# == larray +# age 2:7 5:10 +# a[2:7, 'M', ['P01', 'P05']] a[5:10, 'M', ['P01', 'P05']] +# OR? +# == larray with 4 dim (age_group, age, sex, lipro) +# this would currently only work if the slices have the same size, +# but with pandas/MI, this could work even when the slices are different + +# a[G[2:7, 5:10, 'M', 'F']] <---- should this be supported? (I think so +# for first step (split in individual +# groups) but fail in a[] +# == a[G[2:7], G[5:10], G['M'], G['F']] +# == a[2:7, 5:10, 'M', 'F'] +# == a[2:7, 'M'], a[2:7, 'F'], a[5:10, 'M'], a[5:10, 'F'] +# +# or return an larray? + +# 2:7 5:10 +# M a[2:7, 'M'] a[5:10, 'M'] +# F a[2:7, 'F'] a[5:10, 'F'] + +# a[G[2:7, 5:10], G['M', 'F']]] +# == a[(G[2:7], G[5:10]), (G['M'], G['F'])] +# == [(a[2:7], a[5:10]), (a['M'], a['F'])] + +# a[G[2:7, 5:10] & G['M', 'F']]] +# == a[G[2:7] & G['M'], G[5:10] & G['M'], G[2:7] & G['F'], G[5:10] & G['F']] +# OR +# == a[G[2:7] & G['M'], G[2:7] & G['F'], G[5:10] & G['M'], G[5:10] & G['F']] + +# a[(G[2:7], 'M'), (G[2:7], 'F'), (G[5:10], 'M'), (G[5:10], 'F')] = \ +# [ 1, 2, 3, 4] + +# a[G[2:7, 'M'], G[2:7, 'F'], G[5:10, 'M'], G[5:10, 'F']] = \ +# [ 1, 2, 3, 4] + +# == + +# a[(G[2: 7], G['M']), (G[2: 7], G['F']), + (G[5:10], G['M']), (G[5:10], G['F'])] = \ +# [ 1, 2, +# 3, 4] + +# == + +# a[[(G[2: 7], G['M']), (G[2: 7], G['F']), + (G[5:10], G['M']), (G[5:10], G['F'])]] = \ +# [ 1, 2, +# 3, 4] + +# == + +# a[[(G[2: 7], G['M']), (G[2: 7], G['F']), + (G[5:10], G['M']), (G[5:10], G['F'])]] = \ +# [ 1, 2, +# 3, 4] + +indexing: le dernier niveau (inner-most) => &, +les autres niveaux créent un larray de larrays + +# a[[(G[2: 7], G['M']), (G[2: 7], G['F']), + (G[5:10], G['M']), (G[5:10], G['F'])]] + == LArray([a[2:7 & 'M'], a[2:7 & 'F'], a[5:10 & 'M'], a[5:10 & 'F']]) + +# mais si scalaires au lieu de slices, on pourrait s'attendre à un larray au +lieu de larray de larrays + a[(G[2], G['M']), (G[2], G['F']), (G[5], G['M']), (G[5], G['F'])] + == LArray([a[2, 'M'], a[2, 'F'], a[5, 'M'], a[5, 'F']]) + mais si on veut ça, il suffit de faire: + + a[G[[2, 5]], G[['M', 'F']]] + +reste à savoir si on veut que G splitte les tuples de scalaires: + + a[G[2, 5:10], G['M', 'F']] + == a[G[(2, 5:10)], G[('M', 'F'])] + == a[G[(2, 5:10)], G[('M', 'F'])] + + == a[G[[2, 5]], G[['M', 'F']]] (== a[[2, 5], ['M', 'F']]) + OU + == a[(G[2], G[5]), (G['M'], G['F'])] (== [[a[2], a[5]], [a['M'], a['F']]) + ce qui revient à dire que tuple split et pas list + +ou alors on utilise une méthode spécifique pour split (split ou groups ou +multi): + +G.split[2, 5] == G[2], G[5] +G.clength.split[2, 5:10, 20] == G.clength[2], G.clength[5:10], G.clength[5] +G.clength.split[2, 5] == G.clength[2], G.clength[5] + + +# a[[(G[2: 7], G['M']), (G[2: 7], G['F']), + (G[5:10], G['M']), (G[5:10], G['F'])]] = + + +# a[2:7, 'M'] = 1 +# a[2:7, 'F'] = 2 +# a[5:10, 'M'] = 3 +# a[5:10, 'F'] = 4 + +# a[2:7, 5:10, 'M', 'F'] = [1, 2, 3, 4] + +# multi assignment use case + +# a[:] = {(G[2:7], 'M'): 1, +# (G[2:7], 'F'): 2, +# (G[5:10], 'M'): 3, +# (G[5:10], 'F'): 4} + +# a.update({(G[2:7], 'M'): 1, +# (G[2:7], 'F'): 2, +# (G[5:10], 'M'): 3, +# (G[5:10], 'F'): 4}) + +# a.update({(G.age[2:7], 'M'): 1, +# (G.age[2:7], 'F'): 2, +# (G.age[5:10], 'M'): 3, +# (G.age[5:10], 'F'): 4}) + +# a[:] = [(G[2:7], 'M'), 1, +# (G[2:7], 'F'), 2, +# (G[5:10], 'M'), 3, +# (G[5:10], 'F'), 4] + +# a[:] = {G[2:7, 'M']: 1, +# G[2:7, 'F']: 2, +# G[5:10, 'M']: 3, +# G[5:10, 'F']: 4} + +# a.update({G[2:7, 'M']: 1, +# G[2:7, 'F']: 2, +# G[5:10, 'M']: 3, +# G[5:10, 'F']: 4}) + +# >>>> the goals are to avoid repeating the axes names if ambiguous and the +# array name but have the values as close to the labels as possible (assign by +# position does not scale) + +# same problem for LArray contructor BTW +# m = LArray([[1, 2], +# [3, 4]], axes=[Axis('age', R[2:7]), Axis('sex', 'M,F')]) +# +# minr_replica = LArray([[0.20, 0.57], [0.46, 0.65]], +# [Axis('sex', ['men', 'women']), +# Axis('stat', ['benef_tot', 'prop_carr'])]) +# +# minr_replica = [('men', 'benef_tot'), 0.20, +# ('women', 'benef_tot'), 0.57, +# ('men', 'prop_carr'), 0.46, +# ('women', 'prop_carr'), 0.65], +# ('sex', 'stat') +# +# benef_tot = [('men', 0.20), ('women', 0.57)] +# prop_carr = [('men', 0.46), ('women', 0.65)] +# minr_replica = ('benef_tot', benef_tot), ('prop_carr', prop_carr) + +# hierarchical ordered "dict" (compact & readable but hard to write because of +# punctuation overload) +# minr_replica = [('benef_tot', [('men', 0.20), ('women', 0.57)]) +# ('prop_carr', [('men', 0.46), ('women', 0.65)])] + +# 3.6+ (nice but only string labels) +# minr_replica = od(benef_tot=od(men=0.20, women=0.57), +# prop_carr=od(men=0.46, women=0.65)) + + +# benef_tot = [('men', 0.20), ('women', 0.57)] +# prop_carr = [('men', 0.46), ('women', 0.65)] +# minr_replica = ('benef_tot', benef_tot), ('prop_carr', prop_carr) +# +# minr_replica = ('benef_tot', benef_tot), ('prop_carr', prop_carr) + +# men women +# minr_replica= la([[0.20, 0.57], # benef_tot +# [0.46, 0.65]], # prop_carr +# [Axis('sex', 'men,women'), +# Axis('stat', 'benef_tot,prop_carr')]) + +# minr_replica= la(['stat', 'sex'], ['men', 'women'], +# 'benef_tot', [ 0.20, 0.57], +# 'prop_carr', [ 0.46, 0.65]) + +# minr_replica = fromlists(['stat \ sex', 'men', 'women'], +# ['benef_tot', 0.20, 0.57], +# ['prop_carr', 0.46, 0.65]) + +# minr_replica = fromlists([['stat', 'sex'], 'men', 'women'], +# ['benef_tot', 0.20, 0.57], +# ['prop_carr', 0.46, 0.65]) + +# minr_replica = fromtuples([( 'stat', 'sex', 'value') +# ('benef_tot', 'men', 0.20), +# ('benef_tot', 'women', 0.57), +# ('prop_carr', 'men', 0.46), +# ('prop_carr', 'women', 0.65)]) + +# benef_tot = fromlists(['sex', 'men', 'women'], +# ['', 0.20, 0.57]) + +# benef_tot = fromtuples([( 'sex', 'value') +# ( 'men', 0.20), +# ('women', 0.57)]) + +# benef_tot = fromlists(['sex', 'men', 'women'], +# [None, 0.20, 0.57]) + +# benef_tot = fromlists(['sex', 'men', 'women'], +# [ 0.20, 0.57]) + +# benef_tot = fromtuples([('men', 0.20), ('women', 0.57)], header=False) + +# discourage this because we do not know order of ticks of sex +# for zeros, full, ones, etc. it's fine (and encouraged) to reuse axes ! +# benef_tot = LArray([0.20, 0.57], [sex]) + +# in xarray uses: + +# foo = xr.DataArray(data, coords=[times, locs], dims=['time', 'space']) + +# foo = xr.DataArray(data, [('x', ['a', 'b']), +# ('y', [-2, 0, 2])]) + +# m = {G[2:7, 'M']: 1, G[2:7, 'F']: 2, G[5:10, 'M']: 3, G[5:10, 'F']: 4} +# breaks if combination of axes +# a.set(x.age[m]) + +2) multiple range in same [] means "and" +========================================= + => set op if same axis, ND group otherwise + + G.age[5, 7, 9] == G.age[5] & G.age[7] & G.age[9] => BREAKS ! + => must use G.age[[5, 7, 9]] + + G.age[:20, 10:30] == G.age[:20] & G.age[10:30] == G.age[20:30] + G[2:7, 'M', ['P01', 'P05']] == G[2:7] & G['M'] & G['P01', 'PO5'] + +3) multiple range in same [] means "or" +======================================== + => set op if same axis, ND group otherwise + + G.age[5, 7, 9] == G.age[5] | G.age[7] | G.age[9] + G.age[:20, 10:30] == G.age[:20] | G.age[10:30] == G.age[10:30] + G[2:7, 'M', ['P01', 'P05']] == G[2:7] | G['M'] | G['P01', 'PO5'] + the ND variant is a bit silly (it is so rarely needed) + +4) multiple range in same [] creates multiple groups except when there are + only scalars +=========================================================================== + => set op if same axis, ND group otherwise + + G.age[5, 7, 11] == G.age[[5, 7, 9]] + G.age[5, 7:9, 11] == G.age[5], G.age[7:9], G.age[11] + G.age[:20, 10:30] == G.age[:20], G.age[10:30] + G.age[5, 10, 15:20, 25:30] == G.age[5], G.age[10], G.age[15:20], G.age[25:30] + G.age[5, 10, :20, 10:30] == G.age[:20], G.age[10:30] + G[2:7, 'M', ['P01', 'P05']] == G[2:7], G['M'], G['P01', 'PO5'] + +5) multiple range in same [] means "or" for same axis / "and" for other axis +============================================================================= + => set op if same axis, ND group otherwise + + G.age[5, 7, 11] == G.age[5] | G.age[7] | G.age[9] + G.age[5, 7:9, 11] == G.age[5] | G.age[7:9] | G.age[11] + G.age[:20, 10:30] == G.age[:20] | G.age[10:30] == G.age[:30] + G[5, 7:9, 'M', ['P01', 'P05']] + == (G.age[5] | G.age[7:9]) & G.sex['M'] & G.lipro[['P01', 'PO5']] + +6) some other combination: doing different stuff whether same axis or not, + or whether slice or scalar +=========================================================================== + + +# use cases + +# 1) simple get/set + +a[2:7, 'M', ['P01', 'P02']] + +# 2) boolean selection + +a[(x.age < 10) | (x.clength > 5)] + +# 3) simple with ambiguous values + +a[G.age[2:7], G.clength[5, 7, 9], 'M', ['P01', 'P02']] + +# 4) point-selection + +a[G.age[2:4] ^ G.clength[5, 7, 9], 'M', ['P01', 'P02']] +a[G[2, 9, 3] ^ G['M', 'F', 'M'], ['P01', 'P02']] + +# 4b) lookup (this is a form of point-selection), wh potentially repeated values +person_age = [5, 1, 2, 1, 6, 5] +person_gender = ['M', 'F', 'F', 'M', 'M', 'F'] +person_workstate = [1, 3, 1, 2, 1, 3] +income = mean_income[person_age, person_gender] # <-- no ! does cross product +income = mean_income[G[person_age] ^ G[person_gender]] +income = mean_income[G.points[person_age, person_gender]] # <-- disallow having + # an axis named + # "points" +income = mean_income.points[person_age, person_gender] +# if ambiguous +income = mean_income.points[G.age[person_age], person_gender] + +# 4c) lookup with larger than axis keys + +# 4d) lookup with boolean keys + +TODO, especially versus set ops on group + +income = mean_income[G[person_age] ^ ~G[person_gender]] + +# this would fail because & does set-op, ie will most likely return "False, True" +income = extra_income[G[person_gender] & (G[workstate] == 1)] # <-- fails +# one potential solution might be to introduce yet another concept: G/LG +# could be renamed to (or presented explicitly as) LabelSet. In that case, it +# would make it obvious (for me ;-)) that using that for the "lookup" usecase +# does not fly. + +# now, how would we name the "other concept" in here? LabelGroup? LabelKey? +income = extra_income[LK[person_gender] & (LK[workstate] == 1)] + +# Q: maybe I don't need an extra concept anyway, just use 1D larray instead? +# A: We do need it, because the values, even if given as larray can be +# ambiguous (valid on several axes) + +# Q: maybe we could introduce a different array class "LookupArray" whicb does +# .points by default. +# A: yes, that's an option but would not solve the "set" problem. + +# => I NEED a way to set the axis on an LKey. maybe x.abc[LK] should not +# return an LSet? but an LKey with an axis. + + +# Q: maybe I could solve the boolop/set problem depending on what is inside the +# LGroup (v1): +# 1) scalars, slices, list: set op +# 2) larray: defer op to it (=> element-wise bool op) +# A: set op on list of bools or scalar bools does not make much sense + +# Q: maybe I could solve the boolop/set problem depending on what is inside the +# LGroup (v2): +# 1) non bool stuff (scalars, slices, list, larray, ...): set op +# 2) bool stuff (scalar, list of bools, larray of bools: bool op +# A: + + +# 5) import-export, a single group on several dimensions +dom = (ARRV[nutsbe] & ARRA[nutsbe]).named('dom') +berow = (ARRV[nutsbe] & ARRA[nutsrow]).named('berow') +rowbe = (ARRV[nutsrow] & ARRA[nutsbe]).named('rowbe') +transit = (ARRV[nutsrow] & ARRA[nutsrow]).named('transit') +# we could define act, like this (but that should not be required, as the +# coupling is looser if we can do it manually): +act = Axis('act', (dom, berow, rowbe, transit)) +act2 = (dom, berow, rowbe, transit) +AGGTON = stack([TON2.sum(nutsbe, nutsbe), TON2.sum(nutsbe, nutsrow), + TON2.sum(nutsrow, nutsbe), TON2.sum(nutsrow, nutsrow)], + ["dom", "berow", "rowbe", "transit"], "act") +AGGTON = TON2.sum((dom, berow, rowbe, transit)).rename('ARRV,ARRA', 'act') +AGGTON = TON2.sum(act=(dom, berow, rowbe, transit)) +AGGTON = TON2.sum(act=act) +AGGTON = TON2.sum(act) # <--- this is obviously the shortest but I am unsure +# its a good idea. On one hand, I dislike the fact that in act2 above, we +# cannot name the resulting axis, but on the other hand, summing on an axis +# not present in the original array, and which is created rather than +# aggregated seems weird at best. It's only after inspecting said axis that we +# can tell that it contains groups on axes which +# are present. +# in the 1D case this is usually not a problem since it is usually fine to have +# maybe doing: +act3 = stack([('dom', dom), ('berow', berow), ('rowbe', rowbe), + ('transit', transit)], 'act') +AGGTON = TON2.sum(act3) # <--- I think this makes a lot of sense, and could +# potentially be useful with arrays > 1D: you could e.g. create 2 dimensions +# out of 1: assuming an age axis +act3 = fromlist(['sub \ 40+', '-39', '40+'], + [ 0, G[ : 9], G[40:49]], + [ 1, G[10:19], G[50:59]], + [ 2, G[20:29], G[60:69]], + [ 3, G[30:39], G[70:79]]) + +act3 = table(['sub', '40+'], [ '-39', '40+'], + [ 0, G[ : 9], G[40:49]], + [ 1, G[10:19], G[50:59]], + [ 2, G[20:29], G[60:69]], + [ 3, G[30:39], G[70:79]]) + +act3 = table(['sub', '40+', '-39', '40+'], + [ 0, G[ : 9], G[40:49]], + [ 1, G[10:19], G[50:59]], + [ 2, G[20:29], G[60:69]], + [ 3, G[30:39], G[70:79]]) +.sum(act3) + +# 6) multi slices, aggregate (one group per slice) + +# groups = (x.clength[1:15], x.clength[16:25], x.clength[26:30], +# x.clength[31:35], x.clength[36:40], x.clength[41:50]) +# agg = arr.sum(groups) + +# groups = G.clength[1:15, 16:25, 26:30, 31:35, 36:40, 41:50] +# agg = arr.sum(groups) + +# agg = arr.sum(G[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]) + +# 7) multi slices, assign one value per slice + +# multip_mat_min = zeros([clength, year]) +# multip_mat_min[x.clength[1:15], x.year[first_year_p:2024]] = 7 / 7 +# multip_mat_min[x.clength[16:25], x.year[first_year_p:2024]] = 20 / 20 +# multip_mat_min[x.clength[26:30], x.year[first_year_p:2024]] = 27 / 27 +# multip_mat_min[x.clength[31:35], x.year[first_year_p:2024]] = 32 / 32 +# multip_mat_min[x.clength[36:40], x.year[first_year_p:2024]] = 37 / 37 +# multip_mat_min[x.clength[41:50], x.year[first_year_p:2024]] = 42 / 42 +# multip_mat_min[x.clength[1:15], x.year[2025:2029]] = 8 / 7 +# multip_mat_min[x.clength[16:25], x.year[2025:2029]] = 21 / 20 +# multip_mat_min[x.clength[26:30], x.year[2025:2029]] = 28 / 27 +# multip_mat_min[x.clength[31:35], x.year[2025:2029]] = 33 / 32 +# multip_mat_min[x.clength[36:40], x.year[2025:2029]] = 38 / 37 +# multip_mat_min[x.clength[41:50], x.year[2025:2029]] = 43 / 42 +# multip_mat_min[x.clength[1:15], x.year[2030:]] = 9 / 7 +# multip_mat_min[x.clength[16:25], x.year[2030:]] = 22 / 20 +# multip_mat_min[x.clength[26:30], x.year[2030:]] = 29 / 27 +# multip_mat_min[x.clength[31:35], x.year[2030:]] = 34 / 32 +# multip_mat_min[x.clength[36:40], x.year[2030:]] = 39 / 37 +# multip_mat_min[x.clength[41:50], x.year[2030:]] = 44 / 42 +# +# # already possible +# m = zeros(clength) +# m[x.clength[1:15]] = 7 +# m[x.clength[16:25]] = 20 +# m[x.clength[26:30]] = 27 +# m[x.clength[31:35]] = 32 +# m[x.clength[36:40]] = 37 +# m[x.clength[41:50]] = 42 +# multip_mat_min = zeros([clength, year]) +# multip_mat_min[x.year[:2024]] = m / m +# multip_mat_min[x.year[2025:2029]] = (m + 1) / m +# multip_mat_min[x.year[2030:]] = (m + 2) / m + +# >>> very nice for this case but it does not scale very well with number of +# values to set. On the other hand, splitting it in case it does not fit +# on a line is not TOO horrible (just a bit horrible ;-)) +# m = zeros(clength) +# m[x.clength[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]] = \ +# [ 7, 20, 27, 32, 37, 42] +# multip_mat_min = zeros([clength, year]) +# multip_mat_min[x.year[:2024, 2025:2029, 2030:]] = \ +# [m / m, (m + 1) / m, (m + 2) / m] + +# m = zeros(clength) +# m[:] = { +# G[1:15]: 7, G[16:25]: 20, G[26:30]: 27, G[31:35]: 32, G[36:40]:37, +# G[41:50]: 42 +# } +# VERDICT: FAIL ! (see below) +# but m.set(map) could work + +# this seems powerful but there might be ambiguities? (do we want to expand +# the groups or treat them as normal "scalars") +# m = zeros(clength) +# m[:] = fromlists(['clength', G[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]], +# ['', 7, 20, 27, 32, 37, 42]) + +# VERDICT: FAIL ! the problem is that it breaks two basic assumptions +# * that m[:] will be entirely set +# * that value will be broadcast to the result of array[key] + +# also think about G (for group) or L (for label): + +# a[G[5:10]] +# a[G[5, 7, 9]] + +# a[G[5:10].named('brussels')] +# a[G[5, 7, 9].named('brussels')] + +# this is ugly +# a[G[5, 7, 9].axed('age')] +# a[G[5, 7, 9].x('age')] +# a[G[5, 7, 9].on('age')] +# a[G[5, 7, 9].with(axis='age')] + +# nice for the simple cases, but cannot target anonymous axes G[0] or axes with +# strange names G['strange axis']. would both try to find labels on axes, not +# the axes themselves. + +# a[G.age[5, 7, 9]] +# a[G.geo[5, 7, 9].named('brussels')] + +# a[x.age[G[5, 7, 9]]] +# a[x.age[G[5, 7, 9].named('brussels')]] + +# a[G.get('strange axis')[5, 7, 9].named('Brussels')] + +# a[x.age[5, 7, 9]] + +# positional groups *without axis* (G.i, P[], or I[]) does not make much sense, +# because it will matches all axes, but might be useful as an intermediate +# construct: + +# g = G.i[2, 5, 7] +# g2 = X.age[g] + +# positional groups *with axis* can be useful as a shorter alternative (but +# not worth it IMO, unless the whole API is more consistent for users): + +# g = P.age[2, 5, 7] +# instead of +# g = X.age.i[2, 5, 7] + +# we might want to also consider multi-dimensional groups: +# using K (for key) or I (for indexer) or G (without axis obviously): + +# g = G[2:7, 'M', ['P01', 'P05']] + +# it seems nifty, but that changes the semantic of a group (we would need +# multiple names??? OR ) + +# but it might be better to allow multiple slices from the same dimension in +# the same group: + +# g = G.age[:9, 10:14, 15:25] +# in that case, the above group would be written like: +# g = G[2:7] & G['M'] & G['P01', 'P05'] + +# ND group with single name vs ND group with name per dim vs multi-group. + +# g = G[2:7, 'M', ['P01', 'P05']].named('abc') would be a single ND group + +# vs + +# g = G[2:7].named('child'), G['M'], G['P01', 'P05'].named('plop') +# g = G[2:7].named('child') & G['M'] & G['P01', 'P05'].named('plop') + +# behavior is the same when filtering but when aggregating the multi-name +# version would produce "child & M & plop" while + +# vs + +# g = G[2:7, 9:13].named('abc') would be a single ND group + + +# in that cases, having NDG to create N dimensional groups might be a good idea + +# g = NDG[2:7, 'M', ['P01', 'P05']] + +# we also need the best possible syntax to handle, "arbitrary" resampling + +# pure_min_w1_comp_agg = zeros(result_axes) +# pure_min_w1_comp_agg[x.LBMosesXLS[1]] = pure_min_w1_comp.sum(x.clength[1:15]) +# pure_min_w1_comp_agg[x.LBMosesXLS[2]] = pure_min_w1_comp.sum(x.clength[16:25]) +# pure_min_w1_comp_agg[x.LBMosesXLS[3]] = pure_min_w1_comp.sum(x.clength[26:30]) +# pure_min_w1_comp_agg[x.LBMosesXLS[4]] = pure_min_w1_comp.sum(x.clength[31:35]) +# pure_min_w1_comp_agg[x.LBMosesXLS[5]] = pure_min_w1_comp.sum(x.clength[36:40]) +# pure_min_w1_comp_agg[x.LBMosesXLS[6]] = pure_min_w1_comp.sum(x.clength[41:50]) +# +# clength_groups = (x.clength[1:15], x.clength[16:25], x.clength[26:30], +# x.clength[31:35], x.clength[36:40], x.clength[41:50]) +# pure_min_w1_comp_agg2 = pure_min_w1_comp.sum(clength_groups).rename( +# x.clength, x.LBMosesXLS) + +# clength_groups = (L[1:15], L[16:25], L[26:30], +# L[31:35], L[36:40], L[41:50]) +# pure_min_w1_comp_agg2 = pure_min_w1_comp.sum(clength_groups).rename( +# x.clength, x.LBMosesXLS) +# +# clength_groups = x.clength[1:15, 16:25, 26:30, 31:35, 36:40, 41:50] +# pure_min_w1_comp_agg2 = pure_min_w1_comp.sum(clength_groups) +# +# clength_groups = G[1:15, 16:25, 26:30, 31:35, 36:40, 41:50] +# pure_min_w1_comp_agg2 = pure_min_w1_comp.sum(clength_groups) \ +# .replace(x.clength, LBMosesXLS) + +# XXX: what if I want to sum on all the slices (as if it was a single slice) +# clength_groups = G[1:15] | G[16:25] | G[26:30] | G[31:35] | G[36:40] | G[41:50] +# OR +# G.clength.union[1:15, 16:25, 26:30, 31:35, 36:40, 41:50] +# +# pure_min_w1_comp_agg2 = pure_min_w1_comp.sum(clength_groups) \ + +# I would also like to have a nice syntax for assigning (multiple) values to +# multiple slices (example courtesy of MOSES) + +# clength = Axis('clength', range(1, 51)) +# year = Axis('year', range(2010, 2050)) +# result_axes = AxisCollection([ +# clength, +# year +# ]) +# +# multip_mat_min = zeros([clength, year]) +# multip_mat_min[x.clength[1:15], x.year[first_year_p:2024]] = 7 / 7 +# multip_mat_min[x.clength[16:25], x.year[first_year_p:2024]] = 20 / 20 +# multip_mat_min[x.clength[26:30], x.year[first_year_p:2024]] = 27 / 27 +# multip_mat_min[x.clength[31:35], x.year[first_year_p:2024]] = 32 / 32 +# multip_mat_min[x.clength[36:40], x.year[first_year_p:2024]] = 37 / 37 +# multip_mat_min[x.clength[41:50], x.year[first_year_p:2024]] = 42 / 42 +# multip_mat_min[x.clength[1:15], x.year[2025:2029]] = 8 / 7 +# multip_mat_min[x.clength[16:25], x.year[2025:2029]] = 21 / 20 +# multip_mat_min[x.clength[26:30], x.year[2025:2029]] = 28 / 27 +# multip_mat_min[x.clength[31:35], x.year[2025:2029]] = 33 / 32 +# multip_mat_min[x.clength[36:40], x.year[2025:2029]] = 38 / 37 +# multip_mat_min[x.clength[41:50], x.year[2025:2029]] = 43 / 42 +# multip_mat_min[x.clength[1:15], x.year[2030:]] = 9 / 7 +# multip_mat_min[x.clength[16:25], x.year[2030:]] = 22 / 20 +# multip_mat_min[x.clength[26:30], x.year[2030:]] = 29 / 27 +# multip_mat_min[x.clength[31:35], x.year[2030:]] = 34 / 32 +# multip_mat_min[x.clength[36:40], x.year[2030:]] = 39 / 37 +# multip_mat_min[x.clength[41:50], x.year[2030:]] = 44 / 42 +# +# # already possible +# m = zeros(clength) +# m[x.clength[1:15]] = 7 +# m[x.clength[16:25]] = 20 +# m[x.clength[26:30]] = 27 +# m[x.clength[31:35]] = 32 +# m[x.clength[36:40]] = 37 +# m[x.clength[41:50]] = 42 +# multip_mat_min = zeros([clength, year]) +# multip_mat_min[x.year[:2024]] = m / m +# multip_mat_min[x.year[2025:2029]] = (m + 1) / m +# multip_mat_min[x.year[2030:]] = (m + 2) / m + +# TODO: it would be nice to be able to say: +# m[x.clength[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]] = [7, 20, 27, 32, 37, 42] +# but I am unsure it is possible/unambiguous + +# this kind of pattern is not supported by numpy +# in numpy, you can assign multiple slices to the SAME value (not one value per +# slice, using m[np._r[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]] = 7, but +# this actually construct a single array of indices, and ultimately, +# it is much slower than repeatedly doing m[slice()] = value +# %timeit j = np.r_[tuple(slice(i, i+5) for i in range(0, 1000, 10))]; a[j] = 9 +# 1000 loops, best of 3: 307 µs per loop +# %timeit for i in range(0, 1000, 10): a[i:i+5] = i +# 10000 loops, best of 3: 45.9 µs per loop + +# it is technically possibly to achieve in numpy (both in a vectorized manner +# and using explicit loop as above). The trick to vectorize this is to create +# an array of indices (with the slices expanded) and an array of values with +# the same size than the indices array (using np.repeat) + +# http://stackoverflow.com/questions/38923763/assign-multiple-values-to- +# multiple-slices-of-a-numpy-array-at-once + +# but the question is whether that syntax is unambiguous or not +# (and if not, whether or not we can come up with a syntax that is both nice +# and not ambiguous) + +# m[x.clength[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]] = \ +# [7, 20, 27, 32, 37, 42] +# multip_mat_min[x.year[:2024, 2025:2029, 2030:]] = [m / m, (m + 1) / m, +# (m + 2) / m] + +# for the multi-value case to work I would probably have to make +# m[x.clength[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]] +# return multiple arrays (as a tuple of arrays or an array of arrays) +# with pandas/MI support, we could just return an array with +# a (second) clength axis + + +# ======================================== +# ================ SESSION =============== +# ======================================== + +# with my idea to dispatch aggregate operation to each element + make +# __eq__ use _binop + +# (s1 == s2).all() would return a session with a list of bool scalars + +# which is probably not what people expect (+ don't know how to further +# aggregate) + +# ideally s.sum() would first sum each array then sum those sums +# and s.sum(x.age) would sum each array along age +# and s.sum(x.arrays) would try to add arrays together (and fail in +# some/most cases) +# the problem is that one important use case is not covered: +# aggregating along all dimensions of the arrays but NOT on x.arrays + +# Q: s.elements.sum() (or s.arrays.sum()) vs s.sum() solve this? +# A1: s.arrays.sum() would dispatch to each array and return a new Session +# s.sum() would try to do s.arrays.sum().sum() +# seems doable... + +# A2: s.sum_by(x.arrays) (like Pandas default aggregate) would solve +# the issue even more nicely, but this is a bit more work (is it?) and +# can be safely added later. + +# Q: does s1.arrays (op) s2.arrays works too? +# A: dispatch op to each array present in either s1 or s2 +# so yes, but as we see below, no point + +# Q: what happens when you do s1.arrays + s2 ? +# A: + +# Q: what happens when you do s1 + s2 ? +# A: same than s1.arrays + s2.arrays +# if we view s1 as a big array with an extra dimension, it would give +# that result (modulo union of names until we are Pandas based) + +# Q: does that solve the == use case acceptably? +# A: to test that two session are equal, you'd have to write: +# (s1.arrays == s2.arrays).arrays.all().all() +# which is way too convoluted for users. + +# (s1.arrays == s2.arrays).all() would work too though +# and even +# (s1 == s2).all() + +# Q: what if I want to know which arrays are equal and which are not? +# A: (s1 == s2).all_by(x.arrays) + +# boolean ops +# =========== + +# Q: we could implement two(?) very different behavior: +# set-like behavior: combination of two Session, if same name, +# check that it is the same. a Session is more ordered-dict-like than +# set-like, so this might not make a lot of sense. an "update" method +# might make more sense. However most set-like operations do make sense. + +# intersection: check common are the same or take left? +# union: check common are the same or take left? +# difference + +# A: I think it's best that __bool_ops__ are element-wise, like other __ops__ +# but we can/should define methods for the set-like operations +# .isdisjoint(other) +# .issubset(other) +# .issuperset(other) +# .union(*others) +# .intersection(*others) +# .difference(*others) +# .symmetric_difference(other) + +# references + +# https://docs.scipy.org/doc/numpy/reference/routines.set.html +# https://docs.scipy.org/doc/numpy/reference/routines.logic.html#logical-operations +# https://docs.python.org/3.7/library/stdtypes.html#set + + >>> to_key('axis=a,b:d,e ! groupname') + >>> to_key('axis=a,b:d,e # groupname') + >>> to_key('axis=a,b:d,e & groupname') + >>> to_key('axis=a,b:d,e ~ groupname') + >>> to_key('axis=a,b:d,e @ groupname') + >>> to_key('groupname=a,b:d,e @ axis') + >>> to_key('groupname=#1:7a,b:d,e @ axis') + >>> to_key('teens=#1:7,b:d,e @ age') + >>> ext = la({'M': 55, 'F': 56}) + # cannot use f-string (or string formatting) because that would be too + # limiting, ie. ext above wouldn't work + >>> a.sum('10_19=10:19 ; 20_29=20:29; #-1@year ; services=a,c:e,o@c_from ; {ext}@c_to') + >>> a.sum('age=10:19 > 10_19 ; 20:29 > 20_29 ; year=#-1 ; services=a,c:e ; c_from=o ; c_to={ext}') + # names only make sense when doing group aggregates, ie within parentheses + >>> a.sum('age=(10:19 > 10_19 ; 20:29 > 20_29); year=#-1 ; services=a, c:e ; c_from=o ; c_to={ext}') + # the parentheses are potentially superfluous since we separated groups + # using ; => means different LGroup + # several groups on same axis => multi group aggregate + >>> a['age=20:29|5 & year=#-1 & c_from=o & c_to={ext}'] + >>> a['age=(10:19 >> 10_19 ; 20:29 >> 20_29) & c_from=o & c_to={ext}'] + >>> a['age=10:19->10_19 ; age=20:29->20_29 & c_from=o & c_length={ext}'] + >>> a['age=(10:19->10_19 ; #10:20) & c_from=o & c_length={ext}'] + + + >>> a['age[20:29].by(5) & year.i[-1] & c_from[o] & c_to[{ext}]'] + + >>> a['age=(10:19 >> 10_19 ; 20:29 >> 20_29) & c_from=o & c_to={ext}'] + >>> a['(age[10:19] >> 10_19, age[20:29] >> 20_29) & c_from[o] & c_to[{ext}]'] + >>> a['age=(10:19 >> 10_19 ; 20:29 >> 20_29) & c_from=o & c_to={ext}'] + >>> a['age=10:19->10_19 ; age=20:29->20_29 & c_from=o & c_length={ext}'] + >>> a['age=(10:19->10_19 ; #10:20) & c_from=o & c_length={ext}'] + + is it: + * filter = expr | expr + = expr & expr + = expr ^ expr + = expr + * expr = + >>> a['10:60 by 5 & c_from=o & c_to={ext}'] + >>> a.sum('10:19 > 10_19 ; 20:29 > 20_29 ; year=#-1') + >>> a.sum('(10:19 > 10_19 ; 20:29 > 20_29) & year=#-1') + >>> teens = G['age=10:19 >> teens'] + >>> teens = x.age[10:19].named('teens') + >>> twenties = G['age=20:29'] + >>> a.sum('({teens}, {twenties})') + >>> a.sum((teens, twenties)) + # will we ever want to support this? + >>> a.sum('age > clength') + >>> a.sum('age > {ext}') + >>> a.sum(x.age > ext) + >>> a.sum('age > 10') + LGroup(['a', 'b', 'c'], name='abc') + + +expend_flow[x.cat_from['married_women'], x.cat_to['retirement_survival_women'], y] = \ + flow[x.cat_from['married_women'], x.cat_to['retirement_survival_women'], y] * \ + pension_age_diff_lag['married_men', y] * 1.1 * (45 / average_clength_survival['married_men', y]) + +expend_flow['cat_from[married_women], cat_to[retirement_survival_women]', y] = \ + flow['cat_from[married_women], cat_to[retirement_survival_women]', y] * \ + pension_age_diff_lag['married_men', y] * 1.1 * (45 / average_clength_survival['married_men', y]) + +# =================================================== +# ================ Multi Index/Sparse =============== +# =================================================== + +* for each label in an axis part of a CombinedAxis I need a list/array of + positions => the total size of those position arrays will be equal to N * L + where L is the length of the combined axis + N is the number of axes in the combined axis + +* the questions is whether: + + arr['M', 10] + lines1 = sex.lines('M') + lines2 = age.lines(10) + total_lines = intersect(lines1, lines2) + + is faster than pandas: + + arr['M', 10] + filter1 = sex.filter('M') + filter2 = age.filter(10) + total_lines = (filter1 & filter2).nonzero() + +* does something like categorical (transforms label -> index) help? + +# ======================================================== +# ================ set operation on groups =============== +# ======================================================== + +we want + and - ops on groups to be both set operation +or arithmetic operation depending on the case. + + +for y in time[start_year + 1:]: + res = a[y + 1] + +for c in sutcode.matches('^...$') + sutcode.matches('^..$') - 'ND': + g = sutcode.startswith(c) - c + +# option 1 +# ======== + +op on evaluated key by default (whatever it is -- scalar or ndarray) +set ops must use specific methods + +for y in time[start_year + 1:]: + res = a[y + 1] + +for c in sutcode.matches('^...$').union(sutcode.matches('^..$')).setdiff('ND'): + g = sutcode.startswith(c).setdiff(c) +for c in sutcode.matches('^...$').union(sutcode.matches('^..$')).difference('ND'): + g = sutcode.startswith(c).difference(c) + +# option 2 +# ======== + +op on evaluated key by default (whatever it is -- scalar or ndarray) +convert LGroup to LSet using method a specific method + +for y in time[start_year + 1:]: + res = a[y + 1] + +# the second .set() is optional +for c in sutcode.matches('^...$').set() | sutcode.matches('^..$').set() - 'ND': + g = sutcode.startswith(c).set() - c + +# option 3 (current) +# ================== + +set op on evaluated key by default +need to use .labels on the axis or .eval() on the group to do arithmetic ops +note that it might be a good idea to implement a .labels property on groups + +for y in time.labels: +for y in time[start_year + 1:].eval(): + res = a[y + 1] + +for c in sutcode.matches('^...$') | sutcode.matches('^..$') - 'ND': + g = sutcode.startswith(c) - c + +# option 4 +# ======== + +set op if sequence, arithmetic if scalar. This looks good in our example and is usually what people want +but this is not the path of least surprise ! + +for y in time[start_year + 1:]: + res = a[y + 1] + +for c in sutcode.matches('^...$') | sutcode.matches('^..$') - 'ND': + g = sutcode.startswith(c) - c + + +# an example of unexpected result would be: +age[1:] + 1 + + +for y in time[start_year + 1:]: + res = a[y + 1] + +for c in sutcode.matches('^...$') | sutcode.matches('^..$') - 'ND': + g = sutcode.startswith(c) - c + +========================================== +========================================== + +# other query style + +# we could have special aggregate functions +subset = pop.q('M', sum[10:20]) +# works nicely to disambiguate axes +subset = pop.q('M', age.sum[10:20, 20:30]) +# but we have a problem with naming the aggregated labels (this cannot work except using a full-string syntax) +subset = pop.q('M', age.sum[10:20 >> 'yada1', 20:30 >> 'yada2']) +# this, however could work, but would be error-prone: +subset = pop.q('M', age.sum[10:20, 20:30] >> ('yada1', 'yada2')) +# this could work though +subset = pop.q('M', age.sum(S[10:20] >> 'yada1', S[20:30] >> 'yada2')) +# which maps nicely to the string-only: +subset = pop.q('M, age.sum(10:20 >> yada1, 20:30 >> yada2')) +# without ambiguity, that would be +subset = pop.q('M, sum(10:20 >> yada1, 20:30 >> yada2')) + +# if using a function (like .q) we could also "rename" axes on the fly. the above would create an aggregated axis +# named "age" but the code below would create "toto" instead +subset = pop.q('M', toto=age.sum[10:20, 20:30]) + + diff --git a/doc/environment.yml b/doc/environment.yml new file mode 100644 index 000000000..22bb73a8c --- /dev/null +++ b/doc/environment.yml @@ -0,0 +1,16 @@ +name: larray-docs +channels: + - conda-forge + - defaults +dependencies: + - python=3.5 + - numpy + - pandas + - matplotlib + - pytables + - sphinx + - numpydoc + - pandoc + - ipython + - ipykernel + - nbsphinx diff --git a/doc/make.bat b/doc/make.bat index b468ba1a9..182d20201 100644 --- a/doc/make.bat +++ b/doc/make.bat @@ -1,53 +1,19 @@ @ECHO OFF +pushd %~dp0 + REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) +set SOURCEDIR=source set BUILDDIR=build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source -set I18NSPHINXOPTS=%SPHINXOPTS% source -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) +set SPHINXPROJ=larray if "%1" == "" goto help -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -%SPHINXBUILD% 2> nul +%SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx @@ -60,183 +26,11 @@ if errorlevel 9009 ( exit /b 1 ) -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\LArray.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\LArray.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% :end +popd diff --git a/doc/notebooks/LArray classes.ipynb b/doc/notebooks/LArray classes.ipynb deleted file mode 100644 index 596d7bda1..000000000 --- a/doc/notebooks/LArray classes.ipynb +++ /dev/null @@ -1,759 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Axis" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from larray import *" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "age = Axis('age', ':115')" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'age'" - ] - }, - "execution_count": 4, - "output_type": "execute_result", - "metadata": {} - } - ], - "source": [ - "age.name" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12',\n", - " '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23',\n", - " '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34',\n", - " '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45',\n", - " '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56',\n", - " '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67',\n", - " '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78',\n", - " '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89',\n", - " '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100',\n", - " '101', '102', '103', '104', '105', '106', '107', '108', '109',\n", - " '110', '111', '112', '113', '114', '115'], \n", - " dtype='\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0ma\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mwal_str\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;32mc:\\users\\gdm\\devel\\larray\\larray\\core.py\u001b[0m in \u001b[0;36m__getitem__\u001b[1;34m(self, key, collapse_slices)\u001b[0m\n\u001b[0;32m 946\u001b[0m \u001b[0mdata\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0masarray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 947\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 948\u001b[1;33m \u001b[0mtranslated_key\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtranslated_key\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfull_key\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 949\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 950\u001b[0m axes = [axis.subaxis(axis_key)\n", - "\u001b[1;32mc:\\users\\gdm\\devel\\larray\\larray\\core.py\u001b[0m in \u001b[0;36mtranslated_key\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 941\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mtranslated_key\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 942\u001b[0m return tuple(axis.translate(axis_key)\n\u001b[1;32m--> 943\u001b[1;33m for axis, axis_key in zip(self.axes, key))\n\u001b[0m\u001b[0;32m 944\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 945\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m__getitem__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcollapse_slices\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mc:\\users\\gdm\\devel\\larray\\larray\\core.py\u001b[0m in \u001b[0;36m\u001b[1;34m(.0)\u001b[0m\n\u001b[0;32m 941\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mtranslated_key\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 942\u001b[0m return tuple(axis.translate(axis_key)\n\u001b[1;32m--> 943\u001b[1;33m for axis, axis_key in zip(self.axes, key))\n\u001b[0m\u001b[0;32m 944\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 945\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m__getitem__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcollapse_slices\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mc:\\users\\gdm\\devel\\larray\\larray\\core.py\u001b[0m in \u001b[0;36mtranslate\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 549\u001b[0m \u001b[0mres\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mempty\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mint\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 550\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlabel\u001b[0m \u001b[1;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 551\u001b[1;33m \u001b[0mres\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmapping\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mlabel\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 552\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mres\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 553\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mKeyError\u001b[0m: 'A25'" - ] - } - ], - "source": [ - "a[wal_str]" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "age | geo\\sex | M | F\n", - " 0 | A25 | 0.0 | 0.0\n", - " 0 | A51 | 0.0 | 0.0\n", - " 0 | A52 | 0.0 | 0.0\n", - " 0 | A53 | 0.0 | 0.0\n", - " 0 | A54 | 0.0 | 0.0\n", - "... | ... | ... | ...\n", - "115 | A84 | 0.0 | 0.0\n", - "115 | A85 | 0.0 | 0.0\n", - "115 | A91 | 0.0 | 0.0\n", - "115 | A92 | 0.0 | 0.0\n", - "115 | A93 | 0.0 | 0.0" - ] - }, - "execution_count": 28, - "output_type": "execute_result", - "metadata": {} - } - ], - "source": [ - "a.filter(geo=wal_str)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### ... or using the dimension position" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "age | geo\\sex | M | F\n", - " 0 | A25 | 0.0 | 0.0\n", - " 0 | A51 | 0.0 | 0.0\n", - " 0 | A52 | 0.0 | 0.0\n", - " 0 | A53 | 0.0 | 0.0\n", - " 0 | A54 | 0.0 | 0.0\n", - "... | ... | ... | ...\n", - "115 | A84 | 0.0 | 0.0\n", - "115 | A85 | 0.0 | 0.0\n", - "115 | A91 | 0.0 | 0.0\n", - "115 | A92 | 0.0 | 0.0\n", - "115 | A93 | 0.0 | 0.0" - ] - }, - "execution_count": 29, - "output_type": "execute_result", - "metadata": {} - } - ], - "source": [ - "a[:,wal_str]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### ValueGroup keys can also be slices" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "ValueGroup(slice('A23', 'A42', None))" - ] - }, - "execution_count": 30, - "output_type": "execute_result", - "metadata": {} - } - ], - "source": [ - "geo['A23':'A42']" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "ValueGroup('A23:A42')" - ] - }, - "execution_count": 31, - "output_type": "execute_result", - "metadata": {} - } - ], - "source": [ - "geo['A23:A42']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Note that slice stop bounds are _inclusive_" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Notice that the slices are not expanded within the ValueGroup" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "116 x 12 x 2\n", - " age [116]: '0' '1' '2' ... '113' '114' '115'\n", - " geo [12]: 'A23' 'A24' 'A31' ... 'A38' 'A41' 'A42'\n", - " sex [2]: 'M' 'F'" - ] - }, - "execution_count": 32, - "output_type": "execute_result", - "metadata": {} - } - ], - "source": [ - "a[geo['A23:A42']].info" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3.0 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.4.2" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/doc/notebooks/LArray generate.ipynb b/doc/notebooks/LArray generate.ipynb deleted file mode 100644 index 7a1978db9..000000000 --- a/doc/notebooks/LArray generate.ipynb +++ /dev/null @@ -1,264 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from larray import *" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "age = Axis('age', ':115')" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "vla = 'A11,A12,A13,A23,A24,A31,A32,A33,A34,A35,A36,A37,A38,A41,A42,' \\\n", - " 'A43,A44,A45,A46,A71,A72,A73'\n", - "wal = 'A25,A51,A52,A53,A54,A55,A56,A57,A61,A62,A63,A64,A65,A81,A82,' \\\n", - " 'A83,A84,A85,A91,A92,A93'\n", - "bru = 'A21'" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "belgium = union(vla, wal, bru)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "geo = Axis('geo', belgium)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "sex = Axis('sex', 'H,F')" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "lipro = Axis('lipro', ['P%02d' % i for i in range(1, 16)])" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "a = zeros([age, geo, sex, lipro])" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "116 x 44 x 2 x 15\n", - " age [116]: '0' '1' '2' ... '113' '114' '115'\n", - " geo [44]: 'A11' 'A12' 'A13' ... 'A92' 'A93' 'A21'\n", - " sex [2]: 'H' 'F'\n", - " lipro [15]: 'P01' 'P02' 'P03' ... 'P13' 'P14' 'P15'" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.info" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "1224960" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.nbytes" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "age | geo | sex\\lipro | P01 | P02 | P03 | ... | P13 | P14 | P15\n", - " 0 | A11 | H | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0\n", - " 0 | A11 | F | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0\n", - " 0 | A12 | H | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0\n", - " 0 | A12 | F | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0\n", - " 0 | A13 | H | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0\n", - "... | ... | ... | ... | ... | ... | ... | ... | ... | ...\n", - "115 | A92 | F | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0\n", - "115 | A93 | H | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0\n", - "115 | A93 | F | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0\n", - "115 | A21 | H | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0\n", - "115 | A21 | F | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "a[:] = np.random.random(a.shape)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "age | geo | sex\\lipro | P01 | P02 | ... | P14 | P15\n", - " 0 | A11 | H | 0.668854422352 | 0.0376059619919 | ... | 0.686858789035 | 0.30979163783\n", - " 0 | A11 | F | 0.75855248304 | 0.693872979814 | ... | 0.383254159452 | 0.793161211607\n", - " 0 | A12 | H | 0.314309233292 | 0.563827719724 | ... | 0.262676449687 | 0.471763401789\n", - " 0 | A12 | F | 0.417450209563 | 0.149372133885 | ... | 0.842063762991 | 0.402515717551\n", - " 0 | A13 | H | 0.188513450344 | 0.936639641599 | ... | 0.537113369216 | 0.166630231969\n", - "... | ... | ... | ... | ... | ... | ... | ...\n", - "115 | A92 | F | 0.327695671322 | 0.572358110697 | ... | 0.433911655829 | 0.761581111946\n", - "115 | A93 | H | 0.177279668293 | 0.710137592292 | ... | 0.830251021661 | 0.981382475774\n", - "115 | A93 | F | 0.000884998592067 | 0.838716214915 | ... | 0.0662629828389 | 0.559637960433\n", - "115 | A21 | H | 0.886919131513 | 0.356640301942 | ... | 0.363741993326 | 0.528099559253\n", - "115 | A21 | F | 0.445025411768 | 0.036338797045 | ... | 0.336746572464 | 0.804422784704" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "a.to_csv('test.csv')" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.4.2" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/doc/notebooks/LArray usage.ipynb b/doc/notebooks/LArray usage.ipynb deleted file mode 100644 index 7525c76ff..000000000 --- a/doc/notebooks/LArray usage.ipynb +++ /dev/null @@ -1,806 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from larray import *" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Loading" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "a = read_csv('test.csv')" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "age | geo | sex\\lipro | P01 | ... | P15\n", - " 0 | A11 | F | 0.444719251373 | ... | 0.857357338422\n", - " 0 | A11 | H | 0.190309636993 | ... | 0.14832969697\n", - " 0 | A12 | F | 0.525551565311 | ... | 0.318208198697\n", - " 0 | A12 | H | 0.238886570471 | ... | 0.319796432449\n", - " 0 | A13 | F | 0.392189019207 | ... | 0.574969923834\n", - "... | ... | ... | ... | ... | ...\n", - "115 | A91 | H | 0.391566460037 | ... | 0.728229419264\n", - "115 | A92 | F | 0.0744904918105 | ... | 0.818109781716\n", - "115 | A92 | H | 0.110161927992 | ... | 0.71327740658\n", - "115 | A93 | F | 0.260923731957 | ... | 0.277366470012\n", - "115 | A93 | H | 0.0968159351789 | ... | 0.32785443685" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "age | geo | sex\\lipro | P01 | ... | P15\n", - " 0 | A11 | H | 0.190309636993 | ... | 0.14832969697\n", - " 0 | A11 | F | 0.444719251373 | ... | 0.857357338422\n", - " 0 | A12 | H | 0.238886570471 | ... | 0.319796432449\n", - " 0 | A12 | F | 0.525551565311 | ... | 0.318208198697\n", - " 0 | A13 | H | 0.996500945466 | ... | 0.0680649644884\n", - "... | ... | ... | ... | ... | ...\n", - "115 | A92 | F | 0.0744904918105 | ... | 0.818109781716\n", - "115 | A93 | H | 0.0968159351789 | ... | 0.32785443685\n", - "115 | A93 | F | 0.260923731957 | ... | 0.277366470012\n", - "115 | A21 | H | 0.647621552761 | ... | 0.0584404925351\n", - "115 | A21 | F | 0.583489886972 | ... | 0.0380375565898" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "read_csv('test.csv', sort_rows=False) # this is less efficient" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "116 x 44 x 2 x 15\n", - " age [116]: 0 1 2 ... 113 114 115\n", - " geo [44]: 'A11' 'A12' 'A13' ... 'A91' 'A92' 'A93'\n", - " sex [2]: 'F' 'H'\n", - " lipro [15]: 'P01' 'P02' 'P03' ... 'P13' 'P14' 'P15'" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.info" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Subsets" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "age | geo\\lipro | P01 | P02 | P03\n", - " 10 | A11 | 0.535583193122 | 0.907643374199 | 0.543002311716\n", - " 10 | A12 | 0.903291912629 | 0.0572099558245 | 0.582381520479\n", - " 10 | A13 | 0.469461685932 | 0.0670163452205 | 0.55629091369\n", - " 10 | A21 | 0.9734778082 | 0.317804797686 | 0.166550538449\n", - " 10 | A23 | 0.478404146288 | 0.491018325693 | 0.559592793556\n", - "... | ... | ... | ... | ...\n", - " 19 | A84 | 0.80883179013 | 0.992894544001 | 0.044995377724\n", - " 19 | A85 | 0.0572309653153 | 0.970772472985 | 0.580846330739\n", - " 19 | A91 | 0.604907113218 | 0.765298653884 | 0.215328975058\n", - " 19 | A92 | 0.277793215869 | 0.0874388749842 | 0.933196289014\n", - " 19 | A93 | 0.451208013092 | 0.37275177365 | 0.528825043318" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.filter(age=slice(10, 19), sex='F', lipro=':P03')" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "age, geo, sex, lipro = a.axes" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "age | geo\\lipro | P01 | P02 | P03\n", - " 10 | A11 | 0.535583193122 | 0.907643374199 | 0.543002311716\n", - " 10 | A12 | 0.903291912629 | 0.0572099558245 | 0.582381520479\n", - " 10 | A13 | 0.469461685932 | 0.0670163452205 | 0.55629091369\n", - " 10 | A21 | 0.9734778082 | 0.317804797686 | 0.166550538449\n", - " 10 | A23 | 0.478404146288 | 0.491018325693 | 0.559592793556\n", - "... | ... | ... | ... | ...\n", - " 19 | A84 | 0.80883179013 | 0.992894544001 | 0.044995377724\n", - " 19 | A85 | 0.0572309653153 | 0.970772472985 | 0.580846330739\n", - " 19 | A91 | 0.604907113218 | 0.765298653884 | 0.215328975058\n", - " 19 | A92 | 0.277793215869 | 0.0874388749842 | 0.933196289014\n", - " 19 | A93 | 0.451208013092 | 0.37275177365 | 0.528825043318" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.filter(age=age[10:19], sex='F', lipro=':P03')" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "10 x 44 x 3\n", - " age [10]: 10 11 12 ... 17 18 19\n", - " geo [44]: 'A11' 'A12' 'A13' ... 'A91' 'A92' 'A93'\n", - " lipro [3]: 'P01' 'P02' 'P03'" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[age[10:19], sex['F'], lipro[':P03']].info" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "geo | age | sex\\lipro | P01 | P02 | ... | P14 | P15\n", - "A11 | 0 | F | 0.444719251373 | 0.104695980838 | ... | 0.952346693326 | 0.857357338422\n", - "A11 | 0 | H | 0.190309636993 | 0.335642369715 | ... | 0.23400284437 | 0.14832969697\n", - "A11 | 1 | F | 0.559803413008 | 0.351865844638 | ... | 0.967182623016 | 0.877175711338\n", - "A11 | 1 | H | 0.327116891552 | 0.484645912432 | ... | 0.0284835154138 | 0.498051650916\n", - "A11 | 2 | F | 0.949967449501 | 0.475757094424 | ... | 0.152028652961 | 0.223858387695\n", - "... | ... | ... | ... | ... | ... | ... | ...\n", - "A93 | 113 | H | 0.962987092586 | 0.249248428275 | ... | 0.955409495707 | 0.481918008908\n", - "A93 | 114 | F | 0.166778419369 | 0.250749041642 | ... | 0.512821101609 | 0.568783082515\n", - "A93 | 114 | H | 0.116064691352 | 0.846064135762 | ... | 0.999957770615 | 0.696735430371\n", - "A93 | 115 | F | 0.260923731957 | 0.852319460201 | ... | 0.875187588136 | 0.277366470012\n", - "A93 | 115 | H | 0.0968159351789 | 0.0533891559548 | ... | 0.605907315105 | 0.32785443685" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.transpose('geo', 'age')" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "vla = 'A11,A12,A13,A23,A24,A31,A32,A33,A34,A35,A36,A37,A38,A41,A42,' \\\n", - " 'A43,A44,A45,A46,A71,A72,A73'\n", - "wal = 'A25,A51,A52,A53,A54,A55,A56,A57,A61,A62,A63,A64,A65,A81,A82,' \\\n", - " 'A83,A84,A85,A91,A92,A93'\n", - "bru = 'A21'" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "age | geo | sex\\lipro | P01 | P02 | ... | P14 | P15\n", - " 0 | A11 | F | 0.444719251373 | 0.104695980838 | ... | 0.952346693326 | 0.857357338422\n", - " 0 | A11 | H | 0.190309636993 | 0.335642369715 | ... | 0.23400284437 | 0.14832969697\n", - " 0 | A12 | F | 0.525551565311 | 0.76756879464 | ... | 0.195849317134 | 0.318208198697\n", - " 0 | A12 | H | 0.238886570471 | 0.0196763224555 | ... | 0.180263285931 | 0.319796432449\n", - " 0 | A13 | F | 0.392189019207 | 0.612696515983 | ... | 0.199982435325 | 0.574969923834\n", - "... | ... | ... | ... | ... | ... | ... | ...\n", - "115 | A71 | H | 0.966296563913 | 0.543436587821 | ... | 0.556138400773 | 0.889400334367\n", - "115 | A72 | F | 0.0415274609052 | 0.712388265628 | ... | 0.954952258212 | 0.24686604991\n", - "115 | A72 | H | 0.47467660042 | 0.0887625684572 | ... | 0.876874512088 | 0.598036667603\n", - "115 | A73 | F | 0.116741064304 | 0.812163030273 | ... | 0.534641776825 | 0.69228208191\n", - "115 | A73 | H | 0.317726256191 | 0.392744829078 | ... | 0.865299389507 | 0.516535714438" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[geo[vla]]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Aggregates" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## full axes" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "sex\\lipro | P01 | P02 | ... | P14 | P15\n", - " F | 2524.69770789 | 2549.95634634 | ... | 2524.80212436 | 2518.22600648\n", - " H | 2547.29881892 | 2587.16877625 | ... | 2565.67249288 | 2588.22747713" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.sum(geo, age)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## by group" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "sex\\lipro | P01 | P02 | ... | P14 | P15\n", - " F | 1257.41891451 | 1262.11178447 | ... | 1249.2718058 | 1261.63605388\n", - " H | 1258.84650127 | 1282.23536837 | ... | 1269.91668621 | 1301.38479936" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.sum(age, geo[vla])" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - " geo | sex\\lipro | ...\n", - "A11,A12,A13,A23,A24,A31,A32,A33,A34,A35,A36,A37,A38,A41,A42,A43,A44,A45,A46,A71,A72,A73 | F | ...\n", - "A11,A12,A13,A23,A24,A31,A32,A33,A34,A35,A36,A37,A38,A41,A42,A43,A44,A45,A46,A71,A72,A73 | H | ...\n", - " A25,A51,A52,A53,A54,A55,A56,A57,A61,A62,A63,A64,A65,A81,A82,A83,A84,A85,A91,A92,A93 | F | ...\n", - " A25,A51,A52,A53,A54,A55,A56,A57,A61,A62,A63,A64,A65,A81,A82,A83,A84,A85,A91,A92,A93 | H | ...\n", - " A21 | F | ...\n", - " A21 | H | ..." - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.sum(age, geo=(vla, wal, bru))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Using named groups" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "vla = geo.group(vla, name='Flanders')\n", - "wal = geo.group(wal, name='wal')\n", - "bru = geo.group(bru, name='bru')\n", - "bel = geo.all('belgium')" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "b = a.sum(age, geo=(vla, wal, bru, bel))" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "agg.to_" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Operations on aggregated arrays" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "aggvla = agg[vla]" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "sex\\lipro | P01 | P02 | ... | P14 | P15\n", - " F | 1257.41891451 | 1262.11178447 | ... | 1249.2718058 | 1261.63605388\n", - " H | 1258.84650127 | 1282.23536837 | ... | 1269.91668621 | 1301.38479936" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "aggvla" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "sex\\lipro | P01,P02 | P03:P05 | P07:P11\n", - " F | 2519.53069898 | 3834.76571855 | 6383.13302993\n", - " H | 2541.08186964 | 3855.37262749 | 6396.31174074" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "aggvla.sum(lipro='P01,P02;P03:P05;P07:P11')" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# does not work yet (no idea why)\n", - "# aggvla.sum(sex='H;F;H,F')" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "sex | F | H\n", - " | 2519.53069898 | 2541.08186964" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agg[vla, lipro['P01']] + agg[vla, lipro['P02']]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Arithmetic operations" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "sex\\lipro | P01 | P02 | ... | P14 | P15\n", - " F | 3.28078522152 | 3.29302958834 | ... | 3.25952825337 | 3.2917883394\n", - " H | 3.28450999892 | 3.3455348878 | ... | 3.31339368974 | 3.39549848344" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "aggvla / aggvla.sum() * 100" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "sex\\lipro | P01 | P02 | P03 | P04 | P05 | ... | P11 | P12 | P13 | P14 | P15\n", - " F | 2.0 | 2.0 | 2.0 | 2.0 | 2.0 | ... | 2.0 | 2.0 | 2.0 | 2.0 | 2.0\n", - " H | 2.0 | 2.0 | 2.0 | 2.0 | 2.0 | ... | 2.0 | 2.0 | 2.0 | 2.0 | 2.0" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "aggvla * 2 / aggvla" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## on arrays with a different axis order" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "t = aggvla.transpose()" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "lipro\\sex | F | H\n", - " P01 | 1257.41891451 | 1258.84650127\n", - " P02 | 1262.11178447 | 1282.23536837\n", - " P03 | 1269.8737265 | 1278.89450299\n", - " P04 | 1290.02428115 | 1287.85009927\n", - " P05 | 1274.8677109 | 1288.62802523\n", - " P06 | 1277.25384401 | 1291.28395492\n", - " P07 | 1273.77730123 | 1277.97810064\n", - " P08 | 1276.36834354 | 1287.65325021\n", - " P09 | 1303.26548186 | 1276.8684769\n", - " P10 | 1255.26751446 | 1271.02951343\n", - " P11 | 1274.45438884 | 1282.78239956\n", - " P12 | 1282.53299787 | 1267.04452183\n", - " P13 | 1298.07892426 | 1298.16793633\n", - " P14 | 1249.2718058 | 1269.91668621\n", - " P15 | 1261.63605388 | 1301.38479936" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - "sex\\lipro | P01 | P02 | ... | P14 | P15\n", - " F | 2514.83782901 | 2524.22356894 | ... | 2498.54361161 | 2523.27210776\n", - " H | 2517.69300253 | 2564.47073674 | ... | 2539.83337242 | 2602.76959872" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "aggvla + t" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## with missing axes" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - " geo | sex\\lipro | P01 | ... | P15\n", - "Flanders | F | 1.0 | ... | 1.0\n", - "Flanders | H | 1.0 | ... | 1.0\n", - " wal | F | 0.957174200585 | ... | 0.951101552226\n", - " wal | H | 0.980152428259 | ... | 0.94624573877\n", - " bru | F | 0.0506671629946 | ... | 0.0448987988484\n", - " bru | H | 0.043365781748 | ... | 0.0425799171032\n", - " belgium | F | 2.00784136358 | ... | 1.99600035107\n", - " belgium | H | 2.02351821001 | ... | 1.98882565587" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agg / agg[vla]" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\n", - " geo | sex\\lipro | P01 | ... | P15\n", - "Flanders | F | 0.499716328263 | ... | 0.492245723356\n", - "Flanders | H | 0.500283671737 | ... | 0.507754276644\n", - " wal | F | 0.493785974209 | ... | 0.493525098585\n", - " wal | H | 0.506214025791 | ... | 0.506474901415\n", - " bru | F | 0.538541553694 | ... | 0.505501962023\n", - " bru | H | 0.461458446306 | ... | 0.494498037977\n", - " belgium | F | 0.497771970968 | ... | 0.493145783969\n", - " belgium | H | 0.502228029032 | ... | 0.506854216031" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "agg / agg.sum(sex)" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "celltoolbar": "Raw Cell Format", - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.4.2" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/doc/notebooks/Pandas vs LArray benchmark.ipynb b/doc/notebooks/Pandas vs LArray benchmark.ipynb deleted file mode 100644 index 776a933ed..000000000 --- a/doc/notebooks/Pandas vs LArray benchmark.ipynb +++ /dev/null @@ -1,439 +0,0 @@ -{ - "metadata": { - "name": "", - "signature": "sha256:17bb1ddede92e9bd4dc39acbda0c110d1f9feecfa4af52958b666067e1b81ef4" - }, - "nbformat": 3, - "nbformat_minor": 0, - "worksheets": [ - { - "cells": [ - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import pandas as pd" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 2 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "df = pd.read_hdf('c:/tmp/kh/rgl_df_fixed.h5', 'rgl')" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 4 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "df.index.levels" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 5, - "text": [ - "FrozenList([['T'], ['F', 'H'], ['1519', '2024', '2529', '3034', '3539', '4044', '4549', '5054', '5559', '6064', '6569', '7074', '7599', 'ONBE'], ['A', 'B', 'D', 'E', 'L', 'M', 'P', 'R', 'U', 'V', 'W', 'X', 'Y', 'Z'], ['A', 'B', 'F', 'X'], ['R', 'U'], ['D', 'I', 'M', 'O', 'V'], ['G', 'K'], ['01A1', '02A1', '03A1', '05A1', '08A1', '09A1', '10A1', '10B1', '10C1', '10D1', '10E1', '10F1', '10G1', '10H1', '10I1', '10J1', '11A1', '11B1', '12A1', '13A1', '13B1', '14A1', '15A1', '16A1', '17A1', '18A1', '19A1', '20A1', '20B1', '20C1', '20D1', '20E1', '20F1', '20G1', '21A1', '22A1', '22B1', '23A1', '23B1', '23C1', '23D1', '24A1', '24B1A', '24B1B', '24B1C', '25A1', '25B1', '25C1', '26A1A', '26A1B', '26B1A', '26B1B', '26C1A', '26C1B', '26C1C', '27A1A', '27A1B', '27A1C', '27B1', '28A1', '28B1', '29A1', '29B1', '30A1', '30B1', '30C1', '30D1', '31A1', '32A1', '32B1A', '32B1B', '33A1A', '33A1B', '35A1', '35B1', '36A1', '37A1', '37A3', '38A1', '38B1', '39A1', '41A1A', '41A1B', '42A1', '43A1', '43B1', '43C1', '43D1', '45A1', '46A1', '46B1', '47A1', '47B1', '49A1A', '49A1B', '49B1', '49B3', '49C1', '50A1', '50B1', ...]])" - ] - } - ], - "prompt_number": 5 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "df.index.names" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 6, - "text": [ - "FrozenList(['geo', 'sex', 'agecat', 'type', 'sector', 'stat', 'contract', 'dim', 'bedrijfstak\\time'])" - ] - } - ], - "prompt_number": 6 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "timeit df.xs('2024', level='agecat')" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "10 loops, best of 3: 22.1 ms per loop\n" - ] - } - ], - "prompt_number": 7 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "# peaks at 500Mb RAM !\n", - "timeit pd.read_hdf('c:/tmp/kh/rgl_df_fixed.h5', 'rgl')" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "1 loops, best of 3: 286 ms per loop\n" - ] - } - ], - "prompt_number": 9 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "# timeit pd.read_csv('c:/tmp/kh/rgl.csv', index_col=list(range(9)))\n", - "# more than 10s !!" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 10 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "timeit df.loc[(slice(None), slice(None), slice('2024', '3539')),:]" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "10 loops, best of 3: 85.4 ms per loop\n" - ] - } - ], - "prompt_number": 11 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "timeit df.loc(axis=0)[:, :, '2024':'3539']" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "10 loops, best of 3: 84.8 ms per loop\n" - ] - } - ], - "prompt_number": 12 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "df.loc(axis=0)[:, :, '2024':'3539'].sum().sum()" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 19, - "text": [ - "218329668937901.34" - ] - } - ], - "prompt_number": 19 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "timeit df.loc(axis=0)[:, :, '2024':'3539'].sum().sum()" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "1 loops, best of 3: 240 ms per loop\n" - ] - } - ], - "prompt_number": 20 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "s = df.stack()" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 14 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "del df" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 21 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "timeit s.loc[:, :, '2024':'3539']" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "1 loops, best of 3: 1.43 s per loop\n" - ] - } - ], - "prompt_number": 22 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "del s" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 23 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import larray as la" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 3 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "a = la.read_hdf('c:/tmp/kh/rgl_la.h5', 'rgl')" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 7 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "timeit a.filter(agecat='2024:3539')" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "10000 loops, best of 3: 129 \u00b5s per loop\n" - ] - } - ], - "prompt_number": 27 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "a.filter(agecat='2024:3539')" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 28, - "text": [ - "\n", - "geo | sex | agecat | type | sector | stat | contract | dim | bedrijfstak\\time | ...\n", - " T | F | 2024 | A | A | R | D | G | 01A1 | ...\n", - " T | F | 2024 | A | A | R | D | G | 02A1 | ...\n", - " T | F | 2024 | A | A | R | D | G | 03A1 | ...\n", - " T | F | 2024 | A | A | R | D | G | 05A1 | ...\n", - " T | F | 2024 | A | A | R | D | G | 08A1 | ...\n", - "... | ... | ... | ... | ... | ... | ... | ... | ... | ...\n", - " T | H | 3539 | Z | X | U | V | K | 98A1 | ...\n", - " T | H | 3539 | Z | X | U | V | K | 99A9 | ...\n", - " T | H | 3539 | Z | X | U | V | K | MO | ...\n", - " T | H | 3539 | Z | X | U | V | K | ONT | ...\n", - " T | H | 3539 | Z | X | U | V | K | PH | ..." - ] - } - ], - "prompt_number": 28 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "import numpy as np" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 31 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "a[np.isnan(a)] = 0" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 33 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "a.sum()" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 34, - "text": [ - "465606507083673.5" - ] - } - ], - "prompt_number": 34 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "timeit a.sum()" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "1 loops, best of 3: 385 ms per loop\n" - ] - } - ], - "prompt_number": 35 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "# peaks at 5Gb RAM !\n", - "timeit la.read_hdf('c:/tmp/kh/rgl_la.h5', 'rgl')" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "1 loops, best of 3: 6.4 s per loop\n" - ] - } - ], - "prompt_number": 4 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "# peaks at 10Gb RAM !\n", - "timeit la.read_hdf('c:/tmp/kh/rgl_df_fixed.h5', 'rgl')" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "1 loops, best of 3: 12.2 s per loop\n" - ] - } - ], - "prompt_number": 39 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [], - "language": "python", - "metadata": {}, - "outputs": [] - } - ], - "metadata": {} - } - ] -} \ No newline at end of file diff --git a/doc/notebooks/Python functions.ipynb b/doc/notebooks/Python functions.ipynb deleted file mode 100644 index b512eeb7e..000000000 --- a/doc/notebooks/Python functions.ipynb +++ /dev/null @@ -1,750 +0,0 @@ -{ - "metadata": { - "name": "", - "signature": "sha256:277ee028bef695ea969b5f8bdf880f84b2dcc1ebc46a5f8503377718bdd4848b" - }, - "nbformat": 3, - "nbformat_minor": 0, - "worksheets": [ - { - "cells": [ - { - "cell_type": "heading", - "level": 1, - "metadata": {}, - "source": [ - "Defining a function" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def plus(a, b):\n", - " \"\"\"adds a and b\"\"\"\n", - " return a + b" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 1 - }, - { - "cell_type": "heading", - "level": 1, - "metadata": {}, - "source": [ - "Using it" - ] - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "In a simple call, arguments are assigned by position (we call them positional arguments)" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plus(1, 2)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 2, - "text": [ - "3" - ] - } - ], - "prompt_number": 2 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "All required arguments need to be provided" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plus(1)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "plus() missing 1 required positional argument: 'b'", - "output_type": "pyerr", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mplus\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;31mTypeError\u001b[0m: plus() missing 1 required positional argument: 'b'" - ] - } - ], - "prompt_number": 3 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "We can also use the argument names as _keywords_ (we call them keyword arguments)" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plus(a=1, b=2)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 4, - "text": [ - "3" - ] - } - ], - "prompt_number": 4 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "in that case order does not matter" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plus(b=2, a=1)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 5, - "text": [ - "3" - ] - } - ], - "prompt_number": 5 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "or even mix positional arguments and keyword arguments" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plus(2, b=3)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 6, - "text": [ - "5" - ] - } - ], - "prompt_number": 6 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "but keyword arguments must always come AFTER positional arguments" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plus(a=1, 3)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "non-keyword arg after keyword arg (, line 1)", - "output_type": "pyerr", - "traceback": [ - "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m plus(a=1, 3)\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m non-keyword arg after keyword arg\n" - ] - } - ], - "prompt_number": 7 - }, - { - "cell_type": "heading", - "level": 1, - "metadata": {}, - "source": [ - "Default values for arguments" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def plus(a, b=1):\n", - " \"\"\"\n", - " adds a and b\n", - " b defaults to 1 if not provided\n", - " \"\"\"\n", - " return a + b" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 8 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "all the above calls are still valid" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plus(1, 2)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 9, - "text": [ - "3" - ] - } - ], - "prompt_number": 9 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "but you can now omit arguments which have a default value" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plus(2)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 10, - "text": [ - "3" - ] - } - ], - "prompt_number": 10 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "arguments with default values need to be _defined_ after normal (required) arguments" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def plus(a=1, b):\n", - " return a + b" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "non-default argument follows default argument (, line 1)", - "output_type": "pyerr", - "traceback": [ - "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m def plus(a=1, b):\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m non-default argument follows default argument\n" - ] - } - ], - "prompt_number": 11 - }, - { - "cell_type": "heading", - "level": 2, - "metadata": {}, - "source": [ - "Variable number of (positional) arguments" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def plusall(a, b, *args, c=5):\n", - " print(args)\n", - " args[2] = 1\n", - " return sum(args) + c" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 12 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plusall(1, 2, 3, 4, c=8)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "(3, 4)\n" - ] - }, - { - "ename": "TypeError", - "evalue": "'tuple' object does not support item assignment", - "output_type": "pyerr", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mplusall\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m4\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mc\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m8\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;32m\u001b[0m in \u001b[0;36mplusall\u001b[1;34m(a, b, c, *args)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mplusall\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mc\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0msum\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mc\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" - ] - } - ], - "prompt_number": 13 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plusall(1, 2, c=5)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "()\n" - ] - }, - { - "ename": "TypeError", - "evalue": "'tuple' object does not support item assignment", - "output_type": "pyerr", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mplusall\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mc\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;32m\u001b[0m in \u001b[0;36mplusall\u001b[1;34m(a, b, c, *args)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mplusall\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mc\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0msum\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mc\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" - ] - } - ], - "prompt_number": 14 - }, - { - "cell_type": "heading", - "level": 2, - "metadata": {}, - "source": [ - "Variable number of keyword arguments" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def plusall(*a, b=1, c=1, **kw):\n", - " print(\"args\", a)\n", - " print(\"kwargs\", kw)\n", - " return sum(a) + sum(kw.values()) + b + c\n", - " " - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 15 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "plusall(1, 2, 3, a=4, b=5)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "output_type": "stream", - "stream": "stdout", - "text": [ - "args (1, 2, 3)\n", - "kwargs {'a': 4}\n" - ] - }, - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 16, - "text": [ - "16" - ] - } - ], - "prompt_number": 16 - }, - { - "cell_type": "heading", - "level": 1, - "metadata": {}, - "source": [ - "Inside functions" - ] - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "variables that you _create_ inside a function are local to the function by default" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def test(a):\n", - " y = 2 + a" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 17 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "test(1)" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 18 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "y" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'y' is not defined", - "output_type": "pyerr", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;31mNameError\u001b[0m: name 'y' is not defined" - ] - } - ], - "prompt_number": 19 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "variables that you define outside of a function are global (accessible outside of any function and within all functions)" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def test(a):\n", - " return x + a" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 20 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "x = 10" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 21 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "test(1)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 22, - "text": [ - "11" - ] - } - ], - "prompt_number": 22 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "the value of the global variable is the one at the time of the call" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "x = 1" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 23 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "test(1)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 24, - "text": [ - "2" - ] - } - ], - "prompt_number": 24 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "you _can_ create global variables within functions..." - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def test(a):\n", - " global y\n", - " y = 2 + a" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 25 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "test(1)" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 26 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "y" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 27, - "text": [ - "3" - ] - } - ], - "prompt_number": 27 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "... but this should be _avoided_ as much as possible. In most cases, you can replace them by the more robust:" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def test(a):\n", - " return 2 + a" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 28 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "z = test(1)" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 29 - }, - { - "cell_type": "heading", - "level": 3, - "metadata": {}, - "source": [ - "z is a global variable" - ] - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "z" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 30, - "text": [ - "3" - ] - } - ], - "prompt_number": 30 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "def testz(a):\n", - " return a + z" - ], - "language": "python", - "metadata": {}, - "outputs": [], - "prompt_number": 31 - }, - { - "cell_type": "code", - "collapsed": false, - "input": [ - "testz(1)" - ], - "language": "python", - "metadata": {}, - "outputs": [ - { - "metadata": {}, - "output_type": "pyout", - "prompt_number": 32, - "text": [ - "4" - ] - } - ], - "prompt_number": 32 - } - ], - "metadata": {} - } - ] -} \ No newline at end of file diff --git a/doc/source/_static/compare.png b/doc/source/_static/compare.png new file mode 100644 index 000000000..58f27ef16 Binary files /dev/null and b/doc/source/_static/compare.png differ diff --git a/doc/source/_static/editor.png b/doc/source/_static/editor.png new file mode 100644 index 000000000..087d3091b Binary files /dev/null and b/doc/source/_static/editor.png differ diff --git a/doc/source/_static/editor_new.png b/doc/source/_static/editor_new.png new file mode 100644 index 000000000..86f66316e Binary files /dev/null and b/doc/source/_static/editor_new.png differ diff --git a/doc/source/_static/larray-logo.png b/doc/source/_static/larray-logo.png new file mode 100644 index 000000000..1b8e4fc2e Binary files /dev/null and b/doc/source/_static/larray-logo.png differ diff --git a/doc/source/_static/larray-logo.svg b/doc/source/_static/larray-logo.svg new file mode 100644 index 000000000..1dba36628 --- /dev/null +++ b/doc/source/_static/larray-logo.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LArray + + diff --git a/doc/source/_static/menu_windows.png b/doc/source/_static/menu_windows.png new file mode 100644 index 000000000..fd170f27f Binary files /dev/null and b/doc/source/_static/menu_windows.png differ diff --git a/doc/source/api.rst b/doc/source/api.rst index f2f9e9d0c..05d2e8091 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -1,14 +1,618 @@ +.. _start_api: + +############# API Reference +############# + +.. see larray/__init__.py +.. currentmodule:: larray + +.. _api-axis: + +Axis +==== + +.. autosummary:: + :toctree: _generated/ + + Axis + +Exploring +--------- + +=========================== ============================================================== +Axis.name Name of the axis. None in the case of an anonymous axis. +--------------------------- -------------------------------------------------------------- +:attr:`Axis.labels` Labels of the axis. +--------------------------- -------------------------------------------------------------- +:attr:`Axis.labels_summary` Short representation of the labels. +=========================== ============================================================== + +Copying +------- + +.. autosummary:: + :toctree: _generated/ + + Axis.copy + +Searching +--------- + +.. autosummary:: + :toctree: _generated/ + + Axis.index + Axis.containing + Axis.startingwith + Axis.endingwith + Axis.matching + +Modifying/Selecting/Searching +----------------------------- + +.. autosummary:: + :toctree: _generated/ + + Axis.__getitem__ + Axis.i + Axis.by + Axis.rename + Axis.subaxis + Axis.extend + Axis.insert + Axis.replace + Axis.union + Axis.intersection + Axis.difference + Axis.align + Axis.split + +Testing +------- + +.. autosummary:: + :toctree: _generated/ + + Axis.iscompatible + Axis.equals + +.. _api-group: + +Group +===== + +IGroup +------ + +.. autosummary:: + :toctree: _generated/ + + IGroup + +.. autosummary:: + :toctree: _generated/ + + IGroup.named + IGroup.with_axis + IGroup.by + IGroup.translate + IGroup.union + IGroup.intersection + IGroup.difference + IGroup.containing + IGroup.startingwith + IGroup.endingwith + IGroup.matching + +LGroup +------ + +.. autosummary:: + :toctree: _generated/ + + LGroup + +.. autosummary:: + :toctree: _generated/ + + LGroup.named + LGroup.with_axis + LGroup.by + LGroup.translate + LGroup.union + LGroup.intersection + LGroup.difference + LGroup.containing + LGroup.startingwith + LGroup.endingwith + LGroup.matching + +.. _api-set: + +LSet +==== + +.. autosummary:: + :toctree: _generated/ + + LSet + +.. _api-axiscollection: + +AxisCollection +============== + +.. autosummary:: + :toctree: _generated/ + + AxisCollection + +.. autosummary:: + :toctree: _generated/ + + AxisCollection.names + AxisCollection.display_names + AxisCollection.labels + AxisCollection.shape + AxisCollection.size + AxisCollection.info + AxisCollection.copy + +Searching +--------- + +.. autosummary:: + :toctree: _generated/ + + AxisCollection.keys + AxisCollection.index + AxisCollection.translate_full_key + AxisCollection.axis_id + AxisCollection.ids + +Modifying/Selecting +------------------- + +.. autosummary:: + :toctree: _generated/ + + AxisCollection.get + AxisCollection.get_by_pos + AxisCollection.get_all + AxisCollection.pop + AxisCollection.append + AxisCollection.extend + AxisCollection.insert + AxisCollection.replace + AxisCollection.without + AxisCollection.combine_axes + AxisCollection.split_axes + AxisCollection.align + +Testing +------- + +.. autosummary:: + :toctree: _generated/ + + AxisCollection.isaxis + AxisCollection.check_compatible + +.. _api-larray: + +LArray +====== + +* :ref:`la_overview` +* :ref:`la_creation_func` +* :ref:`la_copying` +* :ref:`la_inspecting` +* :ref:`la_selecting` +* :ref:`la_axes_labels` +* :ref:`la_agg` +* :ref:`la_sorting` +* :ref:`la_reshaping` +* :ref:`la_testing` +* :ref:`la_op` +* :ref:`la_misc` +* :ref:`la_to_pandas` +* :ref:`la_plotting` + + +.. _la_overview: + +Overview +-------- + +.. autosummary:: + :toctree: _generated/ + + LArray + +.. _la_creation_func: + +Array Creation Functions +------------------------ + +.. autosummary:: + :toctree: _generated/ + + sequence + ndtest + zeros + zeros_like + ones + ones_like + empty + empty_like + full + full_like + +.. _la_copying: + +Copying +------- + +.. autosummary:: + :toctree: _generated/ + + LArray.copy + +.. _la_inspecting: + +Inspecting +---------- + +=================== ============================================================== +LArray.data Data of the array (Numpy ndarray) +------------------- -------------------------------------------------------------- +LArray.axes Axes of the array (AxisCollection) +------------------- -------------------------------------------------------------- +LArray.title Title of the array (str) +=================== ============================================================== + +.. autosummary:: + :toctree: _generated/ + + LArray.info + LArray.shape + LArray.ndim + LArray.dtype + LArray.size + LArray.nbytes + LArray.memory_used + LArray.astype + +.. _la_selecting: + +Modifying/Selecting +------------------- + +.. autosummary:: + :toctree: _generated/ + + LArray.i + LArray.points + LArray.ipoints + LArray.set + LArray.drop_labels + LArray.filter + +.. _la_axes_labels: + +Changing Axes or Labels +----------------------- + +.. autosummary:: + :toctree: _generated/ + + LArray.set_axes + LArray.rename + LArray.set_labels + LArray.combine_axes + LArray.split_axes + +.. _la_agg: + +Aggregation Functions +--------------------- + +.. autosummary:: + :toctree: _generated/ + + LArray.sum + LArray.sum_by + LArray.prod + LArray.prod_by + LArray.cumsum + LArray.cumprod + LArray.mean + LArray.mean_by + LArray.median + LArray.median_by + LArray.var + LArray.var_by + LArray.std + LArray.std_by + LArray.percentile + LArray.percentile_by + LArray.ptp + LArray.with_total + LArray.percent + LArray.growth_rate + LArray.describe + LArray.describe_by + +.. _la_sorting: + +Sorting +------- + +.. autosummary:: + :toctree: _generated/ + + LArray.sort_axes + LArray.sort_values + LArray.labelsofsorted + LArray.indicesofsorted + +.. _la_reshaping: + +Reshaping/Extending/Reordering +------------------------------ + +.. autosummary:: + :toctree: _generated/ + + LArray.reshape + LArray.reshape_like + LArray.compact + LArray.reindex + LArray.transpose + LArray.expand + LArray.prepend + LArray.append + LArray.extend + LArray.insert + LArray.broadcast_with + LArray.align + +.. _la_testing: + +Testing/Searching +----------------- + +.. autosummary:: + :toctree: _generated/ + + LArray.equals + LArray.nonzero + LArray.all + LArray.all_by + LArray.any + LArray.any_by + LArray.min + LArray.min_by + LArray.max + LArray.max_by + LArray.labelofmin + LArray.indexofmin + LArray.labelofmax + LArray.indexofmax + +.. _la_op: + +Operators +--------- + +=================================================== ============================== +:py:meth:`@ ` Matrix multiplication +=================================================== ============================== + +.. _la_misc: + +Miscellaneous +------------- + +.. autosummary:: + :toctree: _generated/ + + LArray.ratio + LArray.rationot0 + LArray.divnot0 + LArray.clip + LArray.shift + LArray.diff + LArray.to_clipboard + round + floor + ceil + trunc + sqrt + absolute + fabs + where + isnan + isinf + nan_to_num + +.. _la_to_pandas: + +Converting to Pandas objects +---------------------------- + +.. autosummary:: + :toctree: _generated/ + + LArray.to_series + LArray.to_frame + +.. _la_plotting: + +Plotting +-------- + +.. autosummary:: + :toctree: _generated/ + + LArray.plot + +.. _api-IO: + +Input/Output +============ + +Read +---- + +.. autosummary:: + :toctree: _generated/ + + read_csv + read_tsv + read_excel + read_hdf + read_eurostat + read_sas + +Write +----- + +.. autosummary:: + :toctree: _generated/ + + LArray.to_csv + LArray.to_excel + LArray.to_hdf + +Excel +===== + +.. autosummary:: + :toctree: _generated/ + + open_excel + +.. autosummary:: + :toctree: _generated/ + + Workbook + Workbook.sheet_names + Workbook.save + Workbook.close + +.. _api-misc: + +Miscellaneous ============= -.. automodule:: larray - :members: +.. autosummary:: + :toctree: _generated/ + + aslarray + from_frame + labels_array + element_equal + union + stack + identity + diag + eye + ipfp + +.. _api-session: + +Session +======= + +.. autosummary:: + :toctree: _generated/ + + Session + arrays + local_arrays + global_arrays + load_example_data + +Exploring +--------- + +.. autosummary:: + :toctree: _generated/ + + Session.names + Session.keys + Session.values + Session.items + Session.summary + +Copying +------- + +.. autosummary:: + :toctree: _generated/ + + Session.copy + +Testing +------- + +.. autosummary:: + :toctree: _generated/ + + Session.array_equals + Session.equals + +Selecting +--------- + +.. autosummary:: + :toctree: _generated/ + + Session.get + +Modifying +--------- + +.. autosummary:: + :toctree: _generated/ + + Session.add + Session.get + Session.apply + Session.transpose + +Filtering/Cleaning +------------------ + +.. autosummary:: + :toctree: _generated/ + + Session.filter + Session.compact + +Load/Save +--------- + +.. autosummary:: + :toctree: _generated/ + + Session.load + Session.save + Session.to_csv + Session.to_excel + Session.to_hdf + Session.to_pickle + +.. _api-editor: -.. autoclass:: larray.Axis - :members: +Editor +====== -.. autoclass:: larray.LGroup - :members: +.. autosummary:: + :toctree: _generated/ -.. autoclass:: larray.LArray - :members: + view + edit + compare diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 80ce32b1b..04fd96e56 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -1,9 +1,375 @@ -.. highlight:: yaml - -Change log +Change log ########## +Version 0.28 +============ + +Released on 2018-03-15. + +.. include:: ./changes/version_0_28.rst.inc + + +Version 0.27 +============ + +Released on 2017-11-30. + +.. include:: ./changes/version_0_27.rst.inc + + +Version 0.26.1 +============== + +Released on 2017-10-25. + +.. include:: ./changes/version_0_26_1.rst.inc + + +Version 0.26 +============ + +Released on 2017-10-13. + +.. include:: ./changes/version_0_26.rst.inc + + +Version 0.25.2 +============== + +Released on 2017-09-06. + +.. include:: ./changes/version_0_25_2.rst.inc + + +Version 0.25.1 +============== + +Released on 2017-09-04. + +.. include:: ./changes/version_0_25_1.rst.inc + + +Version 0.25 +============ + +Released on 2017-08-22. + +.. include:: ./changes/version_0_25.rst.inc + + +Version 0.24.1 +============== + +Released on 2017-06-14. + +.. include:: ./changes/version_0_24_1.rst.inc + + +Version 0.24 +============ + +Released on 2017-06-14. + +.. include:: ./changes/version_0_24.rst.inc + + +Version 0.23 +============ + +Released on 2017-05-30. + +.. include:: ./changes/version_0_23.rst.inc + + +Version 0.22 +============ + +Released on 2017-05-11. + +.. include:: ./changes/version_0_22.rst.inc + + +Version 0.21 +============ + +Released on 2017-03-28. + +.. include:: ./changes/version_0_21.rst.inc + + +Version 0.20 +============ + +Released on 2017-02-09. + +.. include:: changes/version_0_20.rst.inc + + +Version 0.19 +============ + +Released on 2017-01-19. + +.. include:: changes/version_0_19.rst.inc + + +Version 0.18 +============ + +Released on 2016-12-20. + +.. include:: changes/version_0_18.rst.inc + + +Version 0.17 +============ + +Released on 2016-11-29. + +.. include:: changes/version_0_17.rst.inc + + +Version 0.16.1 +============== + +Released on 2016-11-04. + +.. include:: changes/version_0_16_1.rst.inc + + +Version 0.16 +============ + +Released on 2016-10-26. + +.. include:: changes/version_0_16.rst.inc + + +Version 0.15 +============ + +Released on 2016-09-23. + +.. include:: changes/version_0_15.rst.inc + + +Version 0.14.1 +============== + +Released on 2016-08-12. + +.. include:: changes/version_0_14_1.rst.inc + + +Version 0.14 +============ + +Released on 2016-08-10. + +.. include:: changes/version_0_14.rst.inc + + +Version 0.13 +============ + +Released on 2016-07-11. + +.. include:: changes/version_0_13.rst.inc + + +Version 0.12 +============ + +Released on 2016-06-21. + +.. include:: changes/version_0_12.rst.inc + + +Version 0.11.1 +============== + +Released on 2016-05-25. + +.. include:: changes/version_0_11_1.rst.inc + + +Version 0.11 +============ + +Released on 2016-05-25. + +.. include:: changes/version_0_11.rst.inc + + +Version 0.10.1 +============== + +Released on 2016-03-25. + +.. include:: changes/version_0_10_1.rst.inc + + +Version 0.10 +============ + +Released on 2016-03-22. + +.. include:: changes/version_0_10.rst.inc + + +Version 0.9.2 +============= + +Released on 2016-03-02. + +.. include:: changes/version_0_9_2.rst.inc + + +Version 0.9.1 +============= + +Released on 2016-03-01. + +.. include:: changes/version_0_9_1.rst.inc + + +Version 0.9 +=========== + +Released on 2016-02-25. + +.. include:: changes/version_0_9.rst.inc + + +Version 0.8.1 +============= + +Released on 2016-02-24. + +.. include:: changes/version_0_8_1.rst.inc + + +Version 0.8 +=========== + +Released on 2016-02-16. + +.. include:: changes/version_0_8.rst.inc + + +Version 0.7.1 +============= + +Released on 2016-01-29. + +.. include:: changes/version_0_7_1.rst.inc + + +Version 0.7 +=========== + +Released on 2016-01-26. + +.. include:: changes/version_0_7.rst.inc + + +Version 0.6.1 +============= + +Released on 2016-01-13. + +.. include:: changes/version_0_6_1.rst.inc + + +Version 0.6 +=========== + +Released on 2016-01-12. + +.. include:: changes/version_0_6.rst.inc + + +Version 0.5 +=========== + +Released on 2015-12-15. + +.. include:: changes/version_0_5.rst.inc + + +Version 0.4 +=========== + +Released on 2015-12-09. + +.. include:: changes/version_0_4.rst.inc + + +Version 0.3 +=========== + +Released on 2015-11-26. + +.. include:: changes/version_0_3.rst.inc + + +Version 0.2.6 +============= + +Released on 2015-11-24. + +.. include:: changes/version_0_2_6.rst.inc + + +Version 0.2.5 +============= + +Released on 2015-10-29. + +.. include:: changes/version_0_2_5.rst.inc + + +Version 0.2.4 +============= + +Released on 2015-10-27. + +.. include:: changes/version_0_2_4.rst.inc + + +Version 0.2.3 +============= + +Released on 2015-10-19. + +.. include:: changes/version_0_2_3.rst.inc + + +Version 0.2.2 +============= + +Released on 2015-10-15. + +.. include:: changes/version_0_2_2.rst.inc + + +Version 0.2.1 +============= + +Released on 2015-10-14. + +.. include:: changes/version_0_2_1.rst.inc + + +Version 0.2 +=========== + +Released on 2015-10-13. + +.. include:: changes/version_0_2.rst.inc + + Version 0.1 =========== -Released on 2014-10-22. \ No newline at end of file +Released on 2014-10-22. diff --git a/doc/source/changes/template.rst.inc b/doc/source/changes/template.rst.inc index 40d5a3454..101969eb7 100644 --- a/doc/source/changes/template.rst.inc +++ b/doc/source/changes/template.rst.inc @@ -1,10 +1,23 @@ -New features +Syntax changes +-------------- + +* new syntax + + +Backward incompatible changes +----------------------------- + +* backward incompatible changes + + +New features ------------ * added a feature (see the :ref:`miscellaneous section ` for details). * added another feature. + .. _misc: Miscellaneous improvements @@ -12,6 +25,7 @@ Miscellaneous improvements * improved something. + Fixes ----- diff --git a/doc/source/changes/version_0_10.rst.inc b/doc/source/changes/version_0_10.rst.inc new file mode 100644 index 000000000..eac31965b --- /dev/null +++ b/doc/source/changes/version_0_10.rst.inc @@ -0,0 +1,31 @@ +Core +---- + +* implemented dropna argument for to_csv, to_frame and to_series to avoid writing lines with either 'all' or 'any' + NA values. +* implemented read_sas. Needs pandas >= 0.18 (though it seems still buggy on some files). +* implemented experimental support for __getattr__ and __setattr__ on LArray. One can use arr.H instead of arr['M']. + It only works for single string labels though (not for slices or list of labels nor integer labels). Not sure it is a + good idea :). + +* implemented Session +-`*`/ + Eg. sess1 - sess2 will compute the difference on each array present in either session. If an array is present in one + session and not in the other, it is replaced by "NaN". +* added .nbytes property to LArray objects (to know how many bytes of memory the array uses) + +* made sort_axis accept a tuple of axes +* raises an error on a.i[tuple_with_len_greater_than_array_ndim] +* slightly better support for axes with no name (no, still no complete support yet ;-)) +* improved AxisCollection: implemented __delitem__(slice), __setitem__(list), __setitem__(slice) +* fixed exception on AxisCollection.index(invalid_index) +* better docstrings for a few functions +* misc code cleanups, refactoring & improved tests + +Editor +------ + +* added .dirty property on ArrayEditorWidget +* fixed viewing arrays with "inf" (infinite) +* fixed a few edge cases for the ndigit detection code +* fixed colors in some cases in edit() +* made copy-paste of large regions faster in some cases diff --git a/doc/source/changes/version_0_10_1.rst.inc b/doc/source/changes/version_0_10_1.rst.inc new file mode 100644 index 000000000..ba81fbe5c --- /dev/null +++ b/doc/source/changes/version_0_10_1.rst.inc @@ -0,0 +1,11 @@ +New features +------------ + +* A single change in this release: a much more powerful to_excel function which (by default) use Excel itself to write + files. Additional functionality include: + + - write in an existing file without overwriting existing data/sheet/… + - write at a precise position + - view an array in a live Excel instance (a new OR an existing workbook) + + See :meth:`~larray.LArray.to_excel` documentation for details. diff --git a/doc/source/changes/version_0_11.rst.inc b/doc/source/changes/version_0_11.rst.inc new file mode 100644 index 000000000..046e684ba --- /dev/null +++ b/doc/source/changes/version_0_11.rst.inc @@ -0,0 +1,276 @@ +Viewer +------ + +* implemented "Copy to Excel" in context menu (Ctrl+E), to open the selection in a new Excel sheet directly, without + the need to use paste. If nothing is selected, copies the whole array. +* when nothing is selected, Ctrl C selects & copies the whole array to the clipboard. +* when nothing is selected, Ctrl V paste at top-left corner +* implemented view(dict_with_array_values) + + >>> view({'a': array1, 'b': array2}) + +* fixed copy (ctrl-C) when viewing a 2D array: it did not include labels from the first axis in that case + + +Core +---- + +* implemented LArray.growth_rate to compute the growth along an axis + + >>> sex = Axis('sex', ['M', 'F']) + >>> year = Axis('year', [2015, 2016, 2017]) + >>> a = ndrange([sex, year]).cumsum(x.year) + >>> a + sex\year | 2015 | 2016 | 2017 + M | 0 | 1 | 3 + F | 3 | 7 | 12 + >>> a.growth_rate() + sex\year | 2016 | 2017 + M | inf | 2.0 + F | 1.33333333333 | 0.714285714286 + >>> a.growth_rate(d=2) + sex\year | 2017 + M | inf + F | 3.0 + +* implemented LArray.diff (difference along an axis) + + >>> sex = Axis('sex', ['M', 'F']) + >>> xtype = Axis('type', ['type1', 'type2', 'type3']) + >>> a = ndrange([sex, xtype]).cumsum(x.type) + >>> a + sex\type | type1 | type2 | type3 + M | 0 | 1 | 3 + F | 3 | 7 | 12 + >>> a.diff() + sex\type | type2 | type3 + M | 1 | 2 + F | 4 | 5 + >>> a.diff(n=2) + sex\type | type3 + M | 1 + F | 1 + >>> a.diff(x.sex) + sex\type | type1 | type2 | type3 + F | 3 | 6 | 9 + +* implemented round() (as a nicer alias to around() and round_()) + + >>> a = ndrange(5) + 0.5 + >>> a + axis0 | 0 | 1 | 2 | 3 | 4 + | 0.5 | 1.5 | 2.5 | 3.5 | 4.5 + >>> round(a) + axis0 | 0 | 1 | 2 | 3 | 4 + | 0.0 | 2.0 | 2.0 | 4.0 | 4.0 + +* implemented Session[['list', 'of', 'str']] to get a subset of a Session + + >>> s = Session({'a': ndrange(3), 'b': ndrange(4), 'c': ndrange(5)}) + >>> s + Session(a, b, c) + >>> s['a', 'c'] + Session(a, c) + +* implemented LArray.points to do pointwise indexing instead of the default orthogonal indexing when indexing several + dimensions at the same time. + + >>> a = Axis('a', ['a1', 'a2', 'a3']) + >>> b = Axis('b', ['b1', 'b2', 'b3']) + >>> arr = ndrange((a, b)) + >>> arr + a\b | b1 | b2 | b3 + a1 | 0 | 1 | 2 + a2 | 3 | 4 | 5 + >>> arr[['a1', 'a3'], ['b1', 'b2']] + a\b | b1 | b2 + a1 | 0 | 1 + a3 | 6 | 7 + # this selects the points ('a1', 'b1') and ('a3', 'b2') + >>> arr.points[['a1', 'a3'], ['b1', 'b2']] + a,b* | 0 | 1 + | 0 | 7 + + Note that .ipoints (to do pointwise indexing with positions instead of labels – aka numpy indexing) is planned but not + functional yet. + +* made "arr1.drop_labels() * arr2" use the labels from arr2 if any + + >>> a = Axis('a', ['a1', 'a2']) + >>> b = Axis('b', ['b1', 'b2']) + >>> b2 = Axis('b', ['b2', 'b3']) + >>> arr1 = ndrange([a, b]) + >>> arr1 + a\b | b1 | b2 + a1 | 0 | 1 + a2 | 2 | 3 + >>> arr1.drop_labels(b) + a\b* | 0 | 1 + a1 | 0 | 1 + a2 | 2 | 3 + >>> arr1.drop_labels([a, b]) + a*\b* | 0 | 1 + 0 | 0 | 1 + 1 | 2 | 3 + >>> arr2 = ndrange([a, b2]) + >>> arr2 + a\b | b2 | b3 + a1 | 0 | 1 + a2 | 2 | 3 + >>> arr1 * arr2 + Traceback (most recent call last): + ... + ValueError: incompatible axes: + Axis('b', ['b2', 'b3']) + vs + Axis('b', ['b1', 'b2']) + >>> arr1 * arr2.drop_labels() + a\b | b1 | b2 + a1 | 0 | 1 + a2 | 4 | 9 + # in versions < 0.11, it used to return: + # >>> arr1.drop_labels() * arr2 + # a*\b* | 0 | 1 + # 0 | 0 | 1 + # 1 | 2 | 3 + >>> arr1.drop_labels() * arr2 + a\b | b2 | b3 + a1 | 0 | 1 + a2 | 4 | 9 + >>> arr1.drop_labels('a') * arr2.drop_labels('b') + a\b | b1 | b2 + a1 | 0 | 1 + a2 | 4 | 9 + +* made .plot a property, like in Pandas, so that we can do stuff like: + + >>> a.plot.bar() + # instead of + >>> a.plot(kind='bar') + +* made labels from different types not match against each other even if their value is the same. This might break some + code but it is both more efficient and more convenient in some cases, so let us see how it goes: + + >>> a = ndrange(4) + >>> a + axis0 | 0 | 1 | 2 | 3 + | 0 | 1 | 2 | 3 + >>> a[1] + 1 + >>> # This used to "work" (and return 1) + >>> a[True] + … + ValueError: True is not a valid label for any axis + + >>> a[1.0] + … + ValueError: 1.0 is not a valid label for any axis + +* implemented read_csv(dialect='liam2') to read .csv files formatted like in LIAM2 (with the axes names on a separate + line than the last axis labels) + +* implemented Session[boolean LArray] + + >>> a = ndrange(3) + >>> b = ndrange(4) + >>> s1 = Session({'a': a, 'b': b}) + >>> s2 = Session({'a': a + 1, 'b': b}) + >>> s1 == s2 + name | a | b + | False | True + >>> s1[s1 == s2] + Session(b) + >>> s1[s1 != s2] + Session(a) + +* implemented experimental support for creating an array sequentially. Comments on the name of the function and syntax + (especially compared to ndrange) would be appreciated. + + >>> year = Axis('year', range(2016, 2020)) + >>> sex = Axis('sex', ['M', 'F']) + >>> create_sequential(year) + year | 2016 | 2017 | 2018 | 2019 + | 0 | 1 | 2 | 3 + >>> create_sequential(year, 1.0, 0.1) + year | 2016 | 2017 | 2018 | 2019 + | 1.0 | 1.1 | 1.2 | 1.3 + >>> create_sequential(year, 1.0, mult=1.1) + year | 2016 | 2017 | 2018 | 2019 + | 1.0 | 1.1 | 1.21 | 1.331 + >>> inc = LArray([1, 2], [sex]) + >>> inc + sex | M | F + | 1 | 2 + >>> create_sequential(year, 1.0, inc) + sex\year | 2016 | 2017 | 2018 | 2019 + M | 1.0 | 2.0 | 3.0 | 4.0 + F | 1.0 | 3.0 | 5.0 | 7.0 + >>> mult = LArray([2, 3], [sex]) + >>> mult + sex | M | F + | 2 | 3 + >>> create_sequential(year, 1.0, mult=mult) + sex\year | 2016 | 2017 | 2018 | 2019 + M | 1.0 | 2.0 | 4.0 | 8.0 + F | 1.0 | 3.0 | 9.0 | 27.0 + >>> initial = LArray([3, 4], [sex]) + >>> initial + sex | M | F + | 3 | 4 + >>> create_sequential(year, initial, inc, mult) + sex\year | 2016 | 2017 | 2018 | 2019 + M | 3 | 7 | 15 | 31 + F | 4 | 14 | 44 | 134 + >>> def modify(prev_value): + ... return prev_value / 2 + >>> create_sequential(year, 8, func=modify) + year | 2016 | 2017 | 2018 | 2019 + | 8 | 4 | 2 | 1 + >>> create_sequential(3) + axis0* | 0 | 1 | 2 + | 0 | 1 | 2 + >>> create_sequential(x.year, axes=(sex, year)) + sex\year | 2016 | 2017 | 2018 | 2019 + M | 0 | 1 | 2 | 3 + F | 0 | 1 | 2 | 3 + +* implemented full and full_like to create arrays initialize to something else than zeros or ones + + >>> nat = Axis('nat', ['BE', 'FO']) + >>> sex = Axis('sex', ['M', 'F']) + >>> full([nat, sex], 42.0) + nat\sex | M | F + BE | 42.0 | 42.0 + FO | 42.0 | 42.0 + >>> initial_value = ndrange([sex]) + >>> initial_value + sex | M | F + | 0 | 1 + >>> full([nat, sex], initial_value) + nat\sex | M | F + BE | 0 | 1 + FO | 0 | 1 + +* performance improvements when using label keys: a[key] is faster, especially if key is large + + +Fixes +----- + +* to_excel(filepath) only closes the file if it was not open before +* removed code which forced labels from .csv files to be strings (as it caused problems in many cases, e.g. ages in + LIAM2 files) + + +Misc. stuff for completeness +---------------------------- + +* made LGroups usable in Python's builtin range() and convertible to int and float +* implemented AxisCollection.union (equivalent to AxisCollection | Axis) +* fixed boolean array keys (boolean filter) in combination with scalar keys (for other dimensions) +* fixed support for older numpy +* fixed LArray.shift(n=0) +* still more work on making arrays with anonymous axes usable (not there yet) +* added more tests +* better docstrings/error messages… +* misc. code cleanup/simplification/improved comments diff --git a/doc/source/changes/version_0_11_1.rst.inc b/doc/source/changes/version_0_11_1.rst.inc new file mode 100644 index 000000000..b45f423f8 --- /dev/null +++ b/doc/source/changes/version_0_11_1.rst.inc @@ -0,0 +1,4 @@ +Fixes +----- + +* fixed new functions full, full_like and create_sequential not being available when using `from larray import *` diff --git a/doc/source/changes/version_0_12.rst.inc b/doc/source/changes/version_0_12.rst.inc new file mode 100644 index 000000000..a7481902f --- /dev/null +++ b/doc/source/changes/version_0_12.rst.inc @@ -0,0 +1,266 @@ +New features +------------ + +* implemented boolean indexing by using axes objects: + + >>> sex = Axis('sex', 'M,F') + >>> age = Axis('age', range(5)) + >>> a = ndrange((sex, age)) + >>> a + sex\age | 0 | 1 | 2 | 3 | 4 + M | 0 | 1 | 2 | 3 | 4 + F | 5 | 6 | 7 | 8 | 9 + + >>> a[age < 3] + sex\age | 0 | 1 | 2 + M | 0 | 1 | 2 + F | 5 | 6 | 7 + + This new syntax is equivalent to (but currently much slower than): + + >>> a[age[:2]] + sex\age | 0 | 1 | 2 + M | 0 | 1 | 2 + F | 5 | 6 | 7 + + However, the power of this new syntax comes from the fact that you are not limited to scalar constants + + >>> age_limit = LArray([2, 3], sex) + >>> age_limit + sex | M | F + | 2 | 3 + + >>> a[age < age_limit] + sex,age | M,0 | M,1 | F,0 | F,1 | F,2 + | 0 | 1 | 5 | 6 | 7 + + Notice that the concerned axes are merged, so you cannot do much as much with them. For example, + `a[age < age_limit].sum(x.age)` would not work since there is no "age" axis anymore. + + To keep axes intact, one can often set the values of the corresponding cells to 0 or nan instead. + + >>> a[age < age_limit] = 0 + >>> a + sex\age | 0 | 1 | 2 | 3 | 4 + M | 0 | 0 | 2 | 3 | 4 + F | 0 | 0 | 0 | 8 | 9 + >>> # in this case, the sum *is* valid (but the mean would not -- one should use nan for that) + >>> a.sum(x.age) + sex | M | F + | 9 | 17 + + To keep axes intact, this idiom is also often useful: + + >>> b = a * (age >= age_limit) + >>> b + sex\age | 0 | 1 | 2 | 3 | 4 + M | 0 | 0 | 2 | 3 | 4 + F | 0 | 0 | 0 | 8 | 9 + + This also works with axes references (x.axis_name), though this is experimental and the filter value is only computed + as late as possible (during []), so you cannot display it before that, like you can with "real" axes. + + Using "real" axes: + + >>> filter1 = age < age_limit + >>> filter1 + age\sex | M | F + 0 | True | True + 1 | True | True + 2 | False | True + 3 | False | False + 4 | False | False + >>> a[filter1] + sex,age | M,0 | M,1 | F,0 | F,1 | F,2 + | 0 | 1 | 5 | 6 | 7 + + With axes references: + + >>> filter2 = x.age < age_limit + >>> filter2 + + >>> a[filter2] + sex,age | M,0 | M,1 | F,0 | F,1 | F,2 + | 0 | 1 | 5 | 6 | 7 + >>> a * ~filter2 + sex\age | 0 | 1 | 2 | 3 | 4 + M | 0 | 0 | 2 | 3 | 4 + F | 0 | 0 | 0 | 8 | 9 + +* implemented LArray.divnot0 + + >>> nat = Axis('nat', ['BE', 'FO']) + >>> sex = Axis('sex', ['M', 'F']) + >>> a = ndrange((nat, sex)) + >>> a + nat\sex | M | F + BE | 0 | 1 + FO | 2 | 3 + >>> b = ndrange(sex) + >>> b + sex | M | F + | 0 | 1 + >>> a / b + nat\sex | M | F + BE | nan | 1.0 + FO | inf | 3.0 + >>> a.divnot0(b) + nat\sex | M | F + BE | 0.0 | 1.0 + FO | 0.0 | 3.0 + +* implemented .named() on groups to name groups after the fact + + >>> a = ndrange(Axis('age', range(100))) + >>> a + age | 0 | 1 | 2 | 3 | 4 | 5 | 6 | ... | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | ... | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 + >>> a.sum((x.age[10:19].named('teens'), x.age[20:29].named('twenties'))) + age | 'teens' (10:19) | 'twenties' (20:29) + | 145 | 245 + +* made all array creation functions (ndrange, zeros, ones, full, LArray, …) more flexible: + + They accept a single Axis argument instead of requiring a tuple/list of them + + >>> sex = Axis('sex', 'M,F') + >>> a = ndrange(sex) + >>> a + sex | M | F + | 0 | 1 + + Shortcut definition for axes work + + >>> ndrange("a,b,c") + {0} | a | b | c + | 0 | 1 | 2 + >>> ndrange(["1:3", "d,e"]) + {0}\{1} | d | e + 1 | 0 | 1 + 2 | 2 | 3 + 3 | 4 | 5 + >>> LArray([1, 5, 7], "a,b,c") + {0} | a | b | c + | 1 | 5 | 7 + + One can mix Axis objects and ints (for axes without labels) + + >>> sex = Axis('sex', 'M,F') + >>> ndrange([sex, 3]) + sex\{1}* | 0 | 1 | 2 + M | 0 | 1 | 2 + F | 3 | 4 | 5 + +* made it possible to iterate on labels of a group (eg a slice of an Axis): + + >>> for year in a.axes.year[2010:]: + ... # do stuff + +* changed representation of anonymous axes from "axisN" (where N is the position of the axis) to "{N}". + The problem was that "axisN" was not recognizable enough as an anonymous axis, and it was thus misleading. For + example "a[x.axis0[...]]" would not work. + +* better overall support for arrays with anonymous axes or several axes with the same name + +* fixed all output functions (to_csv, to_excel, to_hdf, …) when the last axis has no name but other axes have one + +* implemented eye() which creates 2D arrays with ones on the diagonal and zeros elsewhere. + + >>> eye(sex) + sex\sex | M | F + M | 1.0 | 0.0 + F | 0.0 | 1.0 + +* implemented the @ operator to do matrix multiplication (Python3.5+ only) + +* implemented inverse() to return the (matrix) inverse of a (square) 2D array + + >>> a = eye(sex) * 2 + >>> a + sex\sex | M | F + M | 2.0 | 0.0 + F | 0.0 | 2.0 + + >>> a @ inverse(a) + sex\sex | M | F + M | 1.0 | 0.0 + F | 0.0 | 1.0 + +* implemented diag() to extract a diagonal or construct a diagonal array. + + >>> nat = Axis('nat', ['BE', 'FO']) + >>> sex = Axis('sex', ['M', 'F']) + >>> a = ndrange([nat, sex], start=1) + >>> a + nat\sex | M | F + BE | 1 | 2 + FO | 3 | 4 + >>> d = diag(a) + >>> d + nat,sex | BE,M | FO,F + | 1 | 4 + >>> diag(d) + nat\sex | M | F + BE | 1 | 0 + FO | 0 | 4 + >>> a = ndrange(sex, start=1) + >>> a + sex | M | F + | 1 | 2 + >>> diag(a) + sex\sex | M | F + M | 1 | 0 + F | 0 | 2 + + +For completeness +---------------- + +* added Axis.rename method which returns a copy of the axis with a different name and deprecate Axis._rename + +* added labels_array as a generalized version of identity (which is deprecated) + +* implemented LArray.ipoints[...] to do point selection using coordinates instead of labels (aka numpy indexing) + +* raise an error when trying to do a[key_with_more_axes_than_a] = value instead of silently ignoring extra axes. + +* allow using a single int for index_col in read_csv in addition to a list of ints + +* implemented __getitem__ for "x". You can now write stuff like: + + >>> a = ndrange((3, 4)) + >>> a[x[0][1:]] + {0}\{1}* | 0 | 1 | 2 | 3 + 1 | 4 | 5 | 6 | 7 + 2 | 8 | 9 | 10 | 11 + >>> a[x[1][2:]] + {0}*\{1} | 2 | 3 + 0 | 2 | 3 + 1 | 6 | 7 + 2 | 10 | 11 + >>> a.sum(x[0]) + {0}* | 0 | 1 | 2 | 3 + | 12 | 15 | 18 | 21 + +* produce normal axes instead of wildcard axes on LArray.points[...]. This is (much) slower but more correct/informative. + +* changed the way we store axes internally, which has several consequences + + - better overall support for anonymous axes + - better support for arrays with several axes with the same name + - small performance improvement + - the same axis object cannot be added twice in an array (one should use axis.copy() if that need arises) + - changes the way groups with an axis are displayed + +* fixed sum, min, max functions on non-LArray arguments + +* changed __repr__ for wildcard axes to not display their labels but their length + + >>> ndrange(3).axes[0] + Axis(None, 3) + +* fixed aggregates on several groups "forgetting" the name of groups which had been created using axis.all() + +* allow Axis(..., long) in addition to int (Python2 only) + +* better docstrings/tests/comments/error messages/thoughts/… diff --git a/doc/source/changes/version_0_13.rst.inc b/doc/source/changes/version_0_13.rst.inc new file mode 100644 index 000000000..22f0cd7d1 --- /dev/null +++ b/doc/source/changes/version_0_13.rst.inc @@ -0,0 +1,84 @@ +New features +------------ + +* implemented a new way to do input/output from/to Excel + + >>> a = ndrange((2, 3)) + >>> wb = open_excel('c:/tmp/y.xlsx') + # put a at A1 in Sheet1, excluding headers (labels) + >>> wb['Sheet1'] = a + # dump a at A1 in Sheet2, including headers (labels) + >>> wb['Sheet2'] = a.dump() + # save the file to disk + >>> wb.save() + # close it + >>> wb.close() + + >>> wb = open_excel('c:/tmp/y.xlsx') + # load a from the data starting at A1 in Sheet1, assuming the absence of headers. + >>> a1 = wb['Sheet1'] + # load a from the data starting at A1 in Sheet1, assuming the presence of (correctly formatted) headers. + >>> a2 = wb['Sheet2'].load() + >>> wb.close() + + >>> wb = open_excel('c:/tmp/y.xlsx') + # note that Sheet2 must exist + >>> sheet2 = wb['Sheet2'] + # write a without labels starting at C5 + >>> sheet2['C5'] = a + # write a with its labels starting at A10 + >>> sheet2['A10'] = a.dump() + + load an array with its axes information from a range. As you might have guessed, we could also use the sheet2 + variable here + + >>> b = wb['Sheet2']['A10:D12'].load() + >>> b + {0}*\{1}* | 0 | 1 | 2 + 0 | 0 | 1 | 2 + 1 | 3 | 4 | 5 + + load an array (raw data) with no axis information from a range. + + >>> c = sheet['B11:D12'] + >>> # in fact, this is not really an LArray ... + >>> c + + >>> # but it can be used as such (this is currently very experimental) + >>> c.sum(axis=0) + {0}* | 0 | 1 | 2 + | 3.0 | 5.0 | 7.0 + >>> # ... and it can be used for other stuff, like setting the formula instead of the value: + >>> c.formula = '=D10+1' + >>> # in the future, we should also be able to set font name, size, style, etc. + +* implemented LArray.rename({axis: new_name}) as well as using kwargs to rename several axes at once + + >>> nat = Axis('nat', ['BE', 'FO']) + >>> sex = Axis('sex', ['M', 'F']) + >>> a = ndrange([nat, sex]) + >>> a + nat\sex | M | F + BE | 0 | 1 + FO | 2 | 3 + >>> a.rename(nat='nat2', sex='gender') + nat2\gender | M | F + BE | 0 | 1 + FO | 2 | 3 + >>> a.rename({'nat': 'nat2', 'sex': 'gender'}) + nat2\gender | M | F + BE | 0 | 1 + FO | 2 | 3 + +* made tab-completion of axes names possible in an interactive console + +For completeness +---------------- + +* taking a subset of an array with wildcard axes now returns an array with wildcard axes + +* fixed a case where wildcard axes were considered incompatible when they actually were compatible + +* better support for anonymous axes + +* fix for obscure bugs, better doctests, cleaner implementation for a few functions, … diff --git a/doc/source/changes/version_0_14.rst.inc b/doc/source/changes/version_0_14.rst.inc new file mode 100644 index 000000000..a01d9fb62 --- /dev/null +++ b/doc/source/changes/version_0_14.rst.inc @@ -0,0 +1,149 @@ +Important warning +----------------- + +This version is not compatible with the new version of xlwings that just came +out. Consequently, upgrading to this version is different from the usual +"conda update larray". You should rather use: + + conda update larray --no-update-deps + +To get the most of this release, you should also install the "qtconsole" +package via: + + conda install qtconsole + +Viewer +------ + +* upgraded session viewer/editor to work like a super-calculator. The input box + below the array view can be used to type any expression. eg + array1.sum(x.age) / array2, which will be displayed in the viewer. + One can also type assignment commands, like: + array3 = array1.sum(x.age) / array2 + In which case, the new array will be displayed in the viewer AND added to the + session (appear on the list on the left), so that you can use it in other + expressions. + + If you have the "qtconsole" package installed (see above), that input box will be a full ipython console. This means: + - history of typed commands, + - tab-completion (for example, type "nd" and it will change to "ndrange"), + - syntax highlighting, + - calltips (show the documentation of functions when typing commands using them), + - help on functions using "?". For example, type "ndrange?" to get the full documentation about ndrange. + Use or to quit that screen !), + - etc. + + When having the "qtconsole" package installed, you might get a warning when + starting the viewer: :: + + WARNING:root:Message signing is disabled. This is insecure and not recommended! + + This is totally harmless and can be safely ignored ! + +* made view() and edit() without argument equivalent to view(local_arrays()) + and edit(local_arrays()) respectively. + +* made the viewer on large arrays start a lot faster by using a small + subset of the array to guess the number of decimals to display and whether or + not to use scientific notation. + +* improved compare(): + - added support for comparing sessions. Arrays with differences between sessions are colored in red. + - use a single array widget instead of 3. This is done by stacking arrays together to create a new dimension. This + has the following advantages: + + * the filter and scrollbars are de-facto automatically synchronized. + * any number of arrays can be compared, not just 2. All arrays are compared to the first one. + * arrays with different sets of compatible axes can be compared (eg compare an array with its mean along an axis). + + - added label to show maximum absolute difference. + +* implemented edit(session) in addition to view(session). + + +Excel support +------------- + +* added support for copying sheets via: wb['x'] = wb['y'] + if 'x' sheet already existed, it is completely overwritten. + + +Core +---- + +* improved performance. My test models run about 10% faster than with 0.13. + +* made cumsum and cumprod aggregate on the last axis by default so that the + axis does not need to be specified when there is only one. + +* implemented much better support for operations using arrays of different + types. For example, + + - fixed create_sequential when mult, inc and initial are of different types + eg create_sequential(..., initial=1, inc=0.1) had an unexpected integer + result because it always used the type of the initial value for the output + - when appending a string label to an integer axis (eg adding total to an + age axis by using with_total()), the resulting axis should have a mixed + type, and not be suddenly all string. + - stack() now supports arrays with different types. + +* made stack support arrays with different axes (the result has the union of all axes) + + +For completeness +---------------- + +Excel support +~~~~~~~~~~~~~ + +* use xlwings (ie live Excel instance) by default for all Excel input/output, + including read_excel(), session.dump and session.load/Session(filename). + This has the advantage of more coherent results among the different ways to + load/save data to Excel and that simple sessions correctly survive a + round-trip to an .xlsx workbook (ie (named) axes are detected properly). + However, given the very different library involved, we loose most options + that read_excel used to provide (courtesy of pandas.read_excel) and some + bugs were probably introduced in the conversion. + +* fixed creating a new file via open_excel() + +* fixed loading 1D arrays (ranges with height 1 or width 1) via open_excel() + +* fixed sheet['A1'] = array in some cases + +* wb.close() only really close if the workbook was not already open in Excel + when open_excel was called (so that we do not close a workbook a user is + actually viewing). + +* added support for wb.save(filename), or actually for using any relative + path, instead of a full absolute path. + +* when dumping a session to Excel, sort sheets alphabetically instead of + dumping them in a "random" order. + +* try to convert float to int in more situations + +Core +~~~~ + +* added support for using stack() without providing an axis. It creates an + anonymous wildcard axis of the correct length. + +* added aslarray() top-level function to translate anything into an LArray if + it is not already one + +* made labels_array available via `from larray import *` + +* fixed binary operations between an array and an axis where the array + appeared first (eg array > axis). Confusingly, axis < array already worked. + +* added check in "a[bool_larray_key]" to make sure key.axes are compatible + with a.axes + +* made create_sequential a lot faster when mult or inc are constants + +* made axes without name compatible with any name + (this is the equivalent of a wildcard name for labels) + +* misc cleanup/docstring improvements/improved tests/improved error messages + diff --git a/doc/source/changes/version_0_14_1.rst.inc b/doc/source/changes/version_0_14_1.rst.inc new file mode 100644 index 000000000..67d88a8d6 --- /dev/null +++ b/doc/source/changes/version_0_14_1.rst.inc @@ -0,0 +1,7 @@ +Fixes +----- + +* fixed support for loading arrays without axe names from Excel files (in that case index_col/nb_index are necessary) +* fixed using a single int for index_col in read_excel() and sheet.load() +* fixed loading empty Excel sheets via xlwings correctly (ie do not crash) +* fixed dumping a session loaded from an H5 file to Excel diff --git a/doc/source/changes/version_0_15.rst.inc b/doc/source/changes/version_0_15.rst.inc new file mode 100644 index 000000000..c123d5e17 --- /dev/null +++ b/doc/source/changes/version_0_15.rst.inc @@ -0,0 +1,69 @@ +Core +---- + +* added new methods on axes: matches, startswith, endswith + + >>> country = Axis('country', ['FR', 'BE', 'DE', 'BR']) + >>> country.matches('BE|FR') + LGroup(['FR', 'BE']) + >>> country.matches('^..$') # labels 2 characters long + LGroup(['FR', 'BE', 'DE', 'BR']) + + >>> country.startswith('B') + LGroup(['BE', 'BR']) + >>> country.endswith('R') + LGroup(['FR', 'BR']) + +* implemented set-like operations on LGroup: & (intersection), | (union), - (difference). + Slice groups do not work yet on axes references (x.) but that will come in the future… + + >>> alpha = Axis('alpha', 'a,b,c,d') + >>> alpha['a', 'b'] | alpha['c', 'd'] + LGroup(['a', 'b', 'c', 'd'], axis=…) + >>> alpha['a', 'b', 'c'] | alpha['c', 'd'] + LGroup(['a', 'b', 'c', 'd'], axis=…) + + a name is computed automatically when both operands are named + + >>> r = alpha['a', 'b'].named('ab') | alpha['c', 'd'].named('cd') + >>> r.name + 'ab | cd' + >>> r.key + ['a', 'b', 'c', 'd'] + + numeric axes work too + + >>> num = Axis('num', range(10)) + >>> num[:2] | num[8:] + num[0, 1, 2, 8, 9] + >>> num[:2] | num[5] + num[0, 1, 2, 5]) + + intersection + + >>> LGroup(['a', 'b', 'c']) & LGroup(['c', 'd']) + LGroup(['c']) + + difference + + >>> LGroup(['a', 'b', 'c']) - LGroup(['c', 'd']) + LGroup(['a', 'b']) + >>> LGroup(['a', 'b', 'c']) - 'b' + LGroup(['a', 'c']) + +* fixed loading 1D arrays using open_excel + + +Viewer +------ + +* added tooltip with the axes labels corresponding to each cell of the array viewer +* added name and dimensions of the current array to the window title bar in the session viewer +* added tooltip with each array .info() in the list of arrays of the session viewer + +* fixed eval box throwing an exception when trying to set a new variable (if qtconsole is not present) +* fixed group aggregates using LGroups defined using axes references (x.), for example: + + >>> arr.sum(x.age[:10]) + +* fixed group aggregates using anonymous axes diff --git a/doc/source/changes/version_0_16.rst.inc b/doc/source/changes/version_0_16.rst.inc new file mode 100644 index 000000000..66f8277eb --- /dev/null +++ b/doc/source/changes/version_0_16.rst.inc @@ -0,0 +1,178 @@ +Warning: this release needs to be installed using: + + conda update larray + conda update xlwings + + +New features +------------ + +* implemented support for xlwings 0.9+. This allowed us to change the way we interact with Excel: + + - by default, the Excel instance we use is configured to be both hidden and + silent (for example, it does not prompt to update/edit links). + + - by default, we now use a dedicated Excel instance for each call to + open_excel, instead of reusing any existing instance if there was any open. + In practice, it means input/output from/to Excel is more reliable and does + not risk altering any workbook you had open (except if you ask for that + explicitly). The cost of this is that it is slower by default. If you open + many different workbooks, it is recommended that you create a single Excel + instance and reuse it. This can be done with: + + >>> from larray import * + >>> import xlwings as xw + + >>> app = xw.App(visible=False, add_book=False) + >>> wb1 = open_excel('workbook1.xlsx', app=app) + # use wb1 as before + >>> wb1.close() + >>> wb2 = open_excel('workbook2.xlsx', app=app) + # use wb2 as before + >>> wb2.close() + >>> app.quit() + +* added ipfp function which does Iterative Proportional Fitting Procedure (also known as bi-proportional fitting in + statistics or RAS algorithm in economics). Note that this new function is currently not in the core module, + so it needs a specific import command: + + >>> from larray.ipfp import ipfp + + >>> a = Axis('a', 2) + >>> b = Axis('b', 2) + >>> initial = LArray([[2, 1], + ... [1, 2]], [a, b]) + >>> initial + a*\b* | 0 | 1 + 0 | 2 | 1 + 1 | 1 | 2 + >>> target_sum_along_a = LArray([2, 1], b) + >>> target_sum_along_b = LArray([1, 2], a) + >>> ipfp([target_sum_along_a, target_sum_along_b], initial, threshold=0.01) + a*\b* | 0 | 1 + 0 | 0.8450704225352113 | 0.15492957746478875 + 1 | 1.1538461538461537 | 0.8461538461538463 + +* made it possible to create arrays more succintly in some usual cases (especially for quick arrays for testing + purposes). Previously, when one created an array from scratch, he had to provide Axis object(s) (or another array). + Note that the following examples use zeros() but this change affects all array creation functions (ones, zeros, + ndrange, full, empty): + + >>> nat = Axis('nat', ['BE', 'FO']) + >>> sex = Axis('sex', ['M', 'F']) + >>> zeros([nat, sex]) + nat\sex | M | F + BE | 0.0 | 0.0 + FO | 0.0 | 0.0 + + Now, when you have axe names and axes labels but do not have/want to reuse an + existing axis, you can use this syntax: + + >>> zeros([('nat', ['BE', 'FO']), + ... ('sex', ['M', 'F'])]) + nat\sex | M | F + BE | 0.0 | 0.0 + FO | 0.0 | 0.0 + + If additionally all axe names and labels are strings (not integers or other types) which do not contain any special + character ("=", "," or ";") you can use: + + >>> zeros('nat=BE,FO;sex=M,F') + nat\sex | M | F + BE | 0.0 | 0.0 + FO | 0.0 | 0.0 + + See below (*) for some more alternate syntaxes and an explanation of how this works. + +* added additional, less error-prone syntax for stack: + + >>> nat = Axis('nat', 'BE,FO') + >>> arr1 = ones(nat) + >>> arr1 + nat | BE | FO + | 1.0 | 1.0 + >>> arr2 = zeros(nat) + >>> arr2 + nat | BE | FO + | 0.0 | 0.0 + >>> stack([('M', arr1), ('F', arr2)], 'sex') + nat\sex | H | F + BE | 1.0 | 0.0 + FO | 1.0 | 0.0 + + in addition to the still supported but discouraged (because one has to remember the order of labels): + + >>> sex = Axis('sex', ['M', 'F']) + >>> stack((arr1, arr2), sex) + nat\sex | H | F + BE | 1.0 | 0.0 + FO | 1.0 | 0.0 + +* added LArray.compact and Session.compact() to detect and remove "useless" axes + (ie axes for which values are constant over the whole axis) + + >>> a = LArray([[1, 2], [1, 2]], [Axis('sex', 'M,F'), Axis('nat', 'BE,FO')]) + >>> a + sex\nat | BE | FO + M | 1 | 2 + F | 1 | 2 + >>> a.compact() + nat | BE | FO + | 1 | 2 + +* made Session keep the order in which arrays were added to it. The main goal was to make this work: + + >>> b, a = s['b', 'a'] + + Previously, since sessions were always traversed alphabetically, this was a dangerous operation because if the keys + (a and b) were not sorted alphabetically, the result would not be in the expected order: + + s['b', 'a'] previously returned a, b instead of b, a !! + + Session.names is still sorted alphabetically though (Session.keys() is not) + +* added LArray.with_axes(axes) to return a new LArray with the same data but different axes + + >>> a = ndrange(2) + >>> a + {0}* | 0 | 1 + | 0 | 1 + >>> a.with_axes([Axis('sex', 'H,F')]) + sex | H | F + | 0 | 1 + +* changed width from which an LArray is summarized (using "...") from 80 characters to 200. + +* implemented memory_used property which displays nbytes in human-readable form + + >>> a = ndrange('sex=H,F;nat=BE,FO') + >>> a.memory_used + '16 bytes' + >>> a = ndrange(100000) + >>> a.memory_used + '390.62 Kb' + +* implemented Axis + AxisCollection + + >>> a = ndrange('sex=M,F;type=t1,t2') + >>> Axis('nat', 'BE,FO') + a.axes + AxisCollection([ + Axis('nat', ['BE', 'FO']), + Axis('sex', ['M', 'F']), + Axis('type', ['t1', 't2']) + ]) + +(*) For the curious, there are also many syntaxes supported for array creation +functions. In fact, during array creation, at any place a list or tuple of +values is expected, you can specify it using a single string, which will be +split successively at the following characters if present: ";" then "=" then +",". If you apply that algorithm to 'nat=BE,FO;sex=M,F', you get: + +1) 'nat=BE,FO;sex=M,F' +2) ('nat=BE,FO', 'sex=M,F') +3) (('nat', 'BE,FO'), ('sex', 'M,F')) +4) (('nat', ('BE', 'FO')), ('sex', ('M', 'F'))) + +Recognise this last syntax? This is the same as above, except above we replaced +some () with [] for clarity. In fact all the intermediate forms here above are +valid (and equivalent) in array creation functions. diff --git a/doc/source/changes/version_0_16_1.rst.inc b/doc/source/changes/version_0_16_1.rst.inc new file mode 100644 index 000000000..b8953e309 --- /dev/null +++ b/doc/source/changes/version_0_16_1.rst.inc @@ -0,0 +1,12 @@ +Viewer +------ + +* renamed "Ok" button in array/session viewer to "Close". +* added apply and discard buttons in session editor, which permanently apply or discard changes to the current array. + +Core +---- + +* fixed array[sequence, scalar] = value +* fixed array.to_excel() which was broken in 0.16 (by the upgrade to xlwings 0.9+). +* improved a few tests diff --git a/doc/source/changes/version_0_17.rst.inc b/doc/source/changes/version_0_17.rst.inc new file mode 100644 index 000000000..9eff2e190 --- /dev/null +++ b/doc/source/changes/version_0_17.rst.inc @@ -0,0 +1,85 @@ +Core +---- + +* added ndtest function to create n-dimensional test arrays (of given shape). Axes are named by single letters starting from 'a'. Axes labels are constructed using a '{axis_name}{label_pos}' pattern (e.g. 'a0'). + + >>> ndtest(6) + a | a0 | a1 | a2 | a3 | a4 | a5 + | 0 | 1 | 2 | 3 | 4 | 5 + >>> ndtest((2, 3)) + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 2 + a1 | 3 | 4 | 5 + >>> ndtest((2, 3), label_start=1) + a\b | b1 | b2 | b3 + a1 | 0 | 1 | 2 + a2 | 3 | 4 | 5 + +* allow naming "one-shot" groups in group aggregates. + + >>> arr = ndtest((2, 3)) + >>> arr + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 2 + a1 | 3 | 4 | 5 + >>> arr.sum('g1=b0;g2=b1,b2;g3=b0:b2') + a\b | 'g1' ('b0') | 'g2' (['b1' 'b2']) | 'g3' ('b0':'b2') + a0 | 0 | 3 | 3 + a1 | 3 | 9 | 12 + +* implemented argmin, argmax, posargmin, posargmax without an axis argument (works on the full array). + + >>> arr = ndtest((2, 3)) + >>> arr + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 2 + a1 | 3 | 4 | 5 + >>> arr.argmin() + ('a0', 'b0') + +* added preliminary code to add a title attribute to LArray. + + This needs a lot more work to be really useful though, as it can currently only be used + in the LArray() function itself and is only used in Session.summary() (see below). + There are many places where this should be used, but this is not done yet. + +* added Session.summary() which displays a list of all arrays, their dimension names and title if any. + + This can be used in combination with local_arrays() to produce some kind of codebook with all + the arrays of a function. + + >>> arr = LArray([[1, 2], [3, 4]], 'sex=M,F;nat=BE,FO', title='a test array') + >>> arr + sex\nat | BE | FO + M | 1 | 2 + F | 3 | 4 + >>> s = Session({'arr': arr}) + >>> s + Session(arr) + >>> print(s.summary()) + arr: sex, nat + a test array + +* fixed using groups from other (compatible) axis +* fixed group aggregates using groups without axis +* fixed axis[another_label_group] when said group had a non-string Axis +* fixed axis.group(another_label_group, name='a_name') (name was not set correctly) +* fixed ipfp progress message when progress is negative + + +viewer +------ + +* when setting part of an array in the console (by using e.g. arr['M'] = 10), display that array +* when typing in the console the name of an existing array, select it in the list + +* fixed missing tooltips for arrays added to the session from within the session viewer +* fixed window title (with axes info) not updating in many cases +* fixed the filters bar not being cleared when displaying a non-LArray object after an LArray object + + +misc +---- + +* improved messages in ipfp(display_progress=True) +* improved tests, docstrings, ... diff --git a/doc/source/changes/version_0_18.rst.inc b/doc/source/changes/version_0_18.rst.inc new file mode 100644 index 000000000..dc0c9c696 --- /dev/null +++ b/doc/source/changes/version_0_18.rst.inc @@ -0,0 +1,203 @@ +Major improvements +------------------ + +* the documentation (docstrings) of many functions was vastly improved (thanks to Alix) + +* implemented a new optional syntax to generate sequences of labels for axes by using patterns + + integer strings generate integers + + >>> ndrange('age=0..10') + age | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 + + you can combine letters and numbers. The number part is treated like increasing (or decreasing numbers) + + >>> ndrange('lipro=P01..P12') + lipro | P01 | P02 | P03 | P04 | P05 | P06 | P07 | P08 | P09 | P10 | P11 | P12 + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 + + letter patterns generate all combination of letters between the start and end: + + >>> ndrange('test=AA..CC') + test | AA | AB | AC | BA | BB | BC | CA | CB | CC + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 + + other characters are left intact (and should be the same on the start and end patterns: + + >>> ndrange('test=A_1..C_2') + test | A_1 | A_2 | B_1 | B_2 | C_1 | C_2 + | 0 | 1 | 2 | 3 | 4 | 5 + + this also works within Axis() + + >>> Axis('age', '0..10') + Axis('age', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + +* implemented new syntax for defining groups using strings: + + >>> arr = ndtest((3, 4)) + >>> arr + a\b | b0 | b1 | b2 | b3 + a0 | 0 | 1 | 2 | 3 + a1 | 4 | 5 | 6 | 7 + a2 | 8 | 9 | 10 | 11 + + groups can be named using ">>" instead of "=" previously + + >>> arr.sum('b1,b3 >> b13;b0:b2 >> b012') + a\b | b13 | b012 + a0 | 4 | 3 + a1 | 12 | 15 + a2 | 20 | 27 + + if some labels are ambiguous, one can specify the axis by using "axis_name[labels]": + + >>> arr.sum('b[b1,b3] >> b13;b[b0:b2] >> b012') + a\b | b13 | b012 + a0 | 4 | 3 + a1 | 12 | 15 + a2 | 20 | 27 + + groups can also be defined by position using this syntax: + + >>> arr.sum('b.i[1,3] >> b13;b.i[0:3] >> b012') + a\b | b13 | b012 + a0 | 4 | 3 + a1 | 12 | 15 + a2 | 20 | 27 + + A few notes: + + - the goal was to have that syntax as close as the "normal" syntax as possible (just remove the "x." and all inner + quotes). + - in models, the normal syntax should be preferred, so that the groups can be stored in a variable and reused in + several places + - strings representing integers are evaluated as integers. + - there is experimental support for evaluating expressions within string groups by using "{expr}", but this is + fragile and might be removed in the future. + +* implemented combine_axes & split_axis on arrays: + + >>> arr = ndtest((2, 3, 4)) + >>> arr + a | b\c | c0 | c1 | c2 | c3 + a0 | b0 | 0 | 1 | 2 | 3 + a0 | b1 | 4 | 5 | 6 | 7 + a0 | b2 | 8 | 9 | 10 | 11 + a1 | b0 | 12 | 13 | 14 | 15 + a1 | b1 | 16 | 17 | 18 | 19 + a1 | b2 | 20 | 21 | 22 | 23 + + >>> arr2 = arr.combine_axes((x.a, x.b)) + >>> arr2 + a_b\c | c0 | c1 | c2 | c3 + a0_b0 | 0 | 1 | 2 | 3 + a0_b1 | 4 | 5 | 6 | 7 + a0_b2 | 8 | 9 | 10 | 11 + a1_b0 | 12 | 13 | 14 | 15 + a1_b1 | 16 | 17 | 18 | 19 + a1_b2 | 20 | 21 | 22 | 23 + + >>> arr2.split_axis(x.a_b) + a | b\c | c0 | c1 | c2 | c3 + a0 | b0 | 0 | 1 | 2 | 3 + a0 | b1 | 4 | 5 | 6 | 7 + a0 | b2 | 8 | 9 | 10 | 11 + a1 | b0 | 12 | 13 | 14 | 15 + a1 | b1 | 16 | 17 | 18 | 19 + a1 | b2 | 20 | 21 | 22 | 23 + +* implemented .by() method on groups which splits them into subgroups of specified length + + >>> arr = ndtest((5, 2)) + >>> arr + a\b | b0 | b1 + a0 | 0 | 1 + a1 | 2 | 3 + a2 | 4 | 5 + a3 | 6 | 7 + a4 | 8 | 9 + + >>> arr.sum(a['a0':'a4'].by(2)) + a\b | b0 | b1 + a['a0' 'a1'] | 2 | 4 + a['a2' 'a3'] | 10 | 12 + a['a4'] | 8 | 9 + + there is also an optional second argument to specify the "step" between groups + + >>> arr.sum(a['a0':'a4'].by(2, step=3)) + a\b | b0 | b1 + a['a0' 'a1'] | 2 | 4 + a['a3' 'a4'] | 14 | 16 + + if the step is < the group size, you get overlapping groups: + + >>> arr.sum(a['a0':'a4'].by(2, step=1)) + a\b | b0 | b1 + a['a0' 'a1'] | 2 | 4 + a['a1' 'a2'] | 6 | 8 + a['a2' 'a3'] | 10 | 12 + a['a3' 'a4'] | 14 | 16 + a['a4'] | 8 | 9 + +* groups can be renamed using >> (in addition to the "named" method) + + >>> arr = ndtest((2, 3)) + >>> arr + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 2 + a1 | 3 | 4 | 5 + >>> arr.sum((x.b['b0,b1'] >> 'b01', x.b['b1,b2'] >> 'b12')) + a\b | b01 | b12 + a0 | 1 | 3 + a1 | 7 | 9 + +* implemented rationot0 + + >>> a = Axis('a', 'a0,a1') + >>> b = Axis('b', 'b0,b1,b2') + >>> arr = LArray([[6, 0, 2], + ... [4, 0, 8]], [a, b]) + >>> arr + a\b | b0 | b1 | b2 + a0 | 6 | 0 | 2 + a1 | 4 | 0 | 8 + >>> arr.sum() + 20 + >>> arr.rationot0() + a\b | b0 | b1 | b2 + a0 | 0.3 | 0.0 | 0.1 + a1 | 0.2 | 0.0 | 0.4 + >>> arr.rationot0(x.a) + a\b | b0 | b1 | b2 + a0 | 0.6 | 0.0 | 0.2 + a1 | 0.4 | 0.0 | 0.8 + + for reference, the normal ratio method would return: + + >>> arr.ratio(x.a) + a\b | b0 | b1 | b2 + a0 | 0.6 | nan | 0.2 + a1 | 0.4 | nan | 0.8 + + +Misc improvements +----------------- + +* implemented [] on groups so that you can further subset them +* added a new "condensed" option for ipfp's display_progress argument to get back the old behavior +* changed how named groups are displayed (only the name is displayed) +* positional groups gained a few features and are almost on par with label groups now +* when iterating over an axis (for example when doing "for y in year_axis:" it yields groups (instead of raw labels) so + that it works even in the presence of ambiguous labels. +* Axis.startswith, endswith, matches create groups which include the axis (so that those groups work even if the labels + exist on several axes) + + +Bug fixes +--------- + +* fixed Session.summary() when arrays in the session have axes without name +* fixed full() and full_like() with an explicit dtype (the dtype was ignored) diff --git a/doc/source/changes/version_0_19.rst.inc b/doc/source/changes/version_0_19.rst.inc new file mode 100644 index 000000000..bdb51bd34 --- /dev/null +++ b/doc/source/changes/version_0_19.rst.inc @@ -0,0 +1,166 @@ +New features +------------ + +* Implemented a "by" variant to all aggregate methods (e.g. sum_by, mean_by, etc.). These methods aggregate all axes + except those listed, which means the only axes remaining after the aggregate operation will be those listed. + For example: arr.sum_by(x.a) is equivalent to arr.sum(arr.axes - x.a) + + >>> arr = ndtest((2, 3, 4)) + >>> arr + a | b\c | c0 | c1 | c2 | c3 + a0 | b0 | 0 | 1 | 2 | 3 + a0 | b1 | 4 | 5 | 6 | 7 + a0 | b2 | 8 | 9 | 10 | 11 + a1 | b0 | 12 | 13 | 14 | 15 + a1 | b1 | 16 | 17 | 18 | 19 + a1 | b2 | 20 | 21 | 22 | 23 + >>> arr.sum_by(x.b) + b | b0 | b1 | b2 + | 60 | 92 | 124 + +* Added .extend() method to Axis class + + >>> a = Axis('a', 'a0..a2') + >>> a + Axis('a', ['a0', 'a1', 'a2']) + >>> other = Axis('other', 'a3..a5') + >>> a.extend(other) + Axis('a', ['a0', 'a1', 'a2', 'a3', 'a4', 'a5']) + + or directly specify the extra labels as a list or as a "label string": + + >>> a.extend('a3..a5') + Axis('a', ['a0', 'a1', 'a2', 'a3', 'a4', 'a5']) + +* Added title argument to all array creation functions (ndrange, zeros, ones, ...) and display it in the .info of + array objects. + + >>> a = ndrange(3, title='a simple test array') + >>> a.info + a simple test array + 3 + {0}* [3]: 0 1 2 + +* implemented creating an Axis using a group: + + >>> arr = ndtest((2, 3)) + >>> arr + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 2 + a1 | 3 | 4 | 5 + >>> a, b = arr.axes + >>> zeros((a, b[:'b1'])) + a\b | b0 | b1 + a0 | 0.0 | 0.0 + a1 | 0.0 | 0.0 + +* made Axis.startswith, .endswith and .matches accept Group instances + + >>> a = Axis('a', 'a0..b2') + >>> a + Axis('a', ['a0', 'a1', 'a2', 'b0', 'b1', 'b2']) + + >>> prefix = Axis('prefix', 'a,b') + >>> a.startswith(prefix['a']) + a['a0', 'a1', 'a2'] + >>> a.startswith(prefix.i[1]) + a['b0', 'b1', 'b2'] + +* implemented all usual binary operations (+, -, `*`, /, ...) on Group + + >>> year = Axis('year', '2011..2016') + >>> year[2013] + 1 + 2014 + >>> year.i[2] + 1 + 2014 + +* made the viewer is much more useful as a debugger in the middle of a function by generalizing SessionEditor to handle + any mapping, instead of only Session objects but made it list and display only array objects. To view the value of + non-array variable one should type their name in the console. Given those changes, view() will superficially behave + as before, but behind the scene, *all* variables which were defined in the scope where view() was called will be + available in the viewer console, even though they will not appear in the list on the left. This means that the viewer + console will be able to use scalars defined at that point and call others functions of your code. In other words, + there are more chances you can execute some code from the function calling view() by simply copy-pasting the code + line. + + +Backward incompatible changes +----------------------------- + +* LGroup lost set-like operations (intersection and union) to the profit of a specific subclass (LSet). In other words, + this no longer works: + + >>> letters = Axis('letters', 'a..z') + >>> letters[':c'] & letters['b:'] + + To make it work, we need to convert the LGroup(s) to LSets explicitly: + + >>> letters[':c'].set() & letters['b:d'].set() + letters.set[OrderedSet(['b', 'c'])] + + >>> letters[':c'].set() | letters['b:d'].set() + letters.set[OrderedSet(['a', 'b', 'c', 'd'])] + + >>> letters[':c'].set() - 'b' + letters.set[OrderedSet(['a', 'c'])] + +* group aggregates produce simple string labels for the new aggregated axis instead of using the group themselves as + labels. This means one can no longer know where a group comes from but this simplifies the code and fixes a few + issues, most notably export of aggregated arrays to Excel, and some operations between two aggregated arrays. + + >>> arr = ndtest((3, 4)) + >>> arr + a\b | b0 | b1 | b2 | b3 + a0 | 0 | 1 | 2 | 3 + a1 | 4 | 5 | 6 | 7 + a2 | 8 | 9 | 10 | 11 + >>> agg = arr.sum(':b2 >> tob2;b2,b3 >> other') + >>> agg + a\b | tob2 | other + a0 | 3 | 5 + a1 | 15 | 13 + a2 | 27 | 21 + >>> agg.info + 3 x 2 + a [3]: 'a0' 'a1' 'a2' + b [2]: 'tob2' 'other' + >>> agg.axes.b.labels[0] + 'tob2' + + In previous versions this would have returned: + + >>> agg.axes.b.labels[0] + LGroup(':b2', name='tob2', axis=Axis('b', ['b0', 'b1', 'b2', 'b3'])) + +* a string containing only a single "integer-like" is no longer transformed to an integer + e.g. "10" will evaluate to (the string) "10" (like in version 0.17 and earlier) while "10,20" will evaluate to the + list of integers: [10, 20] + + +Other changes +------------- + +* changed how Group instances are displayed. + + >>> a = Axis('a', 'a0..a2') + >>> a['a1,a2'] + a['a1', 'a2'] + + +Fixes +----- + +* fixed > and >= on Group using slices + +* avoid a division by 0 warning when using divnot0 + +* viewer: fixed plots when Qt5 is installed. This also removes the matplotlib warning people got when running the + viewer with Qt5 installed. + +* viewer: display array when typing its name in the console even when no array was selected previously + + +Misc +---- + +* misc code cleanup, improved docstrings, ... diff --git a/doc/source/changes/version_0_2.rst.inc b/doc/source/changes/version_0_2.rst.inc index 81ee7a760..778b53cc4 100644 --- a/doc/source/changes/version_0_2.rst.inc +++ b/doc/source/changes/version_0_2.rst.inc @@ -26,4 +26,4 @@ Miscellaneous improvements Fixes ----- -* column titles are no longer converted to lowercase. \ No newline at end of file +* column titles are no longer converted to lowercase. diff --git a/doc/source/changes/version_0_20.rst.inc b/doc/source/changes/version_0_20.rst.inc new file mode 100644 index 000000000..ab5f304c2 --- /dev/null +++ b/doc/source/changes/version_0_20.rst.inc @@ -0,0 +1,150 @@ +IMPORTANT +--------- + +To make sure all users have all optional dependencies installed and use the same version of packages, and to simplify +the update process, we created a new "larrayenv" package which will install larray itself AND all its dependencies +(*including* the optional ones). This means that this version needs to be installed using: + + conda install larrayenv + +in the future, to update from one version to the next, it should always be enough to do: + + conda update larrayenv + + +New features +------------ + +* implemented from_lists() to create constant arrays (instead of using LArray directly as that is very error prone). + We are not really happy with its name though, so it might change in the future. Any suggestion of a better name is + very welcome (closes :issue:`30`). + + >>> from_lists([['sex\\year', 1991, 1992, 1993], + ... [ 'M', 0, 1, 2], + ... [ 'F', 3, 4, 5]]) + sex\year | 1991 | 1992 | 1993 + M | 0 | 1 | 2 + F | 3 | 4 | 5 + +* added support for loading sparse arrays via open_excel(). + + For example, assuming you have a sheet like this: :: + + age | sex\year | 2015 | 2016 + 10 | F | 0.0 | 1.0 + 10 | M | 2.0 | 3.0 + 20 | M | 4.0 | 5.0 + + loading it will yield: + + >>> wb = open_excel('test_sparse.xlsx') + >>> arr = wb['Sheet1'].load() + >>> arr + age | sex\year | 2015 | 2016 + 10 | F | 0.0 | 1.0 + 10 | M | 2.0 | 3.0 + 20 | F | nan | nan + 20 | M | 4.0 | 5.0 + + +Miscellaneous improvements +-------------------------- + +* allowed to get an axis from an array by using array.axis_name in addition to array.axes.axis_name: + + >>> arr = ndtest((2, 3)) + >>> arr.axes + AxisCollection([ + Axis('a', ['a0', 'a1']), + Axis('b', ['b0', 'b1', 'b2']) + ]) + >>> arr.a + Axis('a', ['a0', 'a1']) + +* viewer: several rows/columns can be plotted together. It draws a separate line for each row except if only one column + has been selected. + +* viewer: the array labels are used as "ticks" in plots. + +* '_by' aggregation methods accept groups in addition to axes (closes :issue:`59`). It will keep only the mentioned + groups and aggregate all other dimensions: + + >>> arr = ndtest((2, 3, 4)) + >>> arr + a | b\c | c0 | c1 | c2 | c3 + a0 | b0 | 0 | 1 | 2 | 3 + a0 | b1 | 4 | 5 | 6 | 7 + a0 | b2 | 8 | 9 | 10 | 11 + a1 | b0 | 12 | 13 | 14 | 15 + a1 | b1 | 16 | 17 | 18 | 19 + a1 | b2 | 20 | 21 | 22 | 23 + + >>> arr.sum_by('c0,c1;c1:c3') + c | c0,c1 | c1:c3 + | 126 | 216 + +* viewer: view() and edit() now accept as argument a path to a file containing arrays. + + >>> view('myfile.h5') + + this is a shortcut for: + + >>> view(Session('myfile.h5')) + +* AxisCollection.without now accepts a single integer position (to exclude an axis by position). + + >>> a = ndtest((2, 3)) + >>> a.axes + AxisCollection([ + Axis('a', ['a0', 'a1']), + Axis('b', ['b0', 'b1', 'b2']) + ]) + >>> a.axes.without(0) + AxisCollection([ + Axis('b', ['b0', 'b1', 'b2']) + ]) + +* nicer display (repr) for LSet (closes :issue:`44`). + + >>> x.b['b0,b2'].set() + x.b['b0', 'b2'].set() + +* implemented sep argument for LArray & AxisCollection.combine_axes() to allow using a custom delimiter + (closes :issue:`53`). + +* added a check that ipfp target sums haves expected axes (closes :issue:`42`). + +* when the nb_index argument is not provided explicitly in read_excel(engine='xlrd'), it is autodetected from the + position of the first "\" (closes :issue:`66`). + +* allow any special character except "." and whitespace when creating axes labels using ".." syntax + (previously only _ was allowed). + +* added many more I/O tests to hopefully lower our regression rate in the future (closes :issue:`70`). + + +Fixes +----- + +* viewer: selection of entire rows/columns will load any remaining data, if any (closes :issue:`37`). Previously if you + selected entire rows or columns of a large dataset (which is not loaded entirely from the start), it only selected + (and thus copied/plotted) the part of the data which was already loaded. + +* viewer: filtering on anonymous axes is now possible (closes :issue:`33`). + +* fixed loading sparse files using read_excel() (fixes :issue:`29`). + +* fixed nb_index argument for read_excel(). + +* fixed creating range axes with a negative start bound using string notation (e.g. `Axis('name', '-1..10')`) + (fixes :issue:`51`). + +* fixed ptp() function. + +* fixed with_axes() to copy the title of the array. + +* fixed Group >> 'name'. + +* fixed workbook[sheet_position] when using open_excel(). + +* fixed plotting in the viewer when using Qt4. diff --git a/doc/source/changes/version_0_21.rst.inc b/doc/source/changes/version_0_21.rst.inc new file mode 100644 index 000000000..7317b9b34 --- /dev/null +++ b/doc/source/changes/version_0_21.rst.inc @@ -0,0 +1,291 @@ +New features +------------ + +* implemented set_axes() method to replace one, several or all axes of an array (closes :issue:`67`). + The method with_axes() is now deprecated (set_axes() must be used instead). + + >>> arr = ndtest((2, 3)) + >>> arr + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 2 + a1 | 3 | 4 | 5 + >>> row = Axis('row', ['r0', 'r1']) + >>> column = Axis('column', ['c0', 'c1', 'c2']) + + Replace one axis (second argument `new_axis` must be provided) + + >>> arr.set_axes(x.a, row) + row\b | b0 | b1 | b2 + r0 | 0 | 1 | 2 + r1 | 3 | 4 | 5 + + Replace several axes (keywords, list of tuple or dictionary) + + >>> arr.set_axes(a=row, b=column) + or + >>> arr.set_axes([(x.a, row), (x.b, column)]) + or + >>> arr.set_axes({x.a: row, x.b: column}) + row\column | c0 | c1 | c2 + r0 | 0 | 1 | 2 + r1 | 3 | 4 | 5 + + Replace all axes (list of axes or AxisCollection) + + >>> arr.set_axes([row, column]) + row\column | c0 | c1 | c2 + r0 | 0 | 1 | 2 + r1 | 3 | 4 | 5 + >>> arr2 = ndrange([row, column]) + >>> arr.set_axes(arr2.axes) + row\column | c0 | c1 | c2 + r0 | 0 | 1 | 2 + r1 | 3 | 4 | 5 + +* implemented Axis.replace to replace some labels from an axis: + + >>> sex = Axis('sex', ['M', 'F']) + >>> sex + Axis('sex', ['M', 'F']) + >>> sex.replace('M', 'Male') + Axis('sex', ['Male', 'F']) + >>> sex.replace({'M': 'Male', 'F': 'Female'}) + Axis('sex', ['Male', 'Female']) + +* implemented from_string() method to create an array from a string (closes :issue:`96`). + + >>> from_string('''age,nat\\sex, M, F + ... 0, BE, 0, 1 + ... 0, FO, 2, 3 + ... 1, BE, 4, 5 + ... 1, FO, 6, 7''') + age | nat\sex | M | F + 0 | BE | 0 | 1 + 0 | FO | 2 | 3 + 1 | BE | 4 | 5 + 1 | FO | 6 | 7 + +* allowed to use a regular expression in split_axis method (closes :issue:`106`): + + >>> combined = ndrange('a_b = a0b0..a1b2') + >>> combined + a_b | a0b0 | a0b1 | a0b2 | a1b0 | a1b1 | a1b2 + | 0 | 1 | 2 | 3 | 4 | 5 + >>> combined.split_axis(x.a_b, regex='(\w{2})(\w{2})') + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 2 + a1 | 3 | 4 | 5 + +* one can assign a new axis to several groups at the same time by using axis[groups]: + + >>> group1 = year[2001:2004] + >>> group2 = year[2008,2009] + >>> # let us change the year axis by time + >>> x.time[group1, group2] + (x.time[2001:2004], x.time[2008, 2009]) + +* implemented Axis.by() which is equivalent to axis[:].by() and divides the axis into several groups of specified + length: + + >>> year = Axis('year', '2010..2016') + >>> year.by(3) + (year.i[0:3], year.i[3:6], year.i[6:7]) + + which is equivalent to (year[2010:2012], year[2013:2015], year[2016]). Like for groups, the optional second argument + specifies the step between groups + + >>> year.by(3, step=4) + (year.i[0:3], year.i[4:7]) + + which is equivalent to (year[2010:2012], year[2014:2016]). And if step is smaller than length, we get overlapping + groups, which can be useful for example for moving averages. + + >>> year.by(3, 2) + (year.i[0:3], year.i[2:5], year.i[4:7], year.i[6:7]) + + which is equivalent to (year[2010:2012], year[2012:2014], year[2014:2016], year[2016]) + +* implemented larray_nan_equal to test whether two arrays are identical even in the presence of nan values. + Two arrays are considered identical by larray_equal if they have exactly the same axes and data. However, since a nan + value has the odd property of not being equal to itself, larray_equal returns False if either array contains a nan + value. larray_nan_equal returns True if all not-nan data is equal and both arrays have nans at the same place. + + >>> arr1 = ndtest((2, 3), dtype=float) + >>> arr1['a1', 'b1'] = nan + >>> arr1 + a\b | b0 | b1 | b2 + a0 | 0.0 | 1.0 | 2.0 + a1 | 3.0 | nan | 5.0 + >>> arr2 = arr1.copy() + >>> arr2 + a\b | b0 | b1 | b2 + a0 | 0.0 | 1.0 | 2.0 + a1 | 3.0 | nan | 5.0 + >>> larray_equal(arr1, arr2) + False + >>> larray_nan_equal(arr1, arr2) + True + >>> arr2['b1'] = 0.0 + >>> larray_nan_equal(arr1, arr2) + False + + +Miscellaneous improvements +-------------------------- + +* viewer: make keyboard shortcuts work even when the focus is not on the array editor widget. It means that, + for example, plotting an array (via Ctrl-P) or opening it in Excel (Ctrl-E) can be done directly even when + interacting with the list of arrays or within the interactive console (closes :issue:`102`). + +* viewer: automatically display plots done in the viewer console in a separate window (see example below), unless + "%matplotlib inline" is used. + + >>> arr = ndtest((3, 3)) + >>> arr.plot() + +* viewer: when calling view(an_array) from within the viewer, the new window opened does not block the initial window, + which means you can have several windows open at the same time. view() without argument can still result in odd + behavior though. + +* improved LArray.set_labels to make it possible to replace only some labels of an axis, instead of all of them + and to replace labels from several axes at the same time. + + >>> a = ndrange('nat=BE,FO;sex=M,F') + >>> a + nat\sex | M | F + BE | 0 | 1 + FO | 2 | 3 + + to replace only some labels, one must give a mapping giving the new label for each label to replace + + >>> a.set_labels(x.sex, {'M': 'Men'}) + nat\sex | Men | F + BE | 0 | 1 + FO | 2 | 3 + + to replace labels for several axes at the same time, one should give a mapping giving the new labels for each changed + axis + + >>> a.set_labels({'sex': 'Men,Women', 'nat': 'Belgian,Foreigner'}) + nat\sex | Men | Women + Belgian | 0 | 1 + Foreigner | 2 | 3 + + one can also replace some labels in several axes by giving a mapping of mappings + + >>> a.set_labels({'sex': {'M': 'Men'}, 'nat': {'BE': 'Belgian'}}) + nat\sex | Men | F + Belgian | 0 | 1 + FO | 2 | 3 + +* allowed matrix multiplication (@ operator) between arrays with dimension != 2 (closes :issue:`122`). + +* improved LArray.plot to get nicer plots by default. The axes are transposed compared to what they used to, because + the last axis is often used for time series. Also it considers a 1D array like a single series, not N series of 1 + point. + +* added installation instructions (closes :issue:`101`). + +* Axis.group and Axis.all are now deprecated (closes :issue:`148`). + + >>> city.group(['London', 'Brussels'], name='capitals') + # should be written as: + >>> city[['London', 'Brussels']] >> 'capitals' + + and + + >>> city.all() + # should be written as: + >>> city[:] >> 'all' + + +Fixes +----- + +* viewer: allow changing the number of displayed digits even for integer arrays as that makes sense when using + scientific notation (closes :issue:`100`). + +* viewer: fixed opening a viewer via view() edit() or compare() from within the viewer + (closes :issue:`109`) + +* viewer: fixed compare() colors when arrays have values which are very close but not exactly equal + (closes :issue:`123`) + +* viewer: fixed legend when plotting arbitrary rows (it always displayed the labels of the first rows) + (closes :issue:`136`). + +* viewer: fixed labels on the x axis when zooming on a plot (closes :issue:`143`) + +* viewer: fixed storing an array in a variable with a name which existed previously but which was not displayable in + the viewer, such as the name of any function or special object. In some cases, this error lead to a crash of the + viewer. For example, this code failed when run in the viewer console, because x is already defined (for the x. + syntax): + + >>> x = ndtest(3) + +* fixed indexing an array using a positional group with a position which corresponds to a label on that axis. This + used to return the wrong data (the data corresponding to the position as if it was the key). + + >>> a = Axis('a', '1..3') + >>> arr = ndrange(a) + >>> arr + a | 1 | 2 | 3 + | 0 | 1 | 2 + >>> # this used to return 0 ! + >>> arr[a.i[1]] + 1 + +* fixed == for positional groups (closes :issue:`93`) + + >>> years = Axis('years', '1995..1997') + >>> years + Axis('years', [1995, 1996, 1997]) + >>> # this used to return False + >>> years.i[0] == 1995 + True + +* fixed using positional groups for their value in many cases (slice bounds, within list of values, within other + groups, etc.). For example, this used to fail: + + >>> arr = ndtest((2, 4)) + >>> arr + a\b | b0 | b1 | b2 | b3 + a0 | 0 | 1 | 2 | 3 + a1 | 4 | 5 | 6 | 7 + >>> b = arr.b + >>> start = b.i[0] # equivalent to start = 'b0' + >>> stop = b.i[2] # equivalent to stop = 'b2' + >>> arr[start:stop] + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 2 + a1 | 4 | 5 | 6 + >>> arr[[b.i[0], b.i[2]]] + a\b | b0 | b2 + a0 | 0 | 2 + a1 | 4 | 6 + +* fixed posargsort labels (closes :issue:`137`). + +* fixed labels when doing group aggregates using positional groups. Previously, it used the positions as labels. This + was most visible when using the Group.by() method (which creates positional groups). + + >>> years = Axis('years', '2010..2015') + >>> arr = ndrange(years) + >>> arr + years | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 + | 0 | 1 | 2 | 3 | 4 | 5 + >>> arr.sum(years.by(3)) + years | 2010:2012 | 2013:2015 + | 3 | 12 + + While this used to return: + + >>> arr.sum(years.by(3)) + years | 0:3 | 3:6 + | 3 | 12 + +* fixed Group.by() when the group was a slice with either bound unspecified. For example, `years[2010:2015].by(3)` + worked but `years[:].by(3)`, `years[2010:].by(3)` and `years[:2015].by(3)` did not. + +* fixed a speed regression in version 0.18 and later versions compared to 0.17. In some cases, it was up to 40% slower + than it should (closes :issue:`165`). diff --git a/doc/source/changes/version_0_22.rst.inc b/doc/source/changes/version_0_22.rst.inc new file mode 100644 index 000000000..16627c9bb --- /dev/null +++ b/doc/source/changes/version_0_22.rst.inc @@ -0,0 +1,333 @@ +New features +------------ + +* viewer: added a menu bar with the ability to clear the current session, save all its arrays to a file (.h5, .xlsx, + or a directory containing multiple .csv files), and load arrays from such a file (closes :issue:`88`). + + WARNING: Only array objects are currently saved. It means that scalars, functions or others non-LArray objects + defined in the console are *not* saved in the file. + +* implemented a new describe() method on arrays to give quick summary statistics. By default, it includes the number of + non-NaN values, the mean, standard deviation, minimum, 25, 50 and 75 percentiles and maximum. + + >>> arr = ndrange('gender=Male,Female;year=2014..2020').astype(float) + >>> arr + gender\year | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 + Male | 0.0 | 1.0 | 2.0 | 3.0 | 4.0 | 5.0 | 6.0 + Female | 7.0 | 8.0 | 9.0 | 10.0 | 11.0 | 12.0 | 13.0 + >>> arr.describe() + statistic | count | mean | std | min | 25% | 50% | 75% | max + | 14.0 | 6.5 | 4.031128874149275 | 0.0 | 3.25 | 6.5 | 9.75 | 13.0 + + an optional keyword argument allows to specify different percentiles to include + + >>> arr.describe(percentiles=[20, 40, 60, 80]) + statistic | count | mean | std | min | 20% | 40% | 60% | 80% | max + | 14.0 | 6.5 | 4.031128874149275 | 0.0 | 2.6 | 5.2 | 7.8 | 10.4 | 13.0 + + its sister method, describe_by() was also implemented to give quick summary statistics along axes or groups. + + >>> arr.describe_by('gender') + gender\statistic | count | mean | std | min | 25% | 50% | 75% | max + Male | 7.0 | 3.0 | 2.0 | 0.0 | 1.5 | 3.0 | 4.5 | 6.0 + Female | 7.0 | 10.0 | 2.0 | 7.0 | 8.5 | 10.0 | 11.5 | 13.0 + >>> arr.describe_by('gender', (x.year[:2015], x.year[2019:])) + gender | year\statistic | count | mean | std | min | 25% | 50% | 75% | max + Male | :2015 | 2.0 | 0.5 | 0.5 | 0.0 | 0.25 | 0.5 | 0.75 | 1.0 + Male | 2019: | 2.0 | 5.5 | 0.5 | 5.0 | 5.25 | 5.5 | 5.75 | 6.0 + Female | :2015 | 2.0 | 7.5 | 0.5 | 7.0 | 7.25 | 7.5 | 7.75 | 8.0 + Female | 2019: | 2.0 | 12.5 | 0.5 | 12.0 | 12.25 | 12.5 | 12.75 | 13.0 + + This closes :issue:`184`. + +* implemented reindex allowing to change the order of labels and add/remove some of them to one or several axes: + + >>> arr = ndtest((2, 2)) + >>> arr + a\b | b0 | b1 + a0 | 0 | 1 + a1 | 2 | 3 + >>> arr.reindex(x.b, ['b1', 'b2', 'b0'], fill_value=-1) + a\b | b1 | b2 | b0 + a0 | 1 | -1 | 0 + a1 | 3 | -1 | 2 + >>> a = Axis('a', ['a1', 'a2', 'a0']) + >>> b = Axis('b', ['b2', 'b1', 'b0']) + >>> arr.reindex({'a': a, 'b': b}, fill_value=-1) + a\b | b2 | b1 | b0 + a1 | -1 | 3 | 2 + a2 | -1 | -1 | -1 + a0 | -1 | 1 | 0 + + using reindex one can make an array compatible with another array which has more/less labels or with labels in a + different order: + + >>> arr2 = ndtest((3, 3)) + >>> arr2 + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 2 + a1 | 3 | 4 | 5 + a2 | 6 | 7 | 8 + >>> arr.reindex(arr2.axes, fill_value=0) + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 0 + a1 | 2 | 3 | 0 + a2 | 0 | 0 | 0 + >>> arr.reindex(arr2.axes, fill_value=0) + arr2 + a\b | b0 | b1 | b2 + a0 | 0 | 2 | 2 + a1 | 5 | 7 | 5 + a2 | 6 | 7 | 8 + + This closes :issue:`18`. + +* added load_example_data function to load datasets used in tutorial and be able to reproduce examples. The name of the + dataset must be provided as argument (there is currently only one available dataset). Datasets are returned as + Session objects: + + >>> demo = load_example_data('demography') + >>> demo.pop.info + 26 x 3 x 121 x 2 x 2 + time [26]: 1991 1992 1993 ... 2014 2015 2016 + geo [3]: 'BruCap' 'Fla' 'Wal' + age [121]: 0 1 2 ... 118 119 120 + sex [2]: 'M' 'F' + nat [2]: 'BE' 'FO' + >>> demo.qx.info + 26 x 3 x 121 x 2 x 2 + time [26]: 1991 1992 1993 ... 2014 2015 2016 + geo [3]: 'BruCap' 'Fla' 'Wal' + age [121]: 0 1 2 ... 118 119 120 + sex [2]: 'M' 'F' + nat [2]: 'BE' 'FO' + + (closes :issue:`170`) + +* implemented Axis.union, intersection and difference which produce new axes by combining the labels of the axis + with the other labels. + + >>> letters = Axis('letters=a,b') + >>> letters.union(Axis('letters=b,c')) + Axis(['a', 'b', 'c'], 'letters') + >>> letters.union(['b', 'c']) + Axis(['a', 'b', 'c'], 'letters') + >>> letters.intersection(['b', 'c']) + Axis(['b'], 'letters') + >>> letters.difference(['b', 'c']) + Axis(['a'], 'letters') + +* implemented Group.union, intersection and difference which produce new groups by combining the labels of the group + with the other labels. + + >>> letters = Axis('letters=a..d') + >>> letters['a', 'b'].union(letters['b', 'c']) + letters['a', 'b', 'c'].set() + >>> letters['a', 'b'].union(['b', 'c']) + letters['a', 'b', 'c'].set() + >>> letters['a', 'b'].intersection(['b', 'c']) + letters['b'].set() + >>> letters['a', 'b'].difference(['b', 'c']) + letters['a'].set() + +* viewer: added possibility to delete an array by pressing Delete on keyboard (closes :issue:`116`). + +* Excel sheets in workbooks opened via open_excel can be renamed by changing their .name attribute: + + >>> wb = open_excel() + >>> wb['old_sheet_name'].name = 'new_sheet_name' + +* Excel sheets in workbooks opened via open_excel can be deleted using "del": + + >>> wb = open_excel() + >>> del wb['sheet_name'] + +* implemented PGroup.set() to transform a positional group to an LSet. + + >>> a = Axis('a=a0..a5') + >>> a.i[:2].set() + a['a0', 'a1'].set() + +.. _misc: + +Miscellaneous improvements +-------------------------- + +* inverted `name` and `labels` arguments when creating an Axis and made `name` argument optional (to create anonymous + axes). Now, it is also possible to create an Axis by passing a single string of the kind 'name=labels': + + >>> anonymous = Axis('0..100') + >>> age = Axis('age=0..100') + >>> gender = Axis('M,F', 'gender') + + (closes :issue:`152`) + +* renamed Session.dump, dump_hdf, dump_excel and dump_csv to save, to_hdf, to_excel and to_csv (closes :issue:`217`). + +* changed default value of `ddof` argument for var and std functions from 0 to 1 (closes :issue:`190`). + +* implemented a new syntax for stack(): `stack({label1: value1, label2: value2}, axis)` + + >>> nat = Axis('nat', 'BE, FO') + >>> sex = Axis('sex', 'M, F') + >>> males = ones(nat) + >>> males + nat | BE | FO + | 1.0 | 1.0 + >>> females = zeros(nat) + >>> females + nat | BE | FO + | 0.0 | 0.0 + + In the case the axis has already been defined in a variable, this gives: + + >>> stack({'M': males, 'F': females}, sex) + nat\sex | M | F + BE | 1.0 | 0.0 + FO | 1.0 | 0.0 + + Additionally, axis can now be an axis string definition in addition to an Axis object, which means one can write this: + + >>> stack({'M': males, 'F': females}, 'sex=M,F') + + It is better than the simpler but *highly discouraged* alternative: + + >>> stack([males, females), sex) + + because it is all too easy to invert labels. It is very hard to spot the error in the following line, and larray + cannot spot it for you either: + + >>> stack([females, males), sex) + nat\sex | M | F + BE | 0.0 | 1.0 + FO | 0.0 | 1.0 + + When creating an axis from scratch (it does not already exist in a variable), one might want to use this: + + >>> stack([males, females], 'sex=M,F') + + even if this could suffer, to a lesser extent, the same problem as above when stacking many arrays. + +* handle ... in transpose method to avoid having to list all axes. This can be useful, for example, to change which + axis is displayed in columns (closes :issue:`188`). + + >>> arr.transpose(..., 'time') + >>> arr.transpose('gender', ..., 'time') + +* made scalar Groups behave even more like their value: any method available on the value is available on the Group. + For example, if the Group has a string value, the string methods are available on it (closes :issue:`202`). + + >>> test = Axis('test', ['abc', 'a1-a2']) + >>> test.i[0].upper() + 'ABC' + >>> test.i[1].split('-') + ['a1', 'a2'] + +* updated AxisCollection.replace so as to replace one, several or all axes and to accept axis definitions as new axes. + + >>> arr = ndtest((2, 3)) + >>> axes = arr.axes + >>> axes + AxisCollection([ + Axis(['a0', 'a1'], 'a'), + Axis(['b0', 'b1', 'b2'], 'b') + ]) + >>> row = Axis(['r0', 'r1'], 'row') + >>> column = Axis(['c0', 'c1', 'c2'], 'column') + + Replace several axes (keywords, list of tuple or dictionary) + + >>> axes.replace(a=row, b=column) + >>> # or + >>> axes.replace(a="row=r0,r1", b="column=c0,c1,c2") + >>> # or + >>> axes.replace([(x.a, row), (x.b, column)]) + >>> # or + >>> axes.replace({x.a: row, x.b: column}) + AxisCollection([ + Axis(['r0', 'r1'], 'row'), + Axis(['c0', 'c1', 'c2'], 'column') + ]) + +* added possibility to delete an array from a session: + + >>> s = Session({'a': ndtest((3, 3)), 'b': ndtest((2, 4)), 'c': ndtest((4, 2))}) + >>> s.names + ['a', 'b', 'c'] + >>> del s.b + >>> del s['c'] + >>> s.names + ['a'] + +* made create_sequential axis argument accept axis definitions in addition to Axis objects like, for example, using a + string definition (closes :issue:`160`). + + >>> create_sequential('year=2016..2019') + year | 2016 | 2017 | 2018 | 2019 + | 0 | 1 | 2 | 3 + +* replaced \*args, \**kwargs by explicit arguments in documentation of aggregation functions (sum, prod, mean, std, + var, ...). Closes :issue:`41`. + +* improved documentation of plot method (closes :issue:`169`). + +* improved auto-completion in ipython interactive consoles for both LArray and Session objects. LArray objects can now + complete keys within []. + + >>> a = ndrange('sex=Male,Female') + >>> a + sex | Male | Female + | 0 | 1 + >>> a['Fe` + + will autocomplete to `a['Female`. Sessions will now auto-complete both attributes (using `session.`) and keys + (using `session[`). + + >>> s = Session({'a_nice_test_array': ndtest(10)}) + >>> s.a_ + + will autocomplete to `s.a_nice_test_array` and `s['a_` will be completed to `s['a_nice_test_array` + +* made warning messages for division by 0 and invalid values (usually caused by 0 / 0) point to the user code line, + instead of the corresponding line in the larray module. + +* preserve order of arrays in a session when saving to/loading from an .xlsx file. + +* when creating a session from a directory containing CSV files, the directory may now contain other (non-CSV) files. + +* several calls to open_excel from within the same program/script will now reuses a single global Excel instance. + This makes Excel I/O much faster without having to create an instance manually using xlwings.App, and still without + risking interfering with other instances of Excel opened manually (closes :issue:`245`). + +* improved error message when trying to copy a sheet from one instance of Excel to another (closes :issue:`231`). + + +Fixes +----- + +* fixed keyword arguments such as `out`, `ddof`, ... for aggregation functions (closes :issue:`189`). + +* fixed percentile(_by) with multiple percentiles values, i.e. when argument `q` is a list/tuple (closes :issue:`192`). + +* fixed group aggregates on integer arrays for median, percentile, var and std (closes :issue:`193`). + +* fixed group sum over boolean arrays (closes :issue:`194`). + +* fixed set_labels when inplace=True. + +* fixed array creation functions not raising an exception when called with wrong syntax func(axis1, axis2, ...) + instead of func([axis1, axis2, ...]) (closes :issue:`203`). + +* fixed position of added sheets in excel workbook: new sheets are appended instead of prepended (closes :issue:`229`). + +* fixed Workbook behavior in case of new workbook: the first added sheet replaces the default sheet `Sheet1` + (closes :issue:`230`). + +* fixed name of Workbook sheets created by copying another sheet (closes :issue:`244`). + + >>> wb = open_excel() + >>> wb['name_of_new_sheet'] = wb['name_of_sheet_to_copy'] + +* fixed with_axes warning to refer to set_axes instead of replace_axes. + +* fixed displayed title in viewer: shows path to file associated with current session + current array info + + extra info (closes :issue:`181`) diff --git a/doc/source/changes/version_0_23.rst.inc b/doc/source/changes/version_0_23.rst.inc new file mode 100644 index 000000000..65c8eb3be --- /dev/null +++ b/doc/source/changes/version_0_23.rst.inc @@ -0,0 +1,131 @@ +Miscellaneous improvements +-------------------------- + +* changed display of arrays (closes :issue:`243`): + + >>> ndtest((2, 3)) + a\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + + instead of + + >>> ndtest((2, 3)) + a\b | b0 | b1 | b2 + a0 | 0 | 1 | 2 + a1 | 3 | 4 | 5 + +* `..` can now be used within keys (between []). Previously it could only be used to define new axes. As a reminder, it + generates increasing values between the two bounds. It is slightly different from : which takes everything between + the two bounds **in the axis order**. + + >>> arr = ndrange('a=a1,a0,a2,a3') + >>> arr + a a1 a0 a2 a3 + 0 1 2 3 + >>> arr['a1..a3'] + a a1 a2 a3 + 0 2 3 + + this is different from `:` which takes everything in between the two bounds : + + >>> arr['a1:a3'] + a a1 a0 a2 a3 + 0 1 2 3 + +* in both axes definitions and keys (within []) `..` can now be mixed with `,` and other `..` : + + >>> arr = ndrange('code=A,C..E,G,X..Z') + >>> arr + code A C D E G X Y Z + 0 1 2 3 4 5 6 7 + >>> arr['A,Z..X,G'] + code A Z Y X G + 0 7 6 5 4 + +* within .. extra zeros are only padded to numbers if zeros are present in the pattern. + + >>> ndrange('code=A1..A12') + code A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 + 0 1 2 3 4 5 6 7 8 9 10 11 + + >>> ndrange('code=A01..A12') + code A01 A02 A03 A04 A05 A06 A07 A08 A09 A10 A11 A12 + 0 1 2 3 4 5 6 7 8 9 10 11 + + in previous larray versions, the two above definitions returned the second array. + +* set `sep` argument of from_string function to ' ' by default (closes :issue:`271`). + For 1D array, a "-" must be added in front of the data line. + + >>> from_string('''sex M F + - 0 1''') + sex M F + 0 1 + >>> from_string('''nat\\sex M F + BE 0 1 + FO 2 3''') + nat\sex M F + BE 0 1 + FO 2 3 + +* improved error message when trying to access nonexistent sheet in an Excel workbook (closes :issue:`266`). + +* when creating an Axis from a Group and no explicit name was given, reuse the name of the group axis. + + >>> a = Axis('a=a0..a2') + >>> Axis(a[:'a1']) + Axis(['a0', 'a1'], 'a') + +* allowed to create an array using a single group as if it was an Axis. + + >>> a = Axis('a=a0..a2') + >>> ndrange(a) + a a0 a1 a2 + 0 1 2 + >>> # using a group as an axis + >>> ndrange(a[:'a1']) + a a0 a1 + 0 1 + +* allowed to use axes (Axis objects) to subset arrays (part of :issue:`210`). + + >>> arr = ndtest((2, 3)) + >>> arr + a\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> b2 = Axis('b=b0,b2') + >>> arr[b2] + a\b b0 b2 + a0 0 2 + a1 3 5 + +* improved string representation of Excel workbooks and sheets (they mention the actual file/sheet they correspond to). + This is mostly useful in the interactive console to check what an object corresponds to. + + >>> wb = open_excel() + >>> wb + + >>> wb[0] + + +Fixes +----- + +* open_excel('non existent file') will raise an explicit error immediately when overwrite_file is False, instead of + failing at a seemingly random point later on (closes :issue:`265`). + +* integer-like strings in axis definition strings using `,` are converted to integers to be consistent with string + definitions using `..`. In other words, ndrange('a=1,2,3') did not create the same array than ndrange('a=1..3'). + +* fixed reading a single cell from an Excel sheet. + +* fixed script execution not resuming after quitting the viewer when it was called using view(a_single_array). + +* fixed opening the viewer after showing a plot window. + +* do not display an error when setting the value of an element of a non LArray sequence in the viewer console + + >>> l = [1, 2, 3] + >>> l[0] = 42 diff --git a/doc/source/changes/version_0_24.rst.inc b/doc/source/changes/version_0_24.rst.inc new file mode 100644 index 000000000..5cf0cdfbd --- /dev/null +++ b/doc/source/changes/version_0_24.rst.inc @@ -0,0 +1,94 @@ +New features +------------ + +* implemented Session.to_globals which creates global variables from variables stored in the session (closes + :issue:`276`). Note that this should usually only be used in an interactive console and not in a script. Code editors + are confused by this kind of manipulation and will likely consider as invalid the code using variables created in + this way. Additionally, when using this method auto-completion, "show definition", "go to declaration" and other + similar code editor features will probably not work for the variables created in this way and any variable derived + from them. + + >>> s = Session(arr1=ndtest(3), arr2=ndtest((2, 2))) + >>> s.to_globals() + >>> arr1 + a a0 a1 a2 + 0 1 2 + >>> arr2 + a\b b0 b1 + a0 0 1 + a1 2 3 + +* added new boolean argument 'overwrite' to Session.save, Session.to_hdf, Session.to_excel and Session.to_pickle + methods (closes :issue:`293`). If overwrite=True and the target file already existed, it is deleted and replaced by a + new one. This is the new default behavior. If overwrite=False, an existing file is updated (like it was in previous + larray versions): + + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) + >>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)]) + + >>> # save arr1, arr2 and arr3 in file output.h5 + >>> s.save('output.h5') + + >>> # replace arr1 and create arr4 + put them in an second session + >>> arr1, arr4 = ndtest((3, 3)), ndtest((2, 3)) + >>> s2 = Session([('arr1', arr1), ('arr4', arr4)]) + + >>> # replace arr1 and add arr4 in file output.h5 + >>> s2.save('output.h5', overwrite=False) + + >>> # erase content of 'output.h5' and save only arrays contained in the second session + >>> s2.save('output.h5') + + +Miscellaneous improvements +-------------------------- + +* renamed create_sequential() to sequence() (closes :issue:`212`). + +* improved auto-completion in ipython interactive consoles (e.g. the viewer console) for Axis, AxisCollection, Group + and Workbook objects. These objects can now complete keys within []. + + >>> gender = Axis('gender=Male,Female') + >>> gender + Axis(['Male', 'Female'], 'gender') + gender['Female + >>> gender['Fe # will be completed to `gender['Female` + + >>> arr = ndrange(gender) + >>> arr.axes['gen # will be completed to `arr.axes['gender` + + >>> wb = open_excel() + >>> wb['Sh # will be completed to `wb['Sheet1` + +* added documentation for Session methods (closes :issue:`277`). + +* allowed to provide explict names for arrays or sessions in compare(). Closes :issue:`307`. + + +Fixes +----- + +* fixed title argument of `ndtest` creation function: title was not passed to the returned array. + +* fixed create_sequential when arguments initial and inc are array and scalar respectively (closes :issue:`288`). + +* fixed auto-completion of attributes of LArray and Group objects (closes :issue:`302`). + +* fixed name of arrays/sessions in compare() not being inferred correctly (closes :issue:`306`). + +* fixed indexing Excel sheets by position to always yield the requested shape even when bounds are outside the range of + used cells. Closes :issue:`273`. + +* fixed the array() method on excel.Sheet returning float labels when int labels are expected. + +* fixed getting float data instead of int when converting an Excel Sheet or Range to an larray or numpy array. + +* fixed some warning messages to point to the correct line in user code. + +* fixed crash of Session.save method when it contained 0D arrays. They are now skipped when saving a session (closes + :issue:`291`). + +* fixed Session.save and Session.to_excel failing to create new Excel files (it only worked if the file already + existed). Closes :issue:`313`. + +* fixed Session.load(file, engine='pandas_excel') : axes were considered as anonymous. diff --git a/doc/source/changes/version_0_24_1.rst.inc b/doc/source/changes/version_0_24_1.rst.inc new file mode 100644 index 000000000..04cff855d --- /dev/null +++ b/doc/source/changes/version_0_24_1.rst.inc @@ -0,0 +1,4 @@ +Fixes +----- + +* updated the tutorial to use version 0.24 syntax. diff --git a/doc/source/changes/version_0_25.rst.inc b/doc/source/changes/version_0_25.rst.inc new file mode 100644 index 000000000..c6832296f --- /dev/null +++ b/doc/source/changes/version_0_25.rst.inc @@ -0,0 +1,364 @@ +New features +------------ + +* viewer functions (`view`, `edit` and `compare`) have been moved to the separate `larray-editor` package, + which needs to be installed separately, unless you are using `larrayenv`. + Closes :issue:`332`. + +* installing larray-editor (or larrayenv) from conda environment creates a new menu 'LArray' in the Windows start menu. + It contains a link to open the documentation, a shortcut to launch the user interface in edition mode + and a shortcut to update larrayenv. Closes :issue:`281`. + +* added possibility to transpose an array in the viewer by dragging and dropping axes' names in the filter bar. + +* implemented array.align(other_array) which makes two arrays compatible with each other (by making all common axes + compatible). This is done by adding, removing or reordering labels for each common axis according to the join method + used: + + - outer: will use a label if it is in either arrays axis (ordered like the first array). This is the default as it + results in no information loss. + - inner: will use a label if it is in both arrays axis (ordered like the first array) + - left: will use the first array axis labels + - right: will use the other array axis labels + + The fill value for missing labels defaults to nan. + + >>> arr1 = ndtest((2, 3)) + >>> arr1 + a\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> arr2 = -ndtest((3, 2)) + >>> # reorder array to make the test more interesting + >>> arr2 = arr2[['b1', 'b0']] + >>> arr2 + a\\b b1 b0 + a0 -1 0 + a1 -3 -2 + a2 -5 -4 + + Align arr1 and arr2 + + >>> aligned1, aligned2 = arr1.align(arr2) + >>> aligned1 + a\b b0 b1 b2 + a0 0.0 1.0 2.0 + a1 3.0 4.0 5.0 + a2 nan nan nan + >>> aligned2 + a\b b0 b1 b2 + a0 0.0 -1.0 nan + a1 -2.0 -3.0 nan + a2 -4.0 -5.0 nan + + After aligning all common axes, one can then do operations between the two arrays + + >>> aligned1 + aligned2 + a\b b0 b1 b2 + a0 0.0 0.0 nan + a1 1.0 1.0 nan + a2 nan nan nan + + The fill value for missing labels defaults to nan but can be changed to any compatible value. + + >>> aligned1, aligned2 = arr1.align(arr2, fill_value=0) + >>> aligned1 + a\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + a2 0 0 0 + >>> aligned2 + a\b b0 b1 b2 + a0 0 -1 0 + a1 -2 -3 0 + a2 -4 -5 0 + >>> aligned1 + aligned2 + a\b b0 b1 b2 + a0 0 0 2 + a1 1 1 5 + a2 -4 -5 0 + +* implemented Session.transpose(axes) to reorder axes of all arrays within a session, ignoring missing axes for each + array. For example, let us first create a test session and a small helper function to display sessions as a short + summary. + + >>> arr1 = ndtest((2, 2, 2)) + >>> arr2 = ndtest((2, 2)) + >>> sess = Session([('arr1', arr1), ('arr2', arr2)]) + >>> def print_summary(s): + ... print(s.summary("{name} -> {axes_names}")) + >>> print_summary(sess) + arr1 -> a, b, c + arr2 -> a, b + + Put the 'b' axis in front of all arrays + + >>> print_summary(sess.transpose('b')) + arr1 -> b, a, c + arr2 -> b, a + + Axes missing on an array are ignored ('c' for arr2 in this case) + + >>> print_summary(sess.transpose('c', 'b')) + arr1 -> c, b, a + arr2 -> b, a + + Use ... to move axes to the end + + >>> print_summary(sess.transpose(..., 'a')) + arr1 -> b, c, a + arr2 -> b, a + +* implemented unary operations on Session, which means one can negate all arrays in a Session or take the absolute + value of all arrays in a Session without writing an explicit loop for that. + + >>> arr1 = ndtest(2) + >>> arr1 + a a0 a1 + 0 1 + >>> arr2 = ndtest(4) - 1 + >>> arr2 + a a0 a1 a2 a3 + -1 0 1 2 + >>> sess1 = Session([('arr1', arr1), ('arr2', arr2)]) + >>> sess2 = -sess1 + >>> sess2.arr1 + a a0 a1 + 0 -1 + >>> sess2.arr2 + a a0 a1 a2 a3 + 1 0 -1 -2 + >>> sess3 = abs(sess1) + >>> sess3.arr2 + a a0 a1 a2 a3 + 1 0 1 2 + +* implemented stacking sessions using stack(). + + Let us first create two test sessions. For example suppose we have a session storing the results of a baseline + simulation: + + >>> arr1 = ndtest(2) + >>> arr1 + a a0 a1 + 0 1 + >>> arr2 = ndtest(3) + >>> arr2 + a a0 a1 a2 + 0 1 2 + >>> baseline = Session([('arr1', arr1), ('arr2', arr2)]) + + and another session with a variant + + >>> arr1variant = arr1 * 2 + >>> arr1variant + a a0 a1 + 0 2 + >>> arr2variant = 2 - arr2 / 2 + >>> arr2variant + a a0 a1 a2 + 2.0 1.5 1.0 + >>> variant = Session([('arr1', arr1variant), ('arr2', arr2variant)]) + + then we stack them together + + >>> stacked = stack([('baseline', baseline), ('variant', variant)], 'sessions') + >>> stacked + Session(arr1, arr2) + >>> stacked.arr1 + a\sessions baseline variant + a0 0 0 + a1 1 2 + >>> stacked.arr2 + a\sessions baseline variant + a0 0.0 2.0 + a1 1.0 1.5 + a2 2.0 1.0 + + Combined with the fact that we can compute some very simple expressions on sessions, this can be extremely useful to + quickly compare all arrays of several sessions (e.g. simulation variants): + + >>> diff = variant - baseline + >>> # compute the absolute difference and relative difference for each array of the sessions + >>> stacked = stack([('baseline', baseline), + ('variant', variant), + ('diff', diff), + ('abs diff', abs(diff)), + ('rel diff', diff / baseline)], 'sessions') + >>> stacked + Session(arr1, arr2) + >>> stacked.arr2 + a\sessions baseline variant diff abs diff rel diff + a0 0.0 2.0 2.0 2.0 inf + a1 1.0 1.5 0.5 0.5 0.5 + a2 2.0 1.0 -1.0 1.0 -0.5 + +* implemented Axis.align(other_axis) and AxisCollection.align(other_collection) which makes two axes / axis collections + compatible with each other, see LArray.align above. + +* implemented Session.apply(function) to apply a function to all elements (arrays) of a Session and return a new + Session. + + Let us first create a test session + + >>> arr1 = ndtest(2) + >>> arr1 + a a0 a1 + 0 1 + >>> arr2 = ndtest(3) + >>> arr2 + a a0 a1 a2 + 0 1 2 + >>> sess1 = Session([('arr1', arr1), ('arr2', arr2)]) + >>> sess1 + Session(arr1, arr2) + + Then define the function we want to apply to all arrays of our session + + >>> def increment(element): + ... return element + 1 + + Apply it + + >>> sess2 = sess1.apply(increment) + >>> sess2.arr1 + a a0 a1 + 1 2 + >>> sess2.arr2 + a a0 a1 a2 + 1 2 3 + +* implemented setting the value of multiple points using array.points[labels] = value + + >>> arr = ndtest((3, 4)) + >>> arr + a\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + + Now, suppose you want to retrieve several specific combinations of labels, for example + (a0, b1), (a0, b3), (a1, b0) and (a2, b2). You could write a loop like this: + + >>> values = [] + >>> for a, b in [('a0', 'b1'), ('a0', 'b3'), ('a1', 'b0'), ('a2', 'b2')]: + ... values.append(arr[a, b]) + >>> values + [1, 3, 4, 10] + + but you could also (this already worked in previous versions) use array.points like: + + >>> arr.points[['a0', 'a0', 'a1', 'a2'], ['b1', 'b3', 'b0', 'b2']] + a,b a0,b1 a0,b3 a1,b0 a2,b2 + 1 3 4 10 + + which has the advantages of being both much faster and keep more information. Now suppose you want to *set* the value + of those points, you could write: + + >>> for a, b in [('a0', 'b1'), ('a0', 'b3'), ('a1', 'b0'), ('a2', 'b2')]: + ... arr[a, b] = 42 + >>> arr + a\b b0 b1 b2 b3 + a0 0 42 2 42 + a1 42 5 6 7 + a2 8 9 42 11 + + but now you can also use the faster alternative: + + >>> arr.points[['a0', 'a0', 'a1', 'a2'], ['b1', 'b3', 'b0', 'b2']] = 42 + + +Miscellaneous improvements +-------------------------- + +* added icon to display in Windows start menu and editor windows. + +* viewer keeps labels visible even when scrolling (label rows and columns are now frozen). + +* added 'Getting Started' section in documentation. + +* implemented axes argument to ipfp to specify on which axes the fitting procedure should be applied (closes + :issue:`185`). For example, let us assume you have a 3D array, such as: + + >>> initial = ndrange('a=a0..a9;b=b0..b9;year=2000..2016') + + and you want to apply a 2D fitting procedure for each value of the year axis. Previously, you had to loop on that + year axis explicitly and call ipfp within the loop, like: + + >>> result = zeros(initial.axes) + >>> for year in initial.year: + ... current = initial[year] + ... # assume you have some targets for each year + ... current_targets = [current.sum(x.a) + 1, current.sum(x.b) + 1] + ... result[year] = ipfp(current_targets, current) + + Now you can apply the procedure on all years at once, by telling you want to do the fitting procedure on the other + axes. This is a bit shorter to type, but this is also *much* faster. + + >>> all_targets = [initial.sum(x.a) + 1, initial.sum(x.b) + 1] + >>> result = ipfp(all_targets, initial, axes=(x.a, x.b)) + +* made ipfp 10 to 20% faster (even without using the axes argument). + +* implemented Session.to_globals(inplace=True) which will update the content of existing arrays instead of creating new + variables and overwriting them. This ensures the arrays have the same axes in the session than the existing variables. + +* added the ability to provide a pattern when loading several .csv files as a session. Among others, patterns can use * + to match any number of characters and ? to match any single character. + + >>> s = Session() + >>> # load all .csv files starting with "output" in the data directory + >>> s.load('data/output*.csv') + +* stack can be used with keyword arguments when labels are "simple strings" (i.e. no integers, no punctuation, + no string starting with integers, etc.). This is an attractive alternative but as it only works in the usual case and + not in all cases, it is not recommended to use it except in the interactive console. + + >>> arr1 = ones('nat=BE,FO') + >>> arr1 + nat BE FO + 1.0 1.0 + >>> arr2 = zeros('nat=BE,FO') + >>> arr2 + nat BE FO + 0.0 0.0 + >>> stack(M=arr1, F=arr2, axis='sex=M,F') + nat\\sex M F + BE 1.0 0.0 + FO 1.0 0.0 + + Without passing an explicit order for labels like above (or an axis object), it should only be used on Python 3.6 or + later because keyword arguments are NOT ordered on earlier Python versions. + + >>> # use this only on Python 3.6 and later + >>> stack(M=arr1, F=arr2, axis='sex') + nat\\sex M F + BE 1.0 0.0 + FO 1.0 0.0 + +* binary operations between session now ignore type errors. For example, if you are comparing two sessions with many + arrays by computing the difference between them but a few arrays contain strings, the whole operation will not fail, + the concerned arrays will be assigned a nan instead. + +* added optional argument `ignore_exceptions` to Session.load to ignore exceptions during load. This is mostly useful + when trying to load many .csv files in a Session and some of them have an invalid format but you want to load the + others. + + +Fixes +----- + +* fixed disambiguating an ambiguous key by adding the axis within the string, for example + arr['axis_name[ambiguouslabel]'] (closes :issue:`331`). + +* fixed converting a string group to integer or float using int() and float() (when that makes sense). + + >>> a = Axis('a=10,20,30,total') + >>> a + Axis(['10', '20', '30', 'total'], 'a') + >>> str(a.i[0]) + '10' + >>> int(a.i[0]) + 10 + >>> float(a.i[0]) + 10.0 diff --git a/doc/source/changes/version_0_25_1.rst.inc b/doc/source/changes/version_0_25_1.rst.inc new file mode 100644 index 000000000..b0d9b3e4a --- /dev/null +++ b/doc/source/changes/version_0_25_1.rst.inc @@ -0,0 +1,65 @@ +Miscellaneous improvements +-------------------------- + +* Deprecated methods display a warning message when they are still used (replaced DeprecationWarning by FutureWarning). + Closes :issue:`310`. + +* updated documentation of method `with_total` (closes :issue:`89`). + +* trying to set values of a subset by passing an array with incompatible axes displays a better error message + (closes :issue:`268`). + +Fixes +----- + +* fixed error raised in viewer when switching between arrays when a filter was set. + +* fixed displaying empty array when starting the viewer or a new session in it. + +* fixed Excel instance created via to_excel() and open_excel() without any filename being closed at the end of the + Python program (closes :issue:`390`). + +* fixed the `view()`, `edit()` and `compare()` functions not being available in the viewer console. + +* fixed row and column resizing by double clicking on the edge of an header cell. + +* fixed `New` and `Open` in the menu `File` of the viewer when IPython console is not available. + +* fixed getting a subset of an array by mixing boolean filters and other filters (closes :issue:`246`): + + >>> arr = ndrange('a=a0..a2;b=0..3') + >>> arr + a\b 0 1 2 3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + >>> arr['a0,a2', x.b < 2] + a\b 0 1 + a0 0 1 + a2 8 9 + + Warning: when mixed with other filters, boolean filters are limited to one dimension. + +* fixed setting an array values using `array.points[key] = value` when value is an LArray (closes :issue:`368`). + +* fixed using syntax 'int..int' in a selection (closes :issue:`350`): + + >>> arr = ndrange('a=2017..2012') + >>> arr + a 2017 2016 2015 2014 2013 2012 + 0 1 2 3 4 5 + >>> arr['2012..2015'] + a 2012 2013 2014 2015 + 5 4 3 2 + +* fixed mixing '..' sequences and spaces in an indexing string (closes :issue:`389`): + + >>> arr = ndtest(7) + >>> arr + a a0 a1 a2 a3 a4 a5 a6 + 0 1 2 3 4 5 6 + >>> arr['a0, a2, a4..a6'] + a a0 a2 a4 a5 a6 + 0 2 4 5 6 + +* fixed indexing/aggregating using groups with renaming (using >>) when the axis has mixed type labels (object dtype). diff --git a/doc/source/changes/version_0_25_2.rst.inc b/doc/source/changes/version_0_25_2.rst.inc new file mode 100644 index 000000000..88f420800 --- /dev/null +++ b/doc/source/changes/version_0_25_2.rst.inc @@ -0,0 +1,26 @@ +Miscellaneous improvements +-------------------------- + +* Excel Workbooks opened with open_excel(visible=False) will use the global Excel instance by default and those using + visible=True will use a new Excel instance by default (closes :issue:`405`). + + +Fixes +----- + +* fixed view() which did not show any array (closes :editor_issue:`57`). + +* fixed exceptions in the viewer crashing it when a Qt app was created (e.g. from a plot) before the viewer was started + (closes :editor_issue:`58`). + +* fixed compare() arrays names not being determined correctly (closes :editor_issue:`61`). + +* fixed filters and title not being updated when displaying array created via the console (closes :editor_issue:`55`). + +* fixed array grid not being updated when selecting a variable when no variable was selected + (closes :editor_issue:`56`). + +* fixed copying or plotting multiple rows in the editor when they were selected via drag and drop on headers + (closes :editor_issue:`59`). + +* fixed digits not being automatically updated when changing filters. diff --git a/doc/source/changes/version_0_26.rst.inc b/doc/source/changes/version_0_26.rst.inc new file mode 100644 index 000000000..5d2670069 --- /dev/null +++ b/doc/source/changes/version_0_26.rst.inc @@ -0,0 +1,460 @@ +Syntax changes +-------------- + +* renamed special variable `x` to `X` to let users define an `x` variable in their code without breaking all + subsequent code using that special variable (closes :issue:`167`). + +* renamed Axis.startswith, endswith and matches to startingwith, endingwith and matching to avoid a possible confusion + with str.startswith and endswith which return booleans (closes :issue:`432`). + +* renamed `na` argument of `read_csv`, `read_excel`, `read_hdf` and `read_sas` functions to `fill_value` to avoid + confusion as to what the argument does and to be consistent with `reindex` and `align` (closes :issue:`394`). + +* renamed `split_axis` to `split_axes` to reflect the fact that it can now split several axes at once (see below). + +* renamed `sort_axis` to `sort_axes` to reflect the fact that it can sort multiple axes at once (and does so by + default). + +* renamed several methods with more explicit names (closes :issue:`50`): + + - `argmax`, `argmin`, `argsort` to `labelofmax`, `labelofmin`, `labelsofsorted` + - `posargmax`, `posargmin`, `posargsort` to `indexofmax`, `indexofmin`, `indicesofsorted` + +* renamed PGroup to IGroup to be consistent with other methods, especially the .i methods on axes and arrays + (I is for Index -- P was for Position). + + +Backward incompatible changes +----------------------------- + +* getting a subset using a boolean selection returns an array with labels combined with underscore by defaults + (for consistency with `split_axes` and `combine_axes`). Closes :issue:`376`: + + >>> arr = ndtest((2, 2)) + >>> arr + a\b b0 b1 + a0 0 1 + a1 2 3 + >>> arr[arr < 3] + a_b a0_b0 a0_b1 a1_b0 + 0 1 2 + + +New features +------------ + +* added global_arrays() and arrays() functions to complement the local_arrays() function. They return a Session + containing respectively all arrays defined in global variables and all available arrays (whether they are defined in + local or global variables). + + When used outside of a function, these three functions should have the same results, but inside a function + local_arrays() will return only arrays local to the function, global_arrays() will return only arrays defined + globally and arrays() will return arrays defined either locally or globally. Closes :issue:`416`. + +* a `*` symbol is appended to the window title when unsaved changes are detected in the viewer (closes :editor_issue:`21`). + +* implemented Axis.containing to create a Group with all labels of an axis containing some substring (closes + :issue:`402`). + + >>> people = Axis(['Bruce Wayne', 'Bruce Willis', 'Arthur Dent'], 'people') + >>> people.containing('Will') + people['Bruce Willis'] + +* implemented Group.containing, startingwith, endingwith and matching to create a group with all labels of a group + matching some criterion (closes :issue:`108`). + + >>> group = people.startingwith('Bru') + >>> group + people['Bruce Wayne', 'Bruce Willis'] + >>> group.containing('Will') + people['Bruce Willis'] + +* implemented nan_equal() function to create an array of booleans telling whether each cell of the first array is + equal to the corresponding cell in the other array, even in the presence of NaN. + + >>> arr1 = ndtest(3, dtype=float) + >>> arr1['a1'] = nan + >>> arr1 + a a0 a1 a2 + 0.0 nan 2.0 + >>> arr2 = arr1.copy() + >>> arr1 == arr2 + a a0 a1 a2 + True False True + >>> nan_equal(arr1, arr2) + a a0 a1 a2 + True True True + +* implemented from_frame() to convert a Pandas DataFrame to an array: + + >>> df = ndtest((2, 2, 2)).to_frame() + >>> df + c c0 c1 + a b + a0 b0 0 1 + b1 2 3 + a1 b0 4 5 + b1 6 7 + >>> from_frame(df) + a b\\c c0 c1 + a0 b0 0 1 + a0 b1 2 3 + a1 b0 4 5 + a1 b1 6 7 + +* implemented Axis.split to split an axis into several. + + >>> a_b = Axis('a_b=a0_b0,a0_b1,a0_b2,a1_b0,a1_b1,a1_b2') + >>> a_b.split() + [Axis(['a0', 'a1'], 'a'), Axis(['b0', 'b1', 'b2'], 'b')] + +* added the possibility to load the example dataset used in the tutorial via the menu ``File > Load Example`` + in the viewer + +Miscellaneous improvements +-------------------------- + +* view() and edit() without argument now display global arrays in addition to local ones (closes :editor_issue:`54`). + +* using the mouse scrollwheel on filter combo boxes will switch to the previous/next label. + +* implemented a combobox to choose which color gradient to use and provide a few gradients. + +* inverted background colors in the viewer (red for low values and blue for high values). Closes :editor_issue:`18`. + +* allowed to pass an array of labels as `new_axis` argument to `reindex` method (closes :issue:`384`): + + >>> arr = ndrange('a=v0..v1;b=v0..v2') + >>> arr + a\b v0 v1 v2 + v0 0 1 2 + v1 3 4 5 + >>> arr.reindex('a', arr.b.labels) + a\b v0 v1 v2 + v0 0 1 2 + v1 3 4 5 + v2 nan nan nan + +* allowed to call the `reindex` method using a differently named axis for labels (closes :issue:`386`): + + >>> arr = ndrange('a=v0..v1;b=v0..v2') + >>> arr + a\b v0 v1 v2 + v0 0 1 2 + v1 3 4 5 + >>> arr.reindex('a', arr.b) + a\b v0 v1 v2 + v0 0 1 2 + v1 3 4 5 + v2 nan nan nan + +* arguments `fill_value`, `sort_rows` and `sort_columns` of `read_excel` function are also supported by the default + `xlwings` engine (closes :issue:`393`). + +* allowed to pass a label or group as `sheet_name` argument of the method `to_excel` or to a Workbook (`open_excel`). + Same for `key` argument of the method `to_hdf`. Closes :issue:`328`. + + >>> arr = ndtest((4, 4, 4)) + + >>> # iterate over labels of a given axis + >>> with open_excel('my_file.xlsx') as wb: + >>> for label in arr.a: + ... wb[label] = arr[label].dump() + ... wb.save() + >>> for label in arr.a: + ... arr[label].to_hdf('my_file.h5', label) + + >>> # create and use a group + >>> even = arr.a['a0,a2'] >> 'even' + >>> arr[even].to_excel('my_file.xlsx', even) + >>> arr[even].to_hdf('my_file.h5', even) + + >>> # special characters : \ / ? * [ or ] in labels or groups are replaced by an _ when exporting to excel + >>> # sheet names cannot exceed 31 characters + >>> g = arr.a['a1,a3,a4'] >> '?name:with*special\/[char]' + >>> arr[g].to_excel('my_file.xlsx', g) + >>> print(open_excel('my_file.xlsx').sheet_names()) + ['_name_with_special___char_'] + >>> # special characters \ or / in labels or groups are replaced by an _ when exporting to HDF file + +* allowed to pass a Group to `read_excel`/`read_hdf` as `sheetname`/`key` argument (closes :issue:`439`). + + >>> a, b, c = arr.a, arr.b, arr.c + + >>> # For Excel + >>> new_from_excel = zeros((a, b, c), dtype=int) + >>> for label in a: + ... new_from_excel[label] = read_excel('my_file.xlsx', label) + >>> # But, to avoid loading the file in Excel repeatedly (which is very inefficient), + >>> # this particular example should rather be written like this: + >>> new_from_excel = zeros((a, b, c), dtype=int) + >>> with open_excel('my_file.xlsx') as wb: + ... for label in a: + ... new_from_excel[label] = wb[label].load() + + >>> # For HDF + >>> new_from_hdf = zeros((a, b, c), dtype=int) + >>> for label in a: + ... new_from_hdf[label] = read_hdf('my_file.h5', label) + +* allowed setting the name of a Group using another Group or Axis (closes :issue:`341`): + + >>> arr = ndrange('axis=a,a0..a3,b,b0..b3,c,c0..c3') + >>> arr + axis a a0 a1 a2 a3 b b0 b1 b2 b3 c c0 c1 c2 c3 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + >>> # matches('^.$') will select labels with only one character: 'a', 'b' and 'c' + >>> groups = tuple(arr.axis.startswith(code) >> code for code in arr.axis.matches('^.$')) + >>> groups + (axis['a', 'a0', 'a1', 'a2', 'a3'] >> 'a', + axis['b', 'b0', 'b1', 'b2', 'b3'] >> 'b', + axis['c', 'c0', 'c1', 'c2', 'c3'] >> 'c') + >>> arr.sum(groups) + axis a b c + 10 35 60 + +* allowed to test if an array contains a label using the `in` operator (closes :issue:`343`): + + >>> arr = ndrange('age=0..99;sex=M,F') + >>> 'M' in arr + True + >>> 'Male' in arr + False + >>> # this can be useful for example in an 'if' statement + >>> if 102 not in arr: + ... # with 'reindex', we extend 'age' axis to 102 + ... arr = arr.reindex('age', Axis('age=0..102'), fill_value=0) + >>> arr.info + 103 x 2 + age [103]: 0 1 2 ... 100 101 102 + sex [2]: 'M' 'F' + +* allowed to create a group on an axis using labels of another axis (closes :issue:`362`): + + >>> year = Axis('year=2000..2017') + >>> even_year = Axis(range(2000, 2017, 2), 'even_year') + >>> group_even_year = year[even_year] + >>> group_even_year + year[2000, 2002, 2004, 2006, 2008, 2010, 2012, 2014, 2016] + +* `split_axes` (formerly `split_axis`) now allows to split several axes at once (closes :issue:`366`): + + >>> combined = ndrange('a_b = a0_b0..a1_b1; c_d = c0_d0..c1_d1') + >>> combined + a_b\c_d c0_d0 c0_d1 c1_d0 c1_d1 + a0_b0 0 1 2 3 + a0_b1 4 5 6 7 + a1_b0 8 9 10 11 + a1_b1 12 13 14 15 + >>> combined.split_axes(['a_b', 'c_d']) + a b c\d d0 d1 + a0 b0 c0 0 1 + a0 b0 c1 2 3 + a0 b1 c0 4 5 + a0 b1 c1 6 7 + a1 b0 c0 8 9 + a1 b0 c1 10 11 + a1 b1 c0 12 13 + a1 b1 c1 14 15 + >>> combined.split_axes({'a_b': ('A', 'B'), 'c_d': ('C', 'D')}) + A B C\D d0 d1 + a0 b0 c0 0 1 + a0 b0 c1 2 3 + a0 b1 c0 4 5 + a0 b1 c1 6 7 + a1 b0 c0 8 9 + a1 b0 c1 10 11 + a1 b1 c0 12 13 + a1 b1 c1 14 15 + +* argument `axes` of `split_axes` has become optional: defaults to all axes whose name contains the specified delimiter + (closes :issue:`365`): + + >>> combined = ndrange('a_b = a0_b0..a1_b1; c_d = c0_d0..c1_d1') + >>> combined + a_b\c_d c0_d0 c0_d1 c1_d0 c1_d1 + a0_b0 0 1 2 3 + a0_b1 4 5 6 7 + a1_b0 8 9 10 11 + a1_b1 12 13 14 15 + >>> combined.split_axes() + a b c\d d0 d1 + a0 b0 c0 0 1 + a0 b0 c1 2 3 + a0 b1 c0 4 5 + a0 b1 c1 6 7 + a1 b0 c0 8 9 + a1 b0 c1 10 11 + a1 b1 c0 12 13 + a1 b1 c1 14 15 + +* allowed to perform several axes combinations at once with the `combine_axes()` method (closes :issue:`382`): + + >>> arr = ndtest((2, 2, 2, 2)) + >>> arr + a b c\d d0 d1 + a0 b0 c0 0 1 + a0 b0 c1 2 3 + a0 b1 c0 4 5 + a0 b1 c1 6 7 + a1 b0 c0 8 9 + a1 b0 c1 10 11 + a1 b1 c0 12 13 + a1 b1 c1 14 15 + >>> arr.combine_axes([('a', 'c'), ('b', 'd')]) + a_c\b_d b0_d0 b0_d1 b1_d0 b1_d1 + a0_c0 0 1 4 5 + a0_c1 2 3 6 7 + a1_c0 8 9 12 13 + a1_c1 10 11 14 15 + >>> # set output axes names by passing a dictionary + >>> arr.combine_axes({('a', 'c'): 'ac', ('b', 'd'): 'bd'}) + ac\bd b0_d0 b0_d1 b1_d0 b1_d1 + a0_c0 0 1 4 5 + a0_c1 2 3 6 7 + a1_c0 8 9 12 13 + a1_c1 10 11 14 15 + +* allowed to use keyword arguments in `set_labels` (closes :issue:`383`): + + >>> a = ndrange('nat=BE,FO;sex=M,F') + >>> a + nat\sex M F + BE 0 1 + FO 2 3 + >>> a.set_labels(sex='Men,Women', nat='Belgian,Foreigner') + nat\sex Men Women + Belgian 0 1 + Foreigner 2 3 + +* allowed passing an axis to `set_labels` as 'labels' argument (closes :issue:`408`). + +* added data type (dtype) to array.info (closes :issue:`454`): + + >>> arr = ndtest((2, 2), dtype=float) + >>> arr + a\b b0 b1 + a0 0.0 1.0 + a1 2.0 3.0 + >>> arr.info + 2 x 2 + a [2]: 'a0' 'a1' + b [2]: 'b0' 'b1' + dtype: float64 + +* To create a 1D array using from_string() and the default separator " ", a tabulation character ``\t`` + (instead of ``-`` previously) must be added in front of the data line: + + >>> from_string('''sex M F + ... \t 0 1''') + sex M F + 0 1 + +* viewer window title also includes the dtype of the current displayed array (closes :editor_issue:`85`) + +* viewer window title uses only the file name instead of the entire file path as it made titles too long in some cases. + +* when editing .csv files, the viewer window title will be "directory\fname.csv - axes_info" instead of having the + file name repeated as before ("dir\fname.csv - fname: axes_info"). + +* the viewer will not update digits/scientific notation nor colors when the filter changes, so that numbers are + more easily comparable when quickly changing the filter, especially using the scrollwheel on filter boxes. + +* NaN values display as grey in the viewer so that they stand out more. + +* compare() will color values depending on relative difference instead of absolute difference as this is usually more + useful. + +* compare(sessions) uses nan_equal to compare arrays so that identical arrays are not marked different when they + contain NaN values. + +* changed compare() "stacked axis" names: arrays -> array and sessions -> session because that reads a bit more + naturally. + + +Fixes +----- + +* fixed array creation with axis(es) given as string containing only one label (axis name and label were inverted). + +* fixed reading an array from a CSV or Excel file when the columns axis is not explicitly named (via ``\``). + For example, let's say we want to read a CSV file 'pop.csv' with the following content (indented for clarity) :: + + sex, 2015, 2016 + F, 11, 13 + M, 12, 10 + + The result of function `read_csv` is: + + >>> pop = read_csv('pop.csv') + >>> pop + sex\{1} 2015 2016 + F 11 13 + M 12 10 + + Closes :issue:`372`. + +* fixed converting a 1xN Pandas DataFrame to an array using `aslarray` (closes :issue:`427`): + + >>> df = pd.DataFrame([[1, 2, 3]], index=['a0'], columns=['b0', 'b1', 'b2']) + >>> df + b0 b1 b2 + a0 1 2 3 + >>> aslarray(df) + {0}\{1} b0 b1 b2 + a0 1 2 3 + + >>> # setting name to index and columns + >>> df.index.name = 'a' + >>> df.columns.name = 'b' + >>> df + b b0 b1 b2 + a + a0 1 2 3 + >>> aslarray(df) + a\b b0 b1 b2 + a0 1 2 3 + +* fixed original file being deleted when trying to overwrite a file via `Session.save` or `open_excel` failed + (closes :issue:`441`) + +* fixed loading arrays from Excel sheets containing blank cells below or right of the array to read + (closes :issue:`443`) + +* fixed unary and binary operations between sessions failing entirely when the operation failed/was invalid on any + array. Now the result will be nan for that array but the operation will carry on for other arrays. + +* fixed stacking sessions failing entirely when the stacking failed on any array. Now the result will be nan for that + array but the operation will carry on for other arrays. + +* fixed stacking arrays with anonymous axes. + +* fixed applying `split_axes` on an array with labels of type 'Object' (could happen when an array is read from a file). + +* fixed background color in the viewer when using filters in the `compare()` dialog (closes :editor_issue:`66`) + +* fixed autoresize of columns by double clicking between column headers (closes :editor_issue:`43`) + +* fixed representing a 0D array (scalar) in the viewer (closes :editor_issue:`71`) + +* fixed viewer not displaying an error message when saving or loading a file failed (closes :editor_issue:`75`) + +* fixed array.split_axis when the combined axis does not contain all the combination of labels resulting + from the split (closes :issue:`369`). + +* fixed array.split_axis when combined labels are not sorted by the first part then second part (closes :issue:`364`). + +* fixed opening .csv files in the editor will create variables named using only the filename without extension (instead + of being named using the full path of the file -- making it almost useless). Closes :editor_issue:`90`. + +* fixed deleting a variable (using the del key in the list) not marking the session/file as being modified. + +* fixed the link to the tutorial (Help->Online Tutorial) (closes :editor_issue:`92`). + +* fixed inplace modifications of arrays in the console (via array[xxx] = value) not updating the view (closes + :editor_issue:`94`). + +* fixed background color in compare() being wrong after changing axes order by drag-and-dropping them (closes + :editor_issue:`89`). + +* fixed the whole array/compare being the same color in the presence of -inf or +inf in the array. diff --git a/doc/source/changes/version_0_26_1.rst.inc b/doc/source/changes/version_0_26_1.rst.inc new file mode 100644 index 000000000..b56152683 --- /dev/null +++ b/doc/source/changes/version_0_26_1.rst.inc @@ -0,0 +1,17 @@ +Miscellaneous improvements +-------------------------- + +* Made handling Excel sheets with many blank columns/rows after the data much faster (but still slower than sheets + without such blank cells). + +Fixes +----- + +* fixed reading from and writing to Excel sheets with 16384 columns or 1048576 rows (Excel's maximum). + +* fixed LArray.split_axes using a custom separator and not using sort=True or when the split labels are + ambiguous with labels from other axes (closes :issue:`485`). + +* fixed reading 1D arrays with non-string labels (closes :issue:`495`). + +* fixed read_csv(sort_columns=True) for 1D arrays (closes :issue:`497`). diff --git a/doc/source/changes/version_0_27.rst.inc b/doc/source/changes/version_0_27.rst.inc new file mode 100644 index 000000000..3d5f0eeff --- /dev/null +++ b/doc/source/changes/version_0_27.rst.inc @@ -0,0 +1,178 @@ +Syntax changes +-------------- + +* renamed `Axis.translate` to `Axis.index` (closes :issue:`479`). + +* deprecated `reverse` argument of `sort_values` and `sort_axes` methods in favor of `ascending` argument + (defaults to True). Closes :issue:`540`. + + +Backward incompatible changes +----------------------------- + +* labels are checked during array subset assignment (closes :issue:`269`): + + >>> arr = ndtest(4) + >>> arr + a a0 a1 a2 a3 + 0 1 2 3 + >>> arr['a0,a1'] = arr['a2,a3'] + ValueError: incompatible axes: + Axis(['a0', 'a1'], 'a') + vs + Axis(['a2', 'a3'], 'a') + + previous behavior can be recovered through `drop_labels` or by changing labels via `set_labels` or `set_axes`: + + >>> arr['a0,a1'] = arr['a2,a3'].drop_labels('a') + >>> arr['a0,a1'] = arr['a2,a3'].set_labels('a', {'a2': 'a0', 'a3': 'a1'}) + +* from_frame `parse_header` argument defaults to `False` instead of `True`. + + +New features +------------ + +* implemented Axis.insert and LArray.insert to add values at a given position of an axis (closes :issue:`54`). + + >>> arr1 = ndtest((2, 3)) + >>> arr1 + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> arr1.insert(42, before='b1', label='b0.5') + a\\b b0 b0.5 b1 b2 + a0 0 42 1 2 + a1 3 42 4 5 + + insert an array + + >>> arr2 = ndtest(2) + >>> arr2 + a a0 a1 + 0 1 + >>> arr1.insert(arr2, after='b0', label='b0.5') + a\\b b0 b0.5 b1 b2 + a0 0 0 1 2 + a1 3 1 4 5 + + insert an array which already has the axis + + >>> arr3 = ndrange('a=a0,a1;b=b0.1,b0.2') + 42 + >>> arr3 + a\\b b0.1 b0.2 + a0 42 43 + a1 44 45 + >>> arr1.insert(arr3, before='b1') + a\\b b0 b0.1 b0.2 b1 b2 + a0 0 42 43 1 2 + a1 3 44 45 4 5 + +* added new items in the Help menu of the editor: + + - `Report Issue...`: to report an issue on the Github project website. + - `Users Discussion...`: redirect to the LArray Users Google Group (you need to be registered to participate). + - `New Releases And Announces Mailing List...`: redirect to the LArray Announce mailing list. + - `About`: give information about the editor and the versions of packages currently installed on your computer + (closes :editor_issue:`88`). + +* added `Save Command History To Script` in the File menu of the editor allowing to save executed commands in a new or + existing Python file. + +* added possibility to show only rows with differences when comparing arrays or sessions through the `compare` + function in the editor (closes :editor_issue:`102`). + +* added `ascending` argument to methods `indicesofsorted` and `labelsofsorted`. + Values are sorted in ascending order by default. Set to False to sort values in descending order: + + >>> arr = LArray([[1, 5], [3, 2], [0, 4]], "nat=BE,FR,IT; sex=M,F") + >>> arr + nat\sex M F + BE 1 5 + FR 3 2 + IT 0 4 + >>> arr.indicesofsorted("nat", ascending=False) + nat\sex M F + 0 1 0 + 1 0 2 + 2 2 1 + >>> arr.labelsofsorted("nat", ascending=False) + nat\sex M F + 0 FR BE + 1 BE IT + 2 IT FR + + Closes :issue:`490`. + + +Miscellaneous improvements +-------------------------- + +* allowed to sort values of an array along an axis (closes :issue:`225`): + + >>> a = LArray([[10, 2, 4], [3, 7, 1]], "sex=M,F; nat=EU,FO,BE") + >>> a + sex\nat EU FO BE + M 10 2 4 + F 3 7 1 + >>> a.sort_values(axis='sex') + sex*\nat EU FO BE + 0 3 2 1 + 1 10 7 4 + >>> a.sort_values(axis='nat') + sex\nat* 0 1 2 + M 2 4 10 + F 1 3 7 + +* method `LArray.sort_values` can be called without argument (closes :issue:`478`): + + >>> arr = LArray([0, 1, 6, 3, -1], "a=a0..a4") + >>> arr + a a0 a1 a2 a3 a4 + 0 1 6 3 -1 + >>> arr.sort_values() + a a4 a0 a1 a3 a2 + -1 0 1 3 6 + + If the array has more than one dimension, axes are combined together: + + >>> a = LArray([[10, 2, 4], [3, 7, 1]], "sex=M,F; nat=EU,FO,BE") + >>> a + sex\nat EU FO BE + M 10 2 4 + F 3 7 1 + >>> a.sort_values() + sex_nat F_BE M_FO F_EU M_BE F_FO M_EU + 1 2 3 4 7 10 + +* when appending/prepending/extending an array, both the original array and the added values will be converted to a + data type which can hold both without loss of information. It used to convert the added values to the type of the + original array. For example, given an array of integers like: + + >>> arr = ndtest(3) + a a0 a1 a2 + 0 1 2 + + Trying to add a floating point number to that array used to result in: + + >>> arr.append('a', 2.5, 'a3') + a a0 a1 a2 a3 + 0 1 2 2 + + Now it will result in: + + >>> arr.append('a', 2.5, 'a3') + a a0 a1 a2 a3 + 0.0 1.0 2.0 2.5 + +* made the editor more responsive when switching to or changing the filter of large arrays (closes :issue:`93`). + +* added support for coloring numeric values for object arrays (e.g. arrays containing both strings and numbers). + +* documentation links in the Help menu of the editor point to the version of the documentation corresponding to + the installed version of larray (closes :editor_issue:`105`). + +Fixes +----- + +* fixed array values being editable in view() (instead of only in edit()). diff --git a/doc/source/changes/version_0_28.rst.inc b/doc/source/changes/version_0_28.rst.inc new file mode 100644 index 000000000..867b73787 --- /dev/null +++ b/doc/source/changes/version_0_28.rst.inc @@ -0,0 +1,432 @@ +Backward incompatible changes +----------------------------- + +* changed behavior of operators `session1 == session2` and `session1 != session2`: returns a session + of boolean arrays (closes :issue:`516`): + + >>> s1 = Session([('arr1', ndtest(2)), ('arr2', ndtest((2, 2)))]) + >>> s2 = Session([('arr1', ndtest(2)), ('arr2', ndtest((2, 2)))]) + >>> (s1 == s2).arr1 + a a0 a1 + True True + >>> s2.arr1['a1'] = 0 + >>> (s1 == s2).arr1 + a a0 a1 + True False + >>> (s1 != s2).arr1 + a a0 a1 + False True + + +New features +------------ + +* made it possible to run the tutorial online (as a Jupyter notebook) by clicking on the ``launch|binder`` badge + on top of the tutorial web page (closes :issue:`73`) + +* added methods `array_equals` and `equals` to `Session` object to compare arrays from two sessions. + The method `array_equals` return a boolean value for each array while the method `equals` returns a unique + boolean value (True if all arrays of both sessions are equal, False otherwise): + + >>> s1 = Session([('arr1', ndtest(2)), ('arr2', ndtest((2, 2)))]) + >>> s2 = Session([('arr1', ndtest(2)), ('arr2', ndtest((2, 2)))]) + >>> s1.array_equals(s2) + name arr1 arr2 + True True + >>> s1.equals(s2) + True + + Different value(s) + + >>> s2.arr1['a1'] = 0 + >>> s1.array_equals(s2) + name arr1 arr2 + False True + >>> s1.equals(s2) + False + + Different label(s) + + >>> from larray import ndrange + >>> s2.arr2 = ndrange("b=b0,b1; a=a0,a1") + >>> s1.array_equals(s2) + name arr1 arr2 + False False + >>> s1.equals(s2) + False + + Extra/missing array(s) + + >>> s2.arr3 = ndtest((3, 3)) + >>> s1.array_equals(s2) + name arr1 arr2 arr3 + False False False + >>> s1.equals(s2) + False + + Closes :issue:`517`. + +* added method `equals` to `LArray` object to compare two arrays: + + >>> arr1 = ndtest((2, 3)) + >>> arr1 + a\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> arr2 = arr1.copy() + >>> arr1.equals(arr2) + True + >>> arr2['b1'] += 1 + >>> arr1.equals(arr2) + False + >>> arr3 = arr1.set_labels('a', ['x0', 'x1']) + >>> arr1.equals(arr3) + False + + Arrays with nan values + + >>> arr1 = ndtest((2, 3), dtype=float) + >>> arr1['a1', 'b1'] = nan + >>> arr1 + a\b b0 b1 b2 + a0 0.0 1.0 2.0 + a1 3.0 nan 5.0 + >>> arr2 = arr1.copy() + >>> # By default, an array containing nan values is never equal to another array, + >>> # even if that other array also contains nan values at the same positions. + >>> # The reason is that a nan value is different from *anything*, including itself. + >>> arr1.equals(arr2) + False + >>> # set flag nan_equal to True to override this behavior + >>> arr1.equals(arr2, nan_equal=True) + True + + This method also includes the arguments `rtol` (relative tolerance) and `atol` (absolute tolerance) + allowing to test the equality between two arrays within a given relative or absolute tolerance: + + >>> arr1 = LArray([6., 8.], "a=a0,a1") + >>> arr1 + a a0 a1 + 6.0 8.0 + >>> arr2 = LArray([5.999, 8.001], "a=a0,a1") + >>> arr2 + a a0 a1 + 5.999 8.001 + >>> arr1.equals(arr2) + False + >>> # equals returns True if abs(array1 - array2) <= (atol + rtol * abs(array2)) + >>> arr1.equals(arr2, atol=0.01) + True + >>> arr1.equals(arr2, rtol=0.01) + True + + Closes :issue:`488` and :issue:`518`. + +* added `Load from Script` in the File menu of the editor allowing to load commands from an + existing Python file (closes :editor_issue:`96`). + +* added `Edit` menu allowing to undo and redo changes of array values by editing cells and + removed `Apply` and `Discard` buttons. Changes are now kept when switching from an array to another + instead of losing them as previously (closes :editor_issue:`32`). + +* allowed to provide an absolute or relative tolerance value when comparing arrays through the `compare` function + (closes :editor_issue:`131`). + +* made the editor able to detect and display plot objects stored in tuple, list or arrays. + For example, arrays of plot objects are returned when using `subplots=True` option in calls of `plot` method: + + >>> a = ndtest('sex=M,F; nat=BE,FO; year=2000..2017') + >>> # display 4 plots vertically placed (one plot for each pair (sex, nationality)) + >>> a.plot(subplots=True) + >>> # display 4 plots ordered in a 2 x 2 grid + >>> a.plot(subplots=True, layout=(2, 2)) + + Closes :editor_issue:`135`. + + +Miscellaneous improvements +-------------------------- + +* functions `local_arrays`, `global_arrays` and `arrays` returns a session excluding arrays starting by + an underscore by default. To include them, set the flag `include_private` to True (closes :issue:`513`): + + >>> global_arr1 = ndtest((2, 2)) + >>> _global_arr2 = ndtest((3, 3)) + >>> def foo(): + ... local_arr1 = ndtest(2) + ... _local_arr2 = ndtest(3) + ... + ... # exclude arrays starting with '_' by default + ... s = arrays() + ... print(s.names) + ... + ... # use flag 'include_private' to include arrays starting with '_' + ... s = arrays(include_private=True) + ... print(s.names) + >>> foo() + ['global_arr1', 'local_arr1'] + ['_global_arr2', '_local_arr2', 'global_arr1', 'local_arr1'] + +* implemented sessions binary operations with non sessions objects (closes :issue:`514` and :issue:`515`): + + >>> s = Session(arr1=ndtest((2, 2)), arr2=ndtest((3, 3))) + >>> s.arr1 + a\b b0 b1 + a0 0 1 + a1 2 3 + >>> s.arr2 + a\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + a2 6 7 8 + + Add a scalar to all arrays + + >>> # equivalent to s2 = 3 + s + >>> s2 = s + 3 + >>> s2.arr1 + a\b b0 b1 + a0 3 4 + a1 5 6 + >>> s2.arr2 + a\b b0 b1 b2 + a0 3 4 5 + a1 6 7 8 + a2 9 10 11 + + Apply binary operations between two sessions + + >>> sdiff = (s2 - s) / s + >>> sdiff.arr1 + a\b b0 b1 + a0 inf 3.0 + a1 1.5 1.0 + >>> sdiff.arr2 + a\b b0 b1 b2 + a0 inf 3.0 1.5 + a1 1.0 0.75 0.6 + a2 0.5 0.43 0.375 + +* added possibility to call the method `reindex` with a group (closes :issue:`531`): + + >>> arr = ndtest((2, 2)) + >>> arr + a\b b0 b1 + a0 0 1 + a1 2 3 + >>> b = Axis("b=b2..b0") + >>> arr.reindex('b', b['b1':]) + a\b b1 b0 + a0 1 0 + a1 3 2 + +* added possibility to call the methods `diff` and `growth_rate` with a group (closes :issue:`532`): + + >>> data = [[2, 4, 5, 4, 6], [4, 6, 3, 6, 9]] + >>> a = LArray(data, "sex=M,F; year=2016..2020") + >>> a + sex\year 2016 2017 2018 2019 2020 + M 2 4 5 4 6 + F 4 6 3 6 9 + >>> a.diff(a.year[2017:]) + sex\year 2018 2019 2020 + M 1 -1 2 + F -3 3 3 + >>> a.growth_rate(a.year[2017:]) + sex\year 2018 2019 2020 + M 0.25 -0.2 0.5 + F -0.5 1.0 0.5 + +* function `ndrange` has been deprecated in favor of `sequence` or `ndtest`. + Also, an Axis or a list/tuple/collection of axes can be passed to the `ndtest` function (closes :issue:`534`): + + >>> ndtest("nat=BE,FO;sex=M,F") + nat\sex M F + BE 0 1 + FO 2 3 + +* allowed to pass a group for argument `axis` of `stack` function (closes :issue:`535`): + + >>> b = Axis('b=b0..b2') + >>> stack(b0=ndtest(2), b1=ndtest(2), axis=b[:'b1']) + a\b b0 b1 + a0 0 0 + a1 1 1 + +* renamed argument `nb_index` of `read_csv`, `read_excel`, `read_sas`, `from_lists` and `from_string` functions + as `nb_axes`. The relation between `nb_index` and `nb_axes` is given by `nb_axes = nb_index + 1`: + + For a given file 'arr.csv' with content :: + + a,b\c,c0,c1 + a0,b0,0,1 + a0,b1,2,3 + a1,b0,4,5 + a1,b1,6,7 + + previous code to read this array such as : + + >>> # deprecated + >>> arr = read_csv('arr.csv', nb_index=2) + + must be updated as follow : + + >>> arr = read_csv('arr.csv', nb_axes=3) + + Closes :issue:`548`. + +* deprecated `nan_equal` function in favor of `element_equal` function. The `element_equal` function has the + same optional arguments as the `LArray.equals` method but compares two arrays element-wise and + returns an array of booleans: + + >>> arr1 = LArray([6., np.nan, 8.], "a=a0..a2") + >>> arr1 + a a0 a1 a2 + 6.0 nan 8.0 + >>> arr2 = LArray([5.999, np.nan, 8.001], "a=a0..a2") + >>> arr2 + a a0 a1 a2 + 5.999 nan 8.001 + >>> element_equal(arr1, arr2) + a a0 a1 a2 + False False False + >>> element_equal(arr1, arr2, nan_equals=True) + a a0 a1 a2 + False True False + >>> element_equal(arr1, arr2, atol=0.01, nan_equals=True) + a a0 a1 a2 + True True True + >>> element_equal(arr1, arr2, rtol=0.01, nan_equals=True) + a a0 a1 a2 + True True True + + Closes :issue:`593`. + +* renamed argument `transpose` by `wide` in `to_csv` method. + +* added argument `wide` in `to_excel` method. When argument `wide` is set to False, the array is exported + in "narrow" format, i.e. one column per axis plus one value column: + + >>> arr = ndtest((2, 3)) + >>> arr + a\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + + Default behavior (`wide=True`): + + >>> arr.to_excel('my_file.xlsx') + a\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + + With `wide=False`: + + >>> arr.to_excel('my_file.xlsx', wide=False) + a b value + a0 b0 0 + a0 b1 1 + a0 b2 2 + a1 b0 3 + a1 b1 4 + a1 b2 5 + + Argument `transpose` has a different purpose than `wide` and is mainly useful to allow multiple axes as header + when exporting arrays with more than 2 dimensions. Closes :issue:`575` and :issue:`371`. + +* added argument `wide` to `read_csv` and `read_excel` functions. If False, the array to be loaded is assumed to + be stored in "narrow" format: + + >>> # assuming the array was saved using command: arr.to_excel('my_file.xlsx', wide=False) + >>> read_excel('my_file.xlsx', wide=False) + a\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + + Closes :issue:`574`. + +* added argument `name` to `to_series` method allowing to set a name to the Pandas Series returned by the method. + +* added argument `value_name` to `to_csv` and `to_excel` allowing to change the default name ('value') to + the column containg the values when the argument `wide` is set to False: + + >>> arr.to_csv('my_file.csv', wide=False, value_name='data') + a,b,data + a0,b0,0 + a0,b1,1 + a0,b2,2 + a1,b0,3 + a1,b1,4 + a1,b2,5 + + Closes :issue:`549`. + +* renamed argument `sheetname` of `read_excel` function as `sheet` (closes :issue:`587`). + +* Renamed `sheet_name` of `LArray.to_excel` to `sheet` since it can also be an index (closes :issue:`580`). + +* allowed to create axes with zero padded string labels (closes :issue:`533`): + + >>> Axis('zero_padding=01,02,03,10,11,12') + Axis(['01', '02', '03', '10', '11', '12'], 'zero_padding') + +* added a dropdown menu containing recently used files in dialog boxes of `Save Command History To Script` + and `Load from Script` from File menu. + + +Fixes +----- + +* fixed passing a scalar group from an external axis to get a subset of an array (closes :issue:`178`): + + >>> arr = ndtest((3, 2)) + >>> arr['a1'] + b b0 b1 + 2 3 + >>> alt_a = Axis("alt_a=a1..a2") + >>> arr[alt_a['a1']] + b b0 b1 + 2 3 + >>> arr[alt_a.i[0]] + b b0 b1 + 2 3 + +* fixed subscript a string LGroup key (closes :issue:`437`): + + >>> axis = Axis("a=a0,a1") + >>> axis['a0'][0] + 'a' + +* fixed `Axis.union`, `Axis.intersection` and `Axis.difference` when passed value is a single string + (closes :issue:`489`): + + >>> a = Axis('a=a0..a2') + >>> a.union('a1') + Axis(['a0', 'a1', 'a2'], 'a') + >>> a.union('a3') + Axis(['a0', 'a1', 'a2', 'a3'], 'a') + >>> a.union('a1..a3') + Axis(['a0', 'a1', 'a2', 'a3'], 'a') + >>> a.intersection('a1..a3') + Axis(['a1', 'a2'], 'a') + >>> a.difference('a1..a3') + Axis(['a0'], 'a') + +* fixed `to_excel` applied on >= 2D arrays using `transpose=True` (closes :issue:`579`) + + >>> arr = ndtest((2, 3)) + >>> arr.to_excel('my_file.xlsx', transpose=True) + b\a a0 a1 + b0 0 3 + b1 1 4 + b2 2 5 + +* fixed aggregation on arrays containing zero padded string labels (closes :issue:`522`): + + >>> arr = ndtest('zero_padding=01,02,03,10,11,12') + >>> arr + zero_padding 01 02 03 10 11 12 + 0 1 2 3 4 5 + >>> arr.sum('01,02,03 >> 01_03; 10') + zero_padding 01_03 10 + 3 3 diff --git a/doc/source/changes/version_0_2_1.rst.inc b/doc/source/changes/version_0_2_1.rst.inc new file mode 100644 index 000000000..2934af3b4 --- /dev/null +++ b/doc/source/changes/version_0_2_1.rst.inc @@ -0,0 +1,15 @@ +New features +------------ + +* implemented LArray.shift(axis, n=1) + +Miscellaneous improvements +-------------------------- + +* change set_labels API (axis, new_labels) +* transform Axis.labels into a property so that _mapping is kept in sync + +Fixes +----- + +* hopefully fix build diff --git a/doc/source/changes/version_0_2_2.rst.inc b/doc/source/changes/version_0_2_2.rst.inc new file mode 100644 index 000000000..2ef56714f --- /dev/null +++ b/doc/source/changes/version_0_2_2.rst.inc @@ -0,0 +1,20 @@ +New features +------------ + +* implement AxisCollection.replace(old_axis, new_axis) +* implement positional indexing + +Miscellaneous improvements +-------------------------- + +* more powerful AxisCollection.pop + added support .pop(name) or .pop(Axis object) + +* LArray.set_labels returns a new LArray by default + use inplace=True to get previous behavior +* include ndrange and __version__ in __all__ + +Fixes +----- + +* fixed shift with n <= 0 diff --git a/doc/source/changes/version_0_2_3.rst.inc b/doc/source/changes/version_0_2_3.rst.inc new file mode 100644 index 000000000..69889f887 --- /dev/null +++ b/doc/source/changes/version_0_2_3.rst.inc @@ -0,0 +1,10 @@ +New features +------------ + +* positional slicing via "x." syntax (x.axis.i[:5]) + +Fixes +----- + +* view(array) is usable when doing `from larray import *` +* fixed a nasty bug for doing "group" aggregates when there is only one dimension diff --git a/doc/source/changes/version_0_2_4.rst.inc b/doc/source/changes/version_0_2_4.rst.inc new file mode 100644 index 000000000..b7145c37e --- /dev/null +++ b/doc/source/changes/version_0_2_4.rst.inc @@ -0,0 +1,10 @@ +New features +------------ + +* includes an experimental (slightly inefficient) version of guess axis, so that one can write: + + >>> arr[10:20] + + instead of + + >>> arr[age[10:20]] diff --git a/doc/source/changes/version_0_2_5.rst.inc b/doc/source/changes/version_0_2_5.rst.inc new file mode 100644 index 000000000..fea2245e5 --- /dev/null +++ b/doc/source/changes/version_0_2_5.rst.inc @@ -0,0 +1,10 @@ +Miscellaneous improvements +-------------------------- + +* many methods got (improved) docstrings (Thanks to Johan). + + +Fixes +----- + +* fixed mixing keys without axis (e.g. arr[10:15]) with key with axes (e.g. arr[x.age[10:15]]). diff --git a/doc/source/changes/version_0_2_6.rst.inc b/doc/source/changes/version_0_2_6.rst.inc new file mode 100644 index 000000000..eea2c0b5b --- /dev/null +++ b/doc/source/changes/version_0_2_6.rst.inc @@ -0,0 +1,5 @@ +Fixes +----- + +* fixed LArray.cumsum and cumprod. +* fixed all doctests just enough so that they run. diff --git a/doc/source/changes/version_0_3.rst.inc b/doc/source/changes/version_0_3.rst.inc new file mode 100644 index 000000000..2a16ac402 --- /dev/null +++ b/doc/source/changes/version_0_3.rst.inc @@ -0,0 +1,38 @@ +New features +------------ + +* implemented LArray.with_total(): appends axes or group aggregates to the array. + + Without argument, it adds totals on all axes. It has optional keyword only arguments: + + * *label*: specify the label ("total" by default) + * *op*: specify the aggregate function (sum by default, all other aggregates should work too) + + With multiple arguments, it adds totals sequentially. There are some tricky cases. For example when, for the same + axis, you add group aggregates and axis aggregates: + + >>> # works but "wrong" for x.geo (double what is expected because the total also + >>> # includes fla wal & bru) + >>> la.with_total(x.sex, (fla, wal, bru), x.geo, x.lipro) + + >>> # correct total but the order is not very nice + >>> la.with_total(x.sex, x.geo, (fla, wal, bru), x.lipro) + + >>> # the correct way to do it, but it is probably not entirely obvious + >>> la.with_total(x.sex, (fla, wal, bru, x.geo.all()), x.lipro) + + >>> # we probably want to display a warning (or even an error?) in that case. + >>> # If the user really wants that behavior, he can split the operation: + >>> # .with_total((fla, wal, bru)).with_total(x.geo) + +* implemented group aggregates without using keyword arguments. As a consequence of this, one can no longer use axis + numbers in aggregates. Eg. `a.sum(0)` does not sum on the first axis anymore (but you can do `a.sum(a.axes[0])` if + needed) + +* implemented LArray.percent: equivalent to ratio * 100 + +* implemented Session.filter -> returns a new Session with only objects matching the filter + +* implemented Session.dump -> dumps all LArray in the Session to a file + +* implemented Session.load -> load several LArrays from a file to a Session diff --git a/doc/source/changes/version_0_4.rst.inc b/doc/source/changes/version_0_4.rst.inc new file mode 100644 index 000000000..55f8a7c27 --- /dev/null +++ b/doc/source/changes/version_0_4.rst.inc @@ -0,0 +1,20 @@ +New features +------------ + +* implemented LArray.expand to add dimensions +* implemented prepend +* implemented sort_axis +* allow creating 0d (scalar) LArrays + +Miscellaneous improvements +-------------------------- + +* made extend expand its arguments +* made .append expand its value before appending +* changed read_* to not sort data by default +* more minor stuff :) + +Fixes +----- + +* fixed loading 1d arrays diff --git a/doc/source/changes/version_0_5.rst.inc b/doc/source/changes/version_0_5.rst.inc new file mode 100644 index 000000000..b45ab3c6c --- /dev/null +++ b/doc/source/changes/version_0_5.rst.inc @@ -0,0 +1,52 @@ +New features +------------ + +* experimental support for indexing an LArray by another (integer) LArray + + >>> array[other_array] + +* experimental support for LArray.drop_labels and the concept of wildcard axes + +* added LArray.display_name and AxisCollection.display_names which add '*' next to wildcard axes + +* implemented where(cond, array1, array2) + +* implemented LArray.__iter__ so that this works: + + >>> for value in array: + ... + +* implement keepaxes=label or keepaxes=True for aggregate functions on full axes + + array.sum(x.age, keepaxes='total') + +* AxisCollection.replace can replace several axes in one call + +* implemented .expand(out=) to expand into an existing array + + +Miscellaneous improvements +-------------------------- + +* removed Axis.sorted() + +* removed LArray.axes_names & axes_labels. One should use .axes.names & .axes.labels instead. + +* raise an error when trying to convert an array with more than one value to a Boolean. For example, this will fail: + + >>> arr = ndrange([sex]) + >>> if arr: + ... + +* convert value to self.dtype in append/prepend + +* faster .extend, .append, .prepend and .expand + +* some code cleanup, better tests, … + + +Fixes +----- + +* fixed .extend when other has longer axes than self + diff --git a/doc/source/changes/version_0_6.rst.inc b/doc/source/changes/version_0_6.rst.inc new file mode 100644 index 000000000..70d1ede9e --- /dev/null +++ b/doc/source/changes/version_0_6.rst.inc @@ -0,0 +1,58 @@ +New features +------------ + +* a[bool_array_key] broadcasts missing/differently ordered dimensions and returns an LArray with combined axes + +* a[bool_array_key] = value broadcasts missing/differently ordered dimensions on both key and value + +* implemented argmin, argmax, argsort, posargmin, posargmax, posargsort. + they do indirect operation along an axis. E.g. argmin gives the label of the minimum value, argsort gives the labels + which would sort the array along that dimension. + posargXXX gives the position/indexes instead of the labels. + +* implemented Axis.__iter__ so that one can write: + + >>> for label in an_array.axes.an_axis: + ... + + instead of + + >>> for label in an_array.axes.an_axis.labels: + ... + +* implemented the .info property on AxisCollection + +* implement all/any top level functions, so that you can use them in with_total. + + +Miscellaneous improvements +-------------------------- + +* renamed ValueGroup to LabelGroup. We might want to rename it to LGroup to be consistent with LArray? + +* allow a single int as argument to LArray creation functions (ndrange et al.) + + e.g. `ndrange(10)` is now allowed instead of `ndrange([10])` + +* use display_name in .info (ie add * next to wildcard axes in .info). + +* allow specifying a custom window title in view() + +* viewer displays booleans as True/False instead of 1/0 + +* slightly better support for axes with no name (None). There is still a long way to go for full support though. + +* improved a few docstrings + +* nicer errors when tests results are different from expected + +* removed debug prints from viewer + +* misc cleanups + +Fixes +----- + +* fixed view() on all-negative arrays + +* fixed view() on string arrays diff --git a/doc/source/changes/version_0_6_1.rst.inc b/doc/source/changes/version_0_6_1.rst.inc new file mode 100644 index 000000000..495141132 --- /dev/null +++ b/doc/source/changes/version_0_6_1.rst.inc @@ -0,0 +1,39 @@ +New features +------------ + +* added dtype argument to all array creation functions to override default data type + +* aggregates can take an explicit "axis" keyword argument which can be used to target an axis by index + + >>> arr.sum(axis=0) + +* implemented LGroup.__getitem__ & LGroup.__iter__, so that for list-based groups (ie not slices) you can write: + + >>> for v in my_group: + ... # some code + + or + + >>> my_group[0] + + +Miscellaneous improvements +-------------------------- + +* renamed LabelGroup to LGroup and PositionalKey to PGroup. We might want to rename the later to IGroup (to be + consistent with axis.i[...]). + +* slightly better support for axes without name +* better docstrings for a few functions +* misc cleanup + + +Fixes +----- + +* fixed XXX_like(a) functions to use the same dtype than a instead of always float +* fixed to_XXX with 1d arrays (e.g. to_clipboard()) +* fixed all() and any() toplevel functions without argument +* fixed LArray without axes in some cases +* fixed array creation functions with only shapes on python2 + diff --git a/doc/source/changes/version_0_7.rst.inc b/doc/source/changes/version_0_7.rst.inc new file mode 100644 index 000000000..e83de3758 --- /dev/null +++ b/doc/source/changes/version_0_7.rst.inc @@ -0,0 +1,64 @@ +Viewer +------ + +* implemented view() on Session objects +* added axes length in window title and add axes info even if title is provided manually (concatenate both) +* ndecimals are recomputed when toggling the scientific checkbox +* allow viewing (some) non-ndarray stuff (e.g. python lists) +* refactored viewer code so that the filter drop downs can be reused too +* Known regression: the viewer is slow on large arrays (this will be fixed in a later release, obviously) + + +Session +------- + +* implemented local_arrays() to return all LArray in locals() as a Session +* implemented Session.__getitem__(int_position) +* implement Session(filename) to directly load all arrays from a file. Equivalent to: + + >>> s = Session() + >>> s.load(filename) + +* implemented Session.__eq__, so that you can compare two sessions and see if all arrays are equal. + Suppose you want to refactor your code and make sure you get the same results. + + >>> # put results in a Session + >>> res = Session({'array1': array1, 'array2': array2}) + >>> # before refactoring + >>> res.dump('results.h5') + >>> # after refactoring + >>> assert Session('results.h5') == res + +* you can load all sheets/arrays of a file (if you do not specify which ones you want, it takes all) +* loading several sheets from an excel file is now MUCH faster because the same file is kept open (apparently xlrd + parses the whole file each time we open it). +* you can specify a subset of arrays to dump +* implemented rudimentary session I/O for .csv files, usage is a bit different from .h5 & excel files + + >>> # need to specify format manually + >>> s.dump('directory_name', fmt='csv') + >>> # need to specify format manually + >>> s = Session() + >>> s.load('directory_name', fmt='csv') + +* pass `*args` and `**kwargs` to lower level functions in Session.load +* fail when trying to read an inexistant H5 file through Session, instead of creating it + + +Other new features +------------------ + +* added start argument in ndrange to specify starting value +* implemented Axis._rename. Not sure it's a good idea though… +* implemented identity function which takes an Axis and returns an LArray with the axis labels as values +* implemented size property on AxisCollection +* allow a single int in AxisCollection.without + +Fixes +----- + +* fixed broadcast_with when other_axes contains 0-len axes +* fixed a[bool_array] = value when the first axis of a is not in bool_array +* fixed view() on arrays with unnamed axes +* fixed view() on arrays of Python objects +* various other small bugs fixed diff --git a/doc/source/changes/version_0_7_1.rst.inc b/doc/source/changes/version_0_7_1.rst.inc new file mode 100644 index 000000000..91e40a9b6 --- /dev/null +++ b/doc/source/changes/version_0_7_1.rst.inc @@ -0,0 +1,39 @@ +Viewer +------ + +* implemented paste (ctrl-V) + +* implemented experimental array comparator: + + >>> compare(array1, array2) + + Known limitation: the arrays must have exactly the same axes and the background color is buggy when using filters + +* when no title is specified in view(), it is determined automatically by inspecting the local variables of the function + where view() is called and using the names of the ones matching the object passed. If several matches, up to 3 are + displayed. + +* added axes names to copy (ctrl-C) + +* fixed copy (ctrl-C) of 0d array + +Input/Output +------------ + +* added 'dialect' argument to to_csv. For example, dialect='classic' does not include the last (horizontal) axis name. + +* fixed loading .csv files without \ (ie 'classic' .csv files), though one needs to specify nb_index in that case if + ndim > 2 + +* strip spaces around axes names so that you can use "axis0\axis1" instead of "axis0\axis1" in .csv files + +* fixed 1d arrays I/O + +* more precise parsing of input headers: 1 and 0 come out as int, not bool + +Misc +---- + +* nicer error message when using an invalid axes names + +* changed LArray .df property to a to_frame() method so that we can pass options to it diff --git a/doc/source/changes/version_0_8.rst.inc b/doc/source/changes/version_0_8.rst.inc new file mode 100644 index 000000000..9c5fb2d1c --- /dev/null +++ b/doc/source/changes/version_0_8.rst.inc @@ -0,0 +1,35 @@ +Core +---- + +* implemented skipna argument for most aggregate functions. defaults to True. +* implemented LArray.sort_values(key) +* implemented percentile and median +* added isnan and isinf toplevel functions +* made axis argument optional for argsort & posargsort on 1D arrays + +* fixed a[key] = value when key corresponds to a single cell of the array +* fixed keepaxes argument for aggregate functions +* fixed a[int_array] (when the axis needs to be guessed) +* fixed empty_like +* fixed aggregates on several axes given as integers e.g. arr.sum(axis=(0, 2)) +* fixed "kind" argument in posargsort + +Viewer +------ + +* added title argument to edit() (set automatically if not provided, like for view()) +* fixed edit() on filtered arrays +* fixed view(expression). + anything which was not stored in a variable was broken in 0.7.1 +* reset background color when setting values if necessary (still buggy in some cases, but much less so ;-)) +* background color for headers is always on +* view() => array cells are not editable, instead of being editable and ignoring entered values +* fixed compare() colors when arrays are entirely equal +* fixed error message for compare() when PyQt is not available + +Misc +---- + +* bump numpy requirement to 1.10, implicitly dropping support for python 3.3 +* renamed view module to editor to not collide with view function +* improved/added a few tests diff --git a/doc/source/changes/version_0_8_1.rst.inc b/doc/source/changes/version_0_8_1.rst.inc new file mode 100644 index 000000000..2f98c4169 --- /dev/null +++ b/doc/source/changes/version_0_8_1.rst.inc @@ -0,0 +1,25 @@ +Viewer +------ + +* implemented min/maxvalue arguments for edit() +* do not close the window when pressing Enter +* allow to start editing cells by pressing Enter +* fixed copy of changed cells (copy the changed value) +* fixed pasted values to not be accepted directly (they go to "changes" like for manual edits) +* fixed color updates on paste +* disabled experimental tooltips on headers +* better error message when entering invalid values + +Core +---- + +* implemented indexing by position on several dimensions at once (like numpy) + + >>> # takes the first item in the first and third dimensions, leave the second dimension intact + >>> arr.i[0, :, 0] + + >>> # sets all the cells corresponding to the first item in the first dimension and the second item in the fourth + >>> # dimension + >>> arr.i[0, :, :, 1] = 42 + +* added optional 'readonly' argument to expand() to produce a readonly view (much faster since no copying is done) diff --git a/doc/source/changes/version_0_9.rst.inc b/doc/source/changes/version_0_9.rst.inc new file mode 100644 index 000000000..fb89833e2 --- /dev/null +++ b/doc/source/changes/version_0_9.rst.inc @@ -0,0 +1,22 @@ +A minor but backward incompatible version (hence the bump in version number)! + +Core +---- + +* fixed int_array.mean() to return floats instead of int (regression in 0.8) +* larray_equal returns False when either value is not an LArray, instead of raising an exception + +Session +------- + +* changed `Session == Session` to return an array of booleans instead of a single boolean, so that we know which + array(s) differ. Code like `session1 == session2`, should be changed to `all(session1 == session2)`. +* implemented Session != Session +* implemented Session.get(k, default) (returns default if k does not exist in Session) +* implemented len() for Session objects to know how many objects are in the Session + +Viewer +------ + +* fixed view() (regression in 0.8.1) +* fixed edit() to actually apply changes on "OK"/accept_changes even when no filter change occurred after the last edit. diff --git a/doc/source/changes/version_0_9_1.rst.inc b/doc/source/changes/version_0_9_1.rst.inc new file mode 100644 index 000000000..4927ff3a1 --- /dev/null +++ b/doc/source/changes/version_0_9_1.rst.inc @@ -0,0 +1,31 @@ +Core +---- + +* better .info for arrays with groups in axes + + >>> # example using groups without a name + >>> reg = la.sum((fla, wal, bru, belgium)) + >>> reg.info + 4 x 15 + geo [4]: ['A11' ... 'A73'] ['A25' ... 'A93'] 'A21' ['A11' ... 'A21'] + lipro [15]: 'P01' 'P02' 'P03' ... 'P13' 'P14' 'P15' + + >>> # example using groups with a name + >>> fla = geo.group(fla_str, name='Flanders') + >>> wal = geo.group(wal_str, name='Wallonia') + >>> bru = geo.group(bru_str, name='Brussels') + >>> reg = la.sum((fla, wal, bru)) + >>> reg.info + 3 x 15 + geo [3]: 'Flanders' (['A11' ... 'A73']) 'Wallonia' (['A25' ... 'A93']) 'Brussels' ('A21') + lipro [15]: 'P01' 'P02' 'P03' ... 'P13' 'P14' 'P15' + + +Editor +------ + +* fixed edit() with non-string labels in axes +* fixed edit() with filters in some more cases +* fixed ArrayEditorWidget.reject_changes and accept_changes to update the model & view accordingly (in case the widget + is kept open) +* avoid (harmless) error messages in some cases diff --git a/doc/source/changes/version_0_9_2.rst.inc b/doc/source/changes/version_0_9_2.rst.inc new file mode 100644 index 000000000..7049a6624 --- /dev/null +++ b/doc/source/changes/version_0_9_2.rst.inc @@ -0,0 +1,9 @@ +Core +---- + +* much better support for unnamed axes overall. Still a long way to go for full support, but it's getting there… + +Editor +------ + +* fixed edit() for arrays with the same labels on several axes diff --git a/doc/source/conf.py b/doc/source/conf.py index 3f8a5269b..7535bc0cb 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -12,6 +12,7 @@ # # All configuration values have a default; values that are commented out # serve to show the default. +from __future__ import print_function import sys import os @@ -21,6 +22,9 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) +import larray +print("larray: {}, {}".format(larray.__version__, larray.__file__)) + # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. @@ -36,17 +40,56 @@ 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode', 'sphinx.ext.extlinks', - 'numpydoc' + 'numpydoc', + 'nbsphinx', + 'sphinx.ext.mathjax', + 'IPython.sphinxext.ipython_directive', + 'IPython.sphinxext.ipython_console_highlighting' ] -extlinks = {'issue': ('https://github.com/liam2/larray/issues/%s', - 'issue ')} +extlinks = { + 'issue': ('https://github.com/larray-project/larray/issues/%s', 'issue '), + 'editor_issue': ('https://github.com/larray-project/larray-editor/issues/%s', 'issue ') +} + +# scan all found documents for autosummary directives, and to generate stub pages for each. +# The new files will be placed in the directories specified in the :toctree: options of the directives. +autosummary_generate = True +numpydoc_class_members_toctree = True # avoid pulling in base class (ndarray) methods numpydoc_show_class_members = False # ============================================================== +# There are three possible settings, "always", "auto" and "never". +# By default (= "auto"), notebooks with no outputs are executed and notebooks with +# at least one output are not. +# nbsphinx_execute = 'auto' + +# Normally, if an exception is raised while executing a notebook, +# the Sphinx build process is stopped immediately. +# However, it is possible to allow errors in all notebooks using option bellow +nbsphinx_allow_errors = True + +# This is processed by Jinja2 and inserted before each notebook +nbsphinx_prolog = r""" +{% set docname = env.doc2path(env.docname, base='doc/source/') %} + +.. only:: html + + .. role:: raw-html(raw) + :format: html + + .. nbinfo:: + Interactive online version: + :raw-html:`Binder badge` +""" + +# ============================================================== + # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -61,16 +104,16 @@ # General information about the project. project = 'LArray' -copyright = '2014-2016, Gaëtan de Menten, Geert Bryon, Johan Duyck' +copyright = '2014-2017, Gaëtan de Menten, Geert Bryon, Johan Duyck, Alix Damman' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '0.12' +version = larray.__version__ # The full version, including alpha/beta/rc tags. -release = '0.12' +release = larray.__version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -84,7 +127,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = [] +exclude_patterns = ['_build', '**.ipynb_checkpoints'] # The reST default role (used for this markup: `text`) to use for all # documents. @@ -110,12 +153,13 @@ # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False +# highlight_language = "python3" # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -214,7 +258,7 @@ # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'larray.tex', 'LArray Documentation', - 'Gaëtan de Menten, Geert Bryon, Johan Duyck', 'manual'), + 'Gaëtan de Menten, Geert Bryon, Johan Duyck, Alix Damman', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -244,7 +288,7 @@ # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'larray', 'LArray Documentation', - ['Gaëtan de Menten, Geert Bryon, Johan Duyck'], 1) + ['Gaëtan de Menten, Geert Bryon, Johan Duyck, Alix Damman'], 1) ] # If true, show URL addresses after external links. @@ -260,7 +304,7 @@ ('index', 'LArray', 'LArray Documentation', - 'Gaëtan de Menten, Geert Bryon, Johan Duyck', + 'Gaëtan de Menten, Geert Bryon, Johan Duyck, Alix Damman', 'LArray', 'One line description of project.', 'Miscellaneous'), @@ -280,4 +324,4 @@ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/': None} +intersphinx_mapping = {'https://docs.python.org/3': None} diff --git a/doc/source/contribute.rst b/doc/source/contribute.rst index f8ebd7797..d68868850 100644 --- a/doc/source/contribute.rst +++ b/doc/source/contribute.rst @@ -6,17 +6,14 @@ Getting the code (for the first time) - install a Git client - On Windows, TortoiseGit provides a nice graphical wrapper. You need to - install both the console client from http://msysgit.github.io/ and - `TortoiseGit `_ - itself. + On Windows, TortoiseGit provides a nice graphical wrapper. You need to install both the console client from + http://msysgit.github.io/ and `TortoiseGit `_ itself. -- create an account on `GitHub `_ (not necessary for - readonly). +- create an account on `GitHub `_ (not necessary for readonly). - clone the repository on your local machine :: - > git clone https://github.com/liam2/larray.git + > git clone https://github.com/larray-project/larray.git Installing the module @@ -26,14 +23,13 @@ You could install LArray in the standard way: :: > python setup.py install -but in that case you need to "install" it again every time you change it. When -developing, it is usually more convenient to use: :: +but in that case you need to "install" it again every time you change it. When developing, it is usually more +convenient to use: :: > python setup.py develop -This creates some kind of symlink between your python installation "modules" -directory and your repository, so that any change in your local copy is -automatically usable by other modules. +This creates some kind of symlink between your python installation "modules" directory and your repository, so that any +change in your local copy is automatically usable by other modules. Updating your local copy with remote changes @@ -47,13 +43,11 @@ Updating your local copy with remote changes Code conventions ---------------- -`PEP8 `_ is your friend. Among others, -this means: +`PEP8 `_ is your friend. Among others, this means: -- 80 characters lines +- 120 characters lines - 4 spaces indentation -- lowercase (with underscores if needed) variables, functions, methods and - modules names +- lowercase (with underscores if needed) variables, functions, methods and modules names - CamelCase classes names - all uppercase constants names - whitespace around binary operators @@ -83,8 +77,8 @@ We use Numpy conventions for docstrings. Here is a template: :: Description of arg2. * value1 -- description of value1 (default2) - * value1 -- description of value2 - * value1 -- description of value3 + * value2 -- description of value2 + * value3 -- description of value3 arg3 : type3 or type3bis, optional Description of arg3. Default is default3. @@ -92,9 +86,13 @@ We use Numpy conventions for docstrings. Here is a template: :: Returns ------- - name : type + type Description of return value. + Notes + ----- + Some interesting facts about this function. + See Also -------- LArray.otherfunc : How other function or method is related. @@ -119,9 +117,8 @@ For example: :: Returns ------- - result : bool - Whether the string representation of the number is equal to the - string. + bool + Whether the string representation of the number is equal to the string. Examples -------- @@ -138,21 +135,18 @@ For example: :: Documentation ------------- -The documentation is written using reStructuredText and built to various -formats using `Sphinx `_. See the `reStructuredText -Primer `_ for a first introduction -of the syntax. +The documentation is written using reStructuredText and built to various formats using +`Sphinx `_. See the `reStructuredText Primer `_ +for a first introduction of the syntax. Installing Requirements ~~~~~~~~~~~~~~~~~~~~~~~ -Basic requirements (to generate an .html version of the documentation) can be -installed using: :: +Basic requirements (to generate an .html version of the documentation) can be installed using: :: > conda install sphinx numpydoc -To build the .pdf version, you need a LaTeX processor. We use -`MiKTeX `_. +To build the .pdf version, you need a LaTeX processor. We use `MiKTeX `_. To build the .chm version, you need `HTML Help Workshop `_. @@ -165,9 +159,8 @@ Open a command prompt and go to the documentation directory: :: > cd doc -If you just want to check that there is no syntax error in the documentation -and that it formats properly, it is usually enough to only generate the .html -version, by using: :: +If you just want to check that there is no syntax error in the documentation and that it formats properly, it is +usually enough to only generate the .html version, by using: :: > make html @@ -175,8 +168,8 @@ Open the result in your favourite web browser. It is located in: :: build/html/index.html -If you want to also generate the .pdf and .chm (and you have the extra -requirements to generate those), you could use: :: +If you want to also generate the .pdf and .chm (and you have the extra requirements to generate those), you could +use: :: > buildall @@ -184,8 +177,8 @@ requirements to generate those), you could use: :: Tests ----- -We use both unit tests and doctests. Unit tests are written using Python's -built-in `unittest module `_. +We use both unit tests and doctests. Unit tests are written using Python's built-in +`unittest module `_. For example: :: from unittest import TestCase @@ -198,19 +191,17 @@ For example: :: pass def test_split(self): - self.assertEqual(to_ticks('H,F'), ['H', 'F']) - self.assertEqual(to_ticks('H, F'), ['H', 'F']) + self.assertEqual(to_ticks('M,F'), ['M', 'F']) + self.assertEqual(to_ticks('M, F'), ['M', 'F']) To run all unit tests: :: > python -m unittest -v larray\tests\test_la.py -We also use doctests for some tests. Doctests is specially-formatted code -within the docstring of a function which embeds the result of calling said -function with a particular set of arguments. This can be used both as -documentation and testing. We only use doctests for the cases where the test is -simple enough to fit on one line and it can help understand what the function -does. For example: :: +We also use doctests for some tests. Doctests is specially-formatted code within the docstring of a function which +embeds the result of calling said function with a particular set of arguments. This can be used both as documentation +and testing. We only use doctests for the cases where the test is simple enough to fit on one line and it can help +understand what the function does. For example: :: def slice_to_str(key): """Converts a slice to a string @@ -225,8 +216,7 @@ To run doc tests: :: > python -m doctest -v larray\larray.py -To run both at the same time, one can use nosetests (install with `conda -install nose`): :: +To run both at the same time, one can use nosetests (install with `conda install nose`): :: > nosetests -v --with-doctest @@ -236,11 +226,9 @@ Sending your changes :: - > git add # tell git it should care about a file it previously - # ignored (only if needed) + > git add # tell git it should care about a file it previously ignored (only if needed) - > git commit # creates a new revision of the repository using its - # current state + > git commit # creates a new revision of the repository using its current state > git pull # updates your local repository with "upstream" changes. # this might create conflicts that you will need to resolve. diff --git a/doc/source/getting_started.rst b/doc/source/getting_started.rst new file mode 100644 index 000000000..8d4390b57 --- /dev/null +++ b/doc/source/getting_started.rst @@ -0,0 +1,371 @@ +.. currentmodule:: larray + +.. _start_getting_started: + +Getting Started +=============== + +To use the LArray library, the first thing to do is to import it + +.. ipython:: python + + from larray import * + +Create an array +--------------- + +Working with the LArray library mainly consists of manipulating :ref:`LArray ` data structures. +They represent N-dimensional labelled arrays and are composed of data (numpy ndarray), :ref:`axes ` +and optionally a title. An axis contains a list of labels and may have a name (if not given, the axis is anonymous). + +You can create an array from scratch by supplying data, axes and optionally a title: + +.. ipython:: python + + # define data + data = [[20, 22], + [33, 31], + [79, 81], + [28, 34]] + + # define axes + age_category = Axis(["0-9", "10-17", "18-66", "67+"], "age_category") + sex = Axis(["M", "F"], "sex") + + # create LArray object + arr = LArray(data, [age_category, sex], "population by age category and sex") + arr + +.. note:: + + LArray offers two syntaxes to build axes and make selections and aggregations. + The first one is more Pythonic (uses Python structures) and allows to use any + character in labels. The second one consists of using strings that are parsed. + It is shorter to type. For example, you could create the *age_category* axis + above as follows:: + + age_category = Axis("age_category=0-9,10-17,18-66,67+") + + The drawback of the string syntax is that some characters such as `, ; = : .. [ ] >>` + have a special meaning and cannot be used in labels. + Strings containing only integers are interpreted as such. + + In this getting started section we will use the first, more verbose, syntax which + works in all cases and provide the equivalent using the shorter syntax in comments. + More examples can be found in the :ref:`tutorial ` and the + :ref:`API reference ` section. + +Here are the key properties for an array: + +.. ipython:: python + + # array summary : dimensions + description of axes + arr.info + + # number of dimensions + arr.ndim + + # array dimensions + arr.shape + + # number of elements + arr.size + + # size in memory + arr.memory_used + + # type of the data of the array + arr.dtype + +Arrays can be generated through dedicated functions: + +* :py:func:`zeros` : fills an array with 0 +* :py:func:`ones` : fills an array with 1 +* :py:func:`full` : fills an array with a given +* :py:func:`eye` : identity matrix +* :py:func:`ndtest` : creates a test array with increasing numbers as data +* :py:func:`sequence` : creates an array by sequentially applying modifications to the array along axis. + +.. ipython:: python + + zeros([age_category, sex]) + + ndtest((3, 3)) + +Save/Load an array +------------------ + +The LArray library offers many I/O functions to read and write arrays in various formats +(CSV, Excel, HDF5, pickle). For example, to save an array in a CSV file, call the method +:py:meth:`~LArray.to_csv`: + +.. ipython:: python + + arr_3D = ndtest((2, 2, 2)) + arr_3D + + arr_3D.to_csv('arr_3D.csv') + +Content of 'arr_3D.csv' file is :: + + a,b\c,c0,c1 + a0,b0,0,1 + a0,b1,2,3 + a1,b0,4,5 + a1,b1,6,7 + +.. note:: + In CSV or Excel files, the last dimension is horizontal and the names of the + two last dimensions are separated by a \\. + +To load a saved array, call the function :py:meth:`read_csv`: + +.. ipython:: python + + arr_3D = read_csv('arr_3D.csv') + arr_3D + +Other input/output functions are described in the :ref:`corresponding section ` +of the API documentation. + +Indexing +-------- + +To select an element or a subset of an array, use brackets [ ]. +Let’s start by selecting a single element: + +.. ipython:: python + + arr = ndtest((4, 4)) + arr + + arr['a0', 'b1'] + + # labels can be given in arbitrary order + arr['b1', 'a0'] + +Let's continue with subsets: + +.. ipython:: python + + # select subset along one axis + arr['a0'] + + arr['b0'] + + # labels associated with the same axis must be given as a list + # equivalent to: arr['a0', 'b1,b3'] + arr['a0', ['b1', 'b3']] + +.. warning:: + + Selecting by labels as above only works as long as there is no ambiguity. + When several axes have common labels and you do not specify explicitly + on which axis to work, it fails with an error + (ValueError: ... is ambiguous (valid in a, b)). + Specifying the axis can be done using the special notation ``X.axis_name``. + The axis name must not contain whitespaces and special characters. + +.. ipython:: python + + # equivalent to: arr2 = ndtest("a=label0,label1;b=label1,label2") + arr2 = ndtest([Axis(["label0", "label1"], "a"), Axis(["label1", "label2"], "b")]) + arr2 + + # equivalent to: arr2["label0", "b[label1]"] + arr2["label0", X.b["label1"]] + +You can also define slices (defined by 'start:stop' or 'start:stop:step'). +A slice will select all labels between `start` and `stop` (stop included). +All arguments of a slice are optional. +When not given, start is the first label of an axis, stop the last one. + +.. ipython:: python + + # "b1":"b3" is a shortcut for ["b1", "b2", "b3"] + # equivalent to: arr["a0,a2", "b1:b3"] + arr[["a0", "a2"], "b1":"b3"] + + # :"a2" will select all labels between the first one and "a2" + # "b1": will select all labels between "b1" and the last one + # equivalent to: arr[":a2", "b1:"] + arr[:"a2", "b1":] + +Aggregation +----------- + +The LArray library includes many aggregations methods. +For example, to calculate the sum along an axis, write: + +.. ipython:: python + + arr_3D + + # equivalent to: arr_3D.sum("a") + arr_3D.sum(X.a) + +To aggregate along all axes except one, you simply have to append `_by` +to the aggregation method you want to use: + +.. ipython:: python + + # equivalent to: arr_3D.sum_by("a") + arr_3D.sum_by(X.a) + +See :ref:`here ` to get the list of all available aggregation methods. + +Groups +------ + +A :ref:`Group ` represents a subset of labels or positions of an axis: + +.. ipython:: python + + arr + + even = X.a["a0", "a2"] + even + + odd = X.a["a1", "a3"] + odd + +They can be used in selections: + +.. ipython:: python + + arr[even] + + arr[odd] + +or aggregations: + +.. ipython:: python + + arr.sum((even, odd)) + +In the case of aggregations, it is often useful to attach them a name +using the ``>>`` operator: + +.. ipython:: python + + # equivalent to: arr.sum("a0,a2 >> even; a1,a3 >> odd") + arr.sum((even >> "even", odd >> "odd")) + +Group arrays in Session +----------------------- + +Arrays may be grouped in :ref:`Session ` objects. +A session is an ordered dict-like container of LArray objects with special I/O methods. +To create a session, you need to pass a list of pairs (array_name, array): + +.. ipython:: python + + arr0 = ndtest((3, 3)) + arr1 = ndtest((2, 4)) + arr2 = ndtest((4, 2)) + + arrays = [("arr0", arr0), ("arr1", arr1), ("arr2", arr2)] + ses = Session(arrays) + + # displays names of arrays contained in the session + ses.names + # get an array + ses["arr0"] + # add/modify an array + ses["arr3"] = ndtest((2, 2, 2)) + +.. warning:: + + You can also pass a dictionary to the Session's constructor but since elements of a dict object are + not ordered by default, you may lose the order. If you are using python 3.6 or later, using keyword + arguments is a nice alternative which keeps ordering. For example, the session above can be defined + using: `ses = Session(arr0=arr0, arr1=arr1, arr2=arr2)`. + +One of the main interests of using sessions is to save and load many arrays at once: + +.. ipython:: python + + ses.save("my_session.h5") + ses = Session("my_session.h5") + +Graphical User Interface +------------------------ + +The LArray project provides an optional package called :ref:`larray-editor ` +allowing users to explore and edit arrays using a graphical interface. +This package is automatically installed with **larrayenv**. + +To explore the content of arrays in read-only mode, import ``larray-editor`` and call :py:func:`view` + +.. ipython:: python + :verbatim: + + from larray_editor import * + + # shows the arrays of a given session in a graphical user interface + view(ses) + + # the session may be directly loaded from a file + view("my_session.h5") + + # creates a session with all existing arrays from the current namespace + # and shows its content + view() + +To open the user interface in edit mode, call :py:func:`edit` instead. + +.. image:: _static/editor.png + :align: center + +Once open, you can save and load any session using the `File` menu. + +Finally, you can also visually compare two arrays or sessions using the :py:func:`compare` function. + +.. ipython:: python + :verbatim: + + arr0 = ndtest((3, 3)) + arr1 = ndtest((3, 3)) + arr1[["a1", "a2"]] = -arr1[["a1", "a2"]] + compare(arr0, arr1) + +.. image:: _static/compare.png + :align: center + +In case of two arrays, they must have compatible axes. + +For Windows Users +^^^^^^^^^^^^^^^^^ + +Installing the ``larray-editor`` package on Windows will create a ``LArray`` menu in the +Windows Start Menu. This menu contains: + + * a shortcut to open the documentation of the last stable version of the library + * a shortcut to open the graphical interface in edit mode. + * a shortcut to update `larrayenv`. + +.. image:: _static/menu_windows.png + :align: center + +.. image:: _static/editor_new.png + :align: center + +Once the graphical interface is open, all LArray objects and functions are directly accessible. +No need to start by `from larray import *`. + +Compatibility with pandas +------------------------- + +To convert a LArray object into a pandas DataFrame, the method :py:meth:`~LArray.to_frame` can be used: + +.. ipython:: python + + df = arr.to_frame() + df + +Inversely, to convert a DataFrame into a LArray object, use the function :py:func:`aslarray`: + +.. ipython:: python + + arr = aslarray(df) + arr \ No newline at end of file diff --git a/doc/source/index.rst b/doc/source/index.rst index 5ce760152..6c341486a 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1,12 +1,43 @@ -Welcome to LArray's documentation! -================================== +.. image:: _static/larray-logo.png + :align: center -Contents: +| + +N-dimensional labelled arrays +============================= + +.. include:: ../../README.rst + :start-after: start-intro: + :end-before: start-install: + +.. image:: _static/editor.png + :align: center + +.. include:: ../../README.rst + :start-after: start-documentation: + :end-before: end-readme-file + +.. raw:: html + +

+ You can subscribe to the announce mailing list by entering your email address here + (if you are connected to your Google account but you want to subscribe using another address, + please log out first): +

+
+ + +
+ +Contents +======== .. toctree:: :maxdepth: 2 - intro + install + getting_started + tutorial api Indices and tables diff --git a/doc/source/install.rst b/doc/source/install.rst new file mode 100644 index 000000000..9dafc4837 --- /dev/null +++ b/doc/source/install.rst @@ -0,0 +1,25 @@ +.. include:: ../../README.rst + :start-after: start-install: + :end-before: start-documentation: + +.. _start-update: + +Update +------ + +If larray has been installed using conda, update is done via :: + + conda update larray + +Be careful if you have installed optional dependencies. +In that case, you may have to update some of them. + +If larray has been installed using conda via larrayenv, you simply must do :: + + conda update larrayenv + +For Windows users who have larrayenv (>= 0.25) installed, simply click on the +``Update LArray`` link in the the Windows Start Menu > LArray. + +.. image:: _static/menu_windows.png + :align: center diff --git a/doc/source/intro.rst b/doc/source/intro.rst deleted file mode 100644 index 769d948d4..000000000 --- a/doc/source/intro.rst +++ /dev/null @@ -1,4 +0,0 @@ -Introduction -============ - -LArray provides a labeled array class. \ No newline at end of file diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst new file mode 100644 index 000000000..d643900a0 --- /dev/null +++ b/doc/source/tutorial.rst @@ -0,0 +1,18 @@ +.. currentmodule:: larray + +.. _start_tutorial: + +Tutorial +======== + +This is an overview of the LArray library. +It is not intended to be a fully comprehensive manual. +It is mainly dedicated to help new users to familiarize with it and others to remind essentials. + +If this is your first time with LArray, please read the :ref:`Getting Started ` +page first. + +.. toctree:: + :maxdepth: 2 + + ./tutorial/tutorial.ipynb diff --git a/doc/source/tutorial/tutorial.ipyml b/doc/source/tutorial/tutorial.ipyml new file mode 100644 index 000000000..7a27b0d2f --- /dev/null +++ b/doc/source/tutorial/tutorial.ipyml @@ -0,0 +1,1694 @@ +cells: + +- code: | + # @tutorial writers: You can remove cells from the HTML/LaTeX output by adding this to the cell metadata: + # "nbsphinx": "hidden" + + # ignore warnings + import warnings + warnings.filterwarnings('ignore') + + # simplify exception output + %xmode Plain + + id: 0 + metadata: + nbsphinx: hidden + +- markdown: | + To import the LArray library, run: + + +- code: | + from larray import * + + id: 1 + +- markdown: | + ## Axis creation + + An Axis represents a dimension of an LArray object. + It consists of a name and a list of labels. They are several ways to create an axis: + + +- code: | + # create a wildcard axis + age = Axis(3, 'age') + # labels given as a list + time = Axis([2007, 2008, 2009], 'time') + # create an axis using one string + sex = Axis('sex=M,F') + # labels generated using a special syntax + other = Axis('other=A01..C03') + + age, sex, time, other + + id: 2 + +- markdown: | + ## Array creation + + A LArray object represents a multidimensional array with labeled axes. + + ### From scratch + + To create an array from scratch, you need to provide the data and a list + of axes. Optionally, a title can be defined. + + +- code: | + import numpy as np + + # list of the axes + axes = [age, sex, time, other] + # data (the shape of data array must match axes lengths) + data = np.random.randint(100, size=[len(axis) for axis in axes]) + # title (optional) + title = 'random data' + + arr = LArray(data, axes, title) + arr + + id: 3 + +- markdown: | + ### Array creation functions + + Arrays can also be generated in an easier way through creation functions: + + - `ndtest` : creates a test array with increasing numbers as data + - `empty` : creates an array but leaves its allocated memory + unchanged (i.e., it contains "garbage". Be careful !) + - `zeros`: fills an array with 0 + - `ones` : fills an array with 1 + - `full` : fills an array with a given value + - `sequence` : creates an array from an axis by iteratively applying a function to a given initial value. + + Except for ndtest, a list of axes must be provided. + Axes can be passed in different ways: + + - as Axis objects + - as integers defining the lengths of auto-generated wildcard axes + - as a string : 'sex=M,F;time=2007,2008,2009' (name is optional) + - as pairs (name, labels) + + Optionally, the type of data stored by the array can be specified using argument dtype. + + +- code: | + # start defines the starting value of data + ndtest(['age=0..2', 'sex=M,F', 'time=2007..2009'], start=-1) + + id: 4 + +- code: | + # start defines the starting value of data + # label_start defines the starting index of labels + ndtest((3, 3), start=-1, label_start=2) + + id: 5 + +- code: | + # empty generates uninitialised array with correct axes + # (much faster but use with care!). + # This not really random either, it just reuses a portion + # of memory that is available, with whatever content is there. + # Use it only if performance matters and make sure all data + # will be overridden. + empty(['age=0..2', 'sex=M,F', 'time=2007..2009']) + + id: 6 + +- code: | + # example with anonymous axes + zeros(['0..2', 'M,F', '2007..2009']) + + id: 7 + +- code: | + # dtype=int forces to store int data instead of default float + ones(['age=0..2', 'sex=M,F', 'time=2007..2009'], dtype=int) + + id: 8 + +- code: | + full(['age=0..2', 'sex=M,F', 'time=2007..2009'], 1.23) + + id: 9 + +- markdown: | + All the above functions exist in *(func)_like* variants which take axes from another array + + +- code: | + ones_like(arr) + + id: 10 + +- markdown: | + ### Sequence + + +- code: | + # With initial=1.0 and inc=0.5, we generate the sequence 1.0, 1.5, 2.0, 2.5, 3.0, ... + sequence('sex=M,F', initial=1.0, inc=0.5) + + id: 11 + +- code: | + # With initial=1.0 and mult=2.0, we generate the sequence 1.0, 2.0, 4.0, 8.0, ... + sequence('age=0..2', initial=1.0, mult=2.0) + + id: 12 + +- code: | + # Using your own function + sequence('time=2007..2009', initial=2.0, func=lambda value: value**2) + + id: 13 + +- markdown: | + You can also create N-dimensional array by passing (N-1)-dimensional + array to initial, inc or mult argument + + +- code: | + birth = LArray([1.05, 1.15], 'sex=M,F') + cumulate_newborns = sequence('time=2007..2009', initial=0.0, inc=birth) + cumulate_newborns + + id: 14 + +- code: | + initial = LArray([90, 100], 'sex=M,F') + survival = LArray([0.96, 0.98], 'sex=M,F') + pop = sequence('age=80..83', initial=initial, mult=survival) + pop + + id: 15 + +- markdown: | + ## Load/Dump from files + + +- code: | + demography = load_example_data('demography') + household = demography.hh + pop = demography.pop + mortality = demography.qx + + id: 16 + metadata: + nbsphinx: hidden + +- markdown: | + ### Load from files + + Arrays can be loaded from CSV files + + ```python + # read_tsv is a shortcut when data are separated by tabs instead of commas (default separator of read_csv) + # read_eurostat is a shortcut to read EUROSTAT TSV files + household = read_csv('hh.csv') + ``` + + +- markdown: | + or Excel sheets + + ```python + # loads array from the first sheet if no sheet is given + pop = read_excel('demography.xlsx', 'pop') + ``` + + +- markdown: | + or HDF5 files (HDF5 is file format designed to store and organize large amounts of data. + An HDF5 file can contain multiple arrays. + + ```python + mortality = read_hdf('demography.h5','qx') + ``` + + +- markdown: | + See documentation of reading functions for more details + + +- markdown: | + ### Dump in files + + Arrays can be dumped in CSV files + + ```python + household.to_csv('hh2.csv') + ``` + + +- markdown: | + or in Excel files + + ```python + # if the file does not already exist, it is created with a single sheet, + # otherwise a new sheet is added to it + household.to_excel('demography_2.xlsx', overwrite_file=True) + # it is usually better to specify the sheet explicitly (by name or position) though + household.to_excel('demography_2.xlsx', 'hh') + ``` + + +- markdown: | + or in HDF5 files + + ```python + household.to_hdf('demography_2.h5', 'hh') + ``` + + +- markdown: | + See documentation of writing methods for more details + + +- markdown: | + ### more Excel IO + + +- markdown: | + #### Write Arrays + + Open an Excel file + + ```python + wb = open_excel('test.xlsx', overwrite_file=True) + ``` + + +- markdown: | + Put an array in an Excel Sheet, **excluding** headers (labels) + + ```python + # put arr at A1 in Sheet1, excluding headers (labels) + wb['Sheet1'] = arr + # same but starting at A9 + # note that Sheet1 must exist + wb['Sheet1']['A9'] = arr + ``` + + +- markdown: | + Put an array in an Excel Sheet, **including** headers (labels) + + ```python + # dump arr at A1 in Sheet2, including headers (labels) + wb['Sheet2'] = arr.dump() + # same but starting at A10 + wb['Sheet2']['A10'] = arr.dump() + ``` + + +- markdown: | + Save file to disk + + ```python + wb.save() + ``` + + +- markdown: | + Close file + + ```python + wb.close() + ``` + + +- markdown: | + #### Read Arrays + + Open an Excel file + + ```python + wb = open_excel('test.xlsx') + ``` + + +- markdown: | + Load an array from a sheet (assuming the presence of (correctly formatted) headers and only one array in sheet) + + ```python + # save one array in Sheet3 (including headers) + wb['Sheet3'] = arr.dump() + + # load array from the data starting at A1 in Sheet3 + arr = wb['Sheet3'].load() + ``` + + +- markdown: | + Load an array with its axes information from a range + + ```python + # if you need to use the same sheet several times, + # you can create a sheet variable + sheet2 = wb['Sheet2'] + + # load array contained in the 4 x 4 table defined by cells A10 and D14 + arr2 = sheet2['A10:D14'].load() + ``` + + +- markdown: | + #### Read Ranges (experimental) + + Load an array (raw data) with no axis information from a range + + ```python + arr3 = wb['Sheet1']['A1:B4'] + ``` + + +- markdown: | + in fact, this is not really an LArray ... + + ```python + type(arr3) + + larray.io.excel.Range + ``` + + +- markdown: | + ... but it can be used as such + + ```python + arr3.sum(axis=0) + ``` + + +- markdown: | + ... and it can be used for other stuff, like setting the formula instead of the value: + + ```python + arr3.formula = '=D10+1' + ``` + + +- markdown: | + In the future, we should also be able to set font name, size, style, etc. + + +- markdown: | + ## Inspecting + + +- code: | + # load population array + pop = load_example_data('demography').pop + + id: 17 + +- markdown: | + Get array summary : dimensions + description of axes + + +- code: | + pop.info + + id: 18 + +- markdown: | + Get axes + + +- code: | + time, geo, age, sex, nat = pop.axes + + id: 19 + +- markdown: | + Get array dimensions + + +- code: | + pop.shape + + id: 20 + +- markdown: | + Get number of elements + + +- code: | + pop.size + + id: 21 + +- markdown: | + Get size in memory + + +- code: | + pop.memory_used + + id: 22 + +- markdown: | + Start viewer (graphical user interface) in read-only mode. + This will open a new window and block execution of the rest of code until the windows is closed! Required PyQt installed. + + ```python + view(pop) + ``` + + +- markdown: | + Load array in an Excel sheet + + ```python + pop.to_excel() + ``` + + +- markdown: | + ## Selection (Subsets) + + LArray allows to select a subset of an array either by labels or positions + + +- markdown: | + ### Selection by Labels + + To take a subset of an array using labels, use brackets [ ]. + + Let's start by selecting a single element: + + +- code: | + # here we select the value associated with Belgian women + # of age 50 from Brussels region for the year 2015 + pop[2015, 'BruCap', 50, 'F', 'BE'] + + id: 23 + +- markdown: | + Continue with selecting a subset using slices and lists of labels + + +- code: | + # here we select the subset associated with Belgian women of age 50, 51 and 52 + # from Brussels region for the years 2010 to 2016 + pop[2010:2016, 'BruCap', 50:52, 'F', 'BE'] + + id: 24 + +- code: | + # slices bounds are optional: + # if not given start is assumed to be the first label and stop is the last one. + # Here we select all years starting from 2010 + pop[2010:, 'BruCap', 50:52, 'F', 'BE'] + + id: 25 + +- code: | + # Slices can also have a step (defaults to 1), to take every Nth labels + # Here we select all even years starting from 2010 + pop[2010::2, 'BruCap', 50:52, 'F', 'BE'] + + id: 26 + +- code: | + # one can also use list of labels to take non-contiguous labels. + # Here we select years 2008, 2010, 2013 and 2015 + pop[[2008, 2010, 2013, 2015], 'BruCap', 50:52, 'F', 'BE'] + + id: 27 + +- markdown: | + The order of indexing does not matter either, so you usually do not care/have to remember about axes positions during computation. It only matters for output. + + +- code: | + # order of index doesn't matter + pop['F', 'BE', 'BruCap', [2008, 2010, 2013, 2015], 50:52] + + id: 28 + +- markdown: | +
+ **Warning:** Selecting by labels as above works well as long as there is no ambiguity. + When two or more axes have common labels, it may lead to a crash. + The solution is then to precise to which axis belong the labels. +
+ + +- code: | + # let us now create an array with the same labels on several axes + age, weight, size = Axis('age=0..80'), Axis('weight=0..120'), Axis('size=0..200') + + arr_ws = ndtest([age, weight, size]) + + id: 29 + +- code: | + # let's try to select teenagers with size between 1 m 60 and 1 m 65 and weight > 80 kg. + # In this case the subset is ambiguous and this results in an error: + arr_ws[10:18, :80, 160:165] + + id: 30 + +- code: | + # the solution is simple. You need to precise the axes on which you make a selection + arr_ws[age[10:18], weight[:80], size[160:165]] + + id: 31 + +- markdown: | + ### Special variable X + + When selecting, assiging or using aggregate functions, an axis can be + refered via the special variable ``X``: + + - pop[X.age[:20]] + - pop.sum(X.age) + + This gives you acces to axes of the array you are manipulating. The main + drawback of using **X** is that you lose the autocompletion available from + many editors. It only works with non-wildcard axes. + + +- code: | + # the previous example could have been also written as + arr_ws[X.age[10:18], X.weight[:80], X.size[160:165]] + + id: 32 + +- markdown: | + ### Selection by Positions + + Sometimes it is more practical to use positions along the axis, instead of labels. + You need to add the character ``i`` before the brackets: ``.i[positions]``. + As for selection with labels, you can use single position or slice or list of positions. + Positions can be also negative (-1 represent the last element of an axis). + + +- markdown: | +
+ **Note:** Remember that positions (indices) are always **0-based** in Python. + So the first element is at position 0, the second is at position 1, etc. +
+ + +- code: | + # here we select the subset associated with Belgian women of age 50, 51 and 52 + # from Brussels region for the first 3 years + pop[X.time.i[:3], 'BruCap', 50:52, 'F', 'BE'] + + id: 33 + +- code: | + # same but for the last 3 years + pop[X.time.i[-3:], 'BruCap', 50:52, 'F', 'BE'] + + id: 34 + +- code: | + # using list of positions + pop[X.time.i[-9,-7,-4,-2], 'BruCap', 50:52, 'F', 'BE'] + + id: 35 + +- markdown: | +
+ **Warning:** The end *indice* (position) is EXCLUSIVE while the end label is INCLUSIVE. +
+ + +- code: | + # with labels (3 is included) + pop[2015, 'BruCap', X.age[:3], 'F', 'BE'] + + id: 36 + +- code: | + # with position (3 is out) + pop[2015, 'BruCap', X.age.i[:3], 'F', 'BE'] + + id: 37 + +- markdown: | + You can use ``.i[]`` selection directly on array instead of axes. + In this context, if you want to select a subset of the first and third axes for example, you must use a full slice ``:`` for the second one. + + +- code: | + # here we select the last year and first 3 ages + # equivalent to: pop.i[-1, :, :3, :, :] + pop.i[-1, :, :3] + + id: 38 + +- markdown: | + ### Assigning subsets + + #### Assigning value + + Assign a value to a subset + + +- code: | + # let's take a smaller array + pop = load_example_data('demography').pop[2016, 'BruCap', 100:105] + pop2 = pop + pop2 + + id: 39 + +- code: | + # set all data corresponding to age >= 102 to 0 + pop2[102:] = 0 + pop2 + + id: 40 + +- markdown: | + One very important gotcha though... + +
+ **Warning:** Modifying a slice of an array in-place like we did above should be done with care otherwise you could have **unexpected effects**. The reason is that taking a **slice** subset of an array does not return a copy of that array, but rather a view on that array. To avoid such behavior, use ``.copy()`` method. +
+ + Remember: + + - taking a slice subset of an array is extremely fast (no data is + copied) + - if one modifies that subset in-place, one also **modifies the + original array** + - **.copy()** returns a copy of the subset (takes speed and memory) but + allows you to change the subset without modifying the original array + in the same time + + +- code: | + # indeed, data from the original array have also changed + pop + + id: 41 + +- code: | + # the right way + pop = load_example_data('demography').pop[2016, 'BruCap', 100:105] + + pop2 = pop.copy() + pop2[102:] = 0 + pop2 + + id: 42 + +- code: | + # now, data from the original array have not changed this time + pop + + id: 43 + +- markdown: | + #### Assigning Arrays & Broadcasting + + Instead of a value, we can also assign an array to a subset. In that + case, that array can have less axes than the target but those which are + present must be compatible with the subset being targeted. + + +- code: | + sex, nat = Axis('sex=M,F'), Axis('nat=BE,FO') + new_value = LArray([[1, -1], [2, -2]],[sex, nat]) + new_value + + id: 44 + +- code: | + # this assigns 1, -1 to Belgian, Foreigner men + # and 2, -2 to Belgian, Foreigner women for all + # people older than 100 + pop[102:] = new_value + pop + + id: 45 + +- markdown: | +
+ **Warning:** The array being assigned must have compatible axes with the target subset. +
+ + +- code: | + # assume we define the following array with shape 3 x 2 x 2 + new_value = zeros(['age=0..2', sex, nat]) + new_value + + id: 46 + +- code: | + # now let's try to assign the previous array in a subset with shape 7 x 2 x 2 + pop[102:] = new_value + + id: 47 + +- code: | + # but this works + pop[102:104] = new_value + pop + + id: 48 + +- markdown: | + ### Boolean filtering + + Boolean filtering can be use to extract subsets. + + +- code: | + #Let's focus on population living in Brussels during the year 2016 + pop = load_example_data('demography').pop[2016, 'BruCap'] + + # here we select all males and females with age less than 5 and 10 respectively + subset = pop[((X.sex == 'H') & (X.age <= 5)) | ((X.sex == 'F') & (X.age <= 10))] + subset + + id: 49 + +- markdown: | +
+ **Note:** Be aware that after boolean filtering, several axes may have merged. +
+ + +- code: | + # 'age' and 'sex' axes have been merged together + subset.info + + id: 50 + +- markdown: | + This may be not what you because previous selections on merged axes are no longer valid + + +- code: | + # now let's try to calculate the proportion of females with age less than 10 + subset['F'].sum() / pop['F'].sum() + + id: 51 + +- markdown: | + Therefore, it is sometimes more useful to not select, but rather set to 0 (or another value) non matching elements + + +- code: | + subset = pop.copy() + subset[((X.sex == 'F') & (X.age > 10))] = 0 + subset['F', :20] + + id: 52 + +- code: | + # now we can calculate the proportion of females with age less than 10 + subset['F'].sum() / pop['F'].sum() + + id: 53 + +- markdown: | + Boolean filtering can also mix axes and arrays. Example above could also have been written as + + +- code: | + age_limit = sequence('sex=M,F', initial=5, inc=5) + age_limit + + id: 54 + +- code: | + age = pop.axes['age'] + (age <= age_limit)[:20] + + id: 55 + +- code: | + subset = pop.copy() + subset[X.age > age_limit] = 0 + subset['F'].sum() / pop['F'].sum() + + id: 56 + +- markdown: | + Finally, you can choose to filter on data instead of axes + + +- code: | + # let's focus on females older than 90 + subset = pop['F', 90:110].copy() + subset + + id: 57 + +- code: | + # here we set to 0 all data < 10 + subset[subset < 10] = 0 + subset + + id: 58 + +- markdown: | + ## Manipulates axes from arrays + + +- code: | + # let's start with + pop = load_example_data('demography').pop[2016, 'BruCap', 90:95] + pop + + id: 59 + +- markdown: | + ### Relabeling + + Replace all labels of one axis + + +- code: | + # returns a copy by default + pop_new_labels = pop.set_labels('sex', ['Men', 'Women']) + pop_new_labels + + id: 60 + +- code: | + # inplace flag avoids to create a copy + pop.set_labels('sex', ['M', 'F'], inplace=True) + + id: 61 + +- markdown: | + ### Renaming axes + + Rename one axis + + +- code: | + pop.info + + id: 62 + +- code: | + # 'rename' returns a copy of the array + pop2 = pop.rename('sex', 'gender') + pop2 + + id: 63 + +- markdown: | + Rename several axes at once + + +- code: | + # No x. here because sex and nat are keywords and not actual axes + pop2 = pop.rename(sex='gender', nat='nationality') + pop2 + + id: 64 + +- markdown: | + ### Reordering axes + + Axes can be reordered using ``transpose`` method. + By default, *transpose* reverse axes, otherwise it permutes the axes according to the list given as argument. + Axes not mentioned come after those which are mentioned(and keep their relative order). + Finally, *transpose* returns a copy of the array. + + +- code: | + # starting order : age, sex, nat + pop + + id: 65 + +- code: | + # no argument --> reverse axes + pop.transpose() + + # .T is a shortcut for .transpose() + pop.T + + id: 66 + +- code: | + # reorder according to list + pop.transpose('age', 'nat', 'sex') + + id: 67 + +- code: | + # axes not mentioned come after those which are mentioned (and keep their relative order) + pop.transpose('sex') + + id: 68 + +- markdown: | + ## Aggregates + + Calculate the sum along an axis + + +- code: | + pop = load_example_data('demography').pop[2016, 'BruCap'] + pop.sum('age') + + id: 69 + +- markdown: | + or along all axes except one by appending `_by` to the aggregation function + + +- code: | + pop[90:95].sum_by('age') + # is equivalent to + pop[90:95].sum('sex', 'nat') + + id: 70 + +- markdown: | + There are many other aggregation functions: + + - mean, min, max, median, percentile, var (variance), std (standard + deviation) + - labelofmin, labelofmax (label indirect minimum/maxium -- labels where the + value is minimum/maximum) + - indexofmin, indexofmax (positional indirect minimum/maxium -- position + along axis where the value is minimum/maximum) + - cumsum, cumprod (cumulative sum, cumulative product) + + +- markdown: | + ## Groups + + One can define groups of labels (or indices) + + +- code: | + age = pop.axes['age'] + + # using indices (remember: 20 will not be included) + teens = age.i[10:20] + # using labels + pensioners = age[67:] + strange = age[[30, 55, 52, 25, 99]] + + strange + + id: 71 + +- markdown: | + or rename them + + +- code: | + # method 'named' returns a new group with the given name + teens = teens.named('children') + + # operator >> is a shortcut for 'named' + pensioners = pensioners >> 'pensioners' + + pensioners + + id: 72 + +- markdown: | + Then, use them in selections + + +- code: | + pop[strange] + + id: 73 + +- markdown: | + or aggregations + + +- code: | + pop.sum(pensioners) + + id: 74 + +- code: | + # several groups (here you see the interest of groups renaming) + pop.sum((teens, pensioners, strange)) + + id: 75 + +- code: | + # combined with other axes + pop.sum((teens, pensioners, strange), 'nat') + + id: 76 + +- markdown: | + ## Arithmetic operations + + +- code: | + # go back to our 6 x 2 x 2 example array + pop = load_example_data('demography').pop[2016, 'BruCap', 90:95] + pop + + id: 77 + +- markdown: | + One can do all usual arithmetic operations on an array, it will apply the operation to all elements individually + + +- code: | + # addition + pop + 200 + + id: 78 + +- code: | + # multiplication + pop * 2 + + id: 79 + +- code: | + # ** means raising to the power (squaring in this case) + pop ** 2 + + id: 80 + +- code: | + # % means modulo (aka remainder of division) + pop % 10 + + id: 81 + +- markdown: | + More interestingly, it also works between two arrays + + +- code: | + # load mortality equivalent array + mortality = load_example_data('demography').qx[2016, 'BruCap', 90:95] + + # compute number of deaths + death = pop * mortality + death + + id: 82 + +- markdown: | +
+ **Note:** Be careful when mixing different data types. + You can use the method ``astype`` to change the data type of an array. +
+ + +- code: | + # to be sure to get number of deaths as integers + # one can use .astype() method + death = (pop * mortality).astype(int) + death + + id: 83 + +- markdown: | + But operations between two arrays only works when they have compatible axes (i.e. same labels) + + +- code: | + pop[90:92] * mortality[93:95] + + id: 84 + +- markdown: | + You can override that but at your own risk. + In that case only the position on the axis is used and not the labels. + + +- code: | + pop[90:92] * mortality[93:95].drop_labels('age') + + id: 85 + +- markdown: | + ### Boolean Operations + + +- code: | + pop2 = pop.copy() + pop2['F'] = -pop2['F'] + pop2 + + id: 86 + +- code: | + # testing for equality is done using == (a single = assigns the value) + pop == pop2 + + id: 87 + +- code: | + # testing for inequality + pop != pop2 + + id: 88 + +- code: | + # what was our original array like again? + pop + + id: 89 + +- code: | + # & means (boolean array) and + (pop >= 500) & (pop <= 1000) + + id: 90 + +- code: | + # | means (boolean array) or + (pop < 500) | (pop > 1000) + + id: 91 + +- markdown: | + ### Arithmetic operations with missing axes + + +- code: | + pop.sum('age') + + id: 92 + +- code: | + # arr has 3 dimensions + pop.info + + id: 93 + +- code: | + # and arr.sum(age) has two + pop.sum('age').info + + id: 94 + +- code: | + # you can do operation with missing axes so this works + pop / pop.sum('age') + + id: 95 + +- markdown: | + ### Axis order does not matter much (except for output) + + You can do operations between arrays having different axes order. + The axis order of the result is the same as the left array + + +- code: | + pop + + id: 96 + +- code: | + # let us change the order of axes + pop_transposed = pop.T + pop_transposed + + id: 97 + +- code: | + # mind blowing + pop_transposed + pop + + id: 98 + +- markdown: | + ## Combining arrays + + ### Append/Prepend + + Append/prepend one element to an axis of an array + + +- code: | + pop = load_example_data('demography').pop[2016, 'BruCap', 90:95] + + # imagine that you have now acces to the number of non-EU foreigners + data = [[25, 54], [15, 33], [12, 28], [11, 37], [5, 21], [7, 19]] + pop_non_eu = LArray(data, pop['FO'].axes) + + # you can do something like this + pop = pop.append(nat, pop_non_eu, 'NEU') + pop + + id: 99 + +- code: | + # you can also add something at the start of an axis + pop = pop.prepend('sex', pop.sum('sex'), 'B') + pop + + id: 100 + +- markdown: | + The value being appended/prepended can have missing (or even extra) axes as long as common axes are compatible + + +- code: | + aliens = zeros(pop.axes['sex']) + aliens + + id: 101 + +- code: | + pop = pop.append('nat', aliens, 'AL') + pop + + id: 102 + +- markdown: | + ### Extend + + Extend an array along an axis with another array *with* that axis (but other labels) + + +- code: | + _pop = load_example_data('demography').pop + pop = _pop[2016, 'BruCap', 90:95] + pop_next = _pop[2016, 'BruCap', 96:100] + + # concatenate along age axis + pop.extend('age', pop_next) + + id: 103 + +- markdown: | + ### Stack + + Stack several arrays together to create an entirely new dimension + + +- code: | + # imagine you have loaded data for each nationality in different arrays (e.g. loaded from different Excel sheets) + pop_be, pop_fo = pop['BE'], pop['FO'] + + # first way to stack them + nat = Axis('nat=BE,FO,NEU') + pop = stack([pop_be, pop_fo, pop_non_eu], nat) + + # second way + pop = stack([('BE', pop_be), ('FO', pop_fo), ('NEU', pop_non_eu)], 'nat') + + pop + + id: 104 + +- markdown: | + ## Sorting + + Sort an axis (alphabetically if labels are strings) + + +- code: | + pop_sorted = pop.sort_axes('nat') + pop_sorted + + id: 105 + +- markdown: | + Give labels which would sort the axis + + +- code: | + pop_sorted.labelsofsorted('sex') + + id: 106 + +- markdown: | + Sort according to values + + +- code: | + pop_sorted.sort_values((90, 'F')) + + id: 107 + +- markdown: | + ## Plotting + + Create a plot (last axis define the different curves to draw) + + +- code: | + pop.plot() + + id: 108 + +- code: | + # plot total of both sex + pop.sum('sex').plot() + + id: 109 + +- markdown: | + ## Interesting methods + + +- code: | + # starting array + pop = load_example_data('demography').pop[2016, 'BruCap', 100:105] + pop + + id: 110 + +- markdown: | + ### with total + + Add totals to one axis + + +- code: | + pop.with_total('sex', label='B') + + id: 111 + +- markdown: | + Add totals to all axes at once + + +- code: | + # by default label is 'total' + pop.with_total() + + id: 112 + +- markdown: | + ### where + + where can be used to apply some computation depending on a condition + + +- code: | + # where(condition, value if true, value if false) + where(pop < 10, 0, -pop) + + id: 113 + +- markdown: | + ### clip + + Set all data between a certain range + + +- code: | + # clip(min, max) + # values below 10 are set to 10 and values above 50 are set to 50 + pop.clip(10, 50) + + id: 114 + +- markdown: | + ### divnot0 + + Replace division by 0 to 0 + + +- code: | + pop['BE'] / pop['FO'] + + id: 115 + +- code: | + # divnot0 replaces results of division by 0 by 0. + # Using it should be done with care though + # because it can hide a real error in your data. + pop['BE'].divnot0(pop['FO']) + + id: 116 + +- markdown: | + ### diff + + The ``diff`` method calculates the n-th order discrete difference along a given axis. + The first order difference is given by out[n+1] = in[n + 1] - in[n] along the given axis. + + +- code: | + pop = load_example_data('demography').pop[2005:2015, 'BruCap', 50] + pop + + id: 117 + +- code: | + # calculates 'pop[year+1] - pop[year]' + pop.diff('time') + + id: 118 + +- code: | + # calculates 'pop[year+2] - pop[year]' + pop.diff('time', d=2) + + id: 119 + +- markdown: | + ### ratio + + +- code: | + pop.ratio('nat') + + # which is equivalent to + pop / pop.sum('nat') + + id: 120 + +- markdown: | + ### percents + + +- code: | + # or, if you want the previous ratios in percents + pop.percent('nat') + + id: 121 + +- markdown: | + ### growth\_rate + + using the same principle than `diff` + + +- code: | + pop.growth_rate('time') + + id: 122 + +- markdown: | + ### shift + + The ``shift`` method drops first label of an axis and shifts all subsequent labels + + +- code: | + pop.shift('time') + + id: 123 + +- code: | + # when shift is applied on an (increasing) time axis, + # it effectively brings "past" data into the future + pop.shift('time').drop_labels('time') == pop[2005:2014].drop_labels('time') + + id: 124 + +- code: | + # this is mostly useful when you want to do operations between the past and now + # as an example, here is an alternative implementation of the .diff method seen above: + pop.i[1:] - pop.shift('time') + + id: 125 + +- markdown: | + ### Misc other interesting functions + + There are a lot more interesting functions available: + + - round, floor, ceil, trunc, + - exp, log, log10, + - sqrt, absolute, nan_to_num, isnan, isinf, inverse, + - sin, cos, tan, arcsin, arccos, arctan + - and many many more... + + +- markdown: | + ## Sessions + + You can group several arrays in a Session + + +- code: | + # load several arrays + arr1, arr2, arr3 = ndtest((3, 3)), ndtest((4, 2)), ndtest((2, 4)) + + # create and populate a 'session' + s1 = Session() + s1.arr1 = arr1 + s1.arr2 = arr2 + s1.arr3 = arr3 + + s1 + + id: 126 + +- code: | + s2 = s1.copy() + s3 = s1.copy() + + id: 127 + metadata: + nbsphinx: hidden + +- markdown: | + The advantage of sessions is that you can manipulate all of the arrays in them in one shot + + ```python + # this saves all the arrays in a single excel file (each array on a different sheet) + s1.save('test.xlsx') + + # this saves all the arrays in a single HDF5 file (which is a very fast format) + s1.save('test.h5') + + # this creates a session out of all arrays in the .h5 file + s2 = Session('test.h5') + ``` + + +- markdown: | + ```python + # this creates a session out of all arrays in the .xlsx file + s3 = Session('test.xlsx') + ``` + + +- markdown: | + You can compare two sessions + + +- code: | + s1.equals(s2) + + id: 128 + +- code: | + # let us introduce a difference (a variant, or a mistake perhaps) + s2.arr1['a0', 'b1':] = 0 + + id: 129 + +- code: | + s1.equals(s2) + + id: 130 + +- code: | + s_diff = s1 != s2 + s_diff + + id: 131 + +- markdown: | + This a bit experimental but can be useful nonetheless (open a graphical interface) + + ```python + compare(s1_diff.arr1, s2_diff.arr1) + ``` + + +# The lines below here may be deleted if you do not need them. +# --------------------------------------------------------------------------- +metadata: + celltoolbar: Edit Metadata + kernelspec: + display_name: Python 3 + language: python + name: python3 + language_info: + codemirror_mode: + name: ipython + version: 3 + file_extension: .py + mimetype: text/x-python + name: python + nbconvert_exporter: python + pygments_lexer: ipython3 + version: 3.6.4 + livereveal: + autolaunch: false + scroll: true +nbformat: 4 +nbformat_minor: 2 + +# --------------------------------------------------------------------------- +data: + [{execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, + outputs: []}, {execution_count: null, outputs: []}, {execution_count: null, outputs: []}, + {execution_count: null, outputs: []}, {execution_count: null, outputs: []}] diff --git a/doc/source/tutorial/tutorial.ipynb b/doc/source/tutorial/tutorial.ipynb new file mode 100644 index 000000000..5d38f2acf --- /dev/null +++ b/doc/source/tutorial/tutorial.ipynb @@ -0,0 +1,2483 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "nbsphinx": "hidden" + }, + "outputs": [], + "source": [ + "# @tutorial writers: You can remove cells from the HTML/LaTeX output by adding this to the cell metadata:\n", + "# \"nbsphinx\": \"hidden\"\n", + "\n", + "# ignore warnings\n", + "import warnings\n", + "warnings.filterwarnings('ignore')\n", + "\n", + "# simplify exception output\n", + "%xmode Plain" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To import the LArray library, run:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from larray import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Axis creation\n", + "\n", + "An Axis represents a dimension of an LArray object.\n", + "It consists of a name and a list of labels. They are several ways to create an axis:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# create a wildcard axis \n", + "age = Axis(3, 'age')\n", + "# labels given as a list \n", + "time = Axis([2007, 2008, 2009], 'time')\n", + "# create an axis using one string\n", + "sex = Axis('sex=M,F')\n", + "# labels generated using a special syntax \n", + "other = Axis('other=A01..C03')\n", + "\n", + "age, sex, time, other" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Array creation\n", + "\n", + "A LArray object represents a multidimensional array with labeled axes.\n", + "\n", + "### From scratch\n", + "\n", + "To create an array from scratch, you need to provide the data and a list\n", + "of axes. Optionally, a title can be defined.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "# list of the axes\n", + "axes = [age, sex, time, other]\n", + "# data (the shape of data array must match axes lengths)\n", + "data = np.random.randint(100, size=[len(axis) for axis in axes])\n", + "# title (optional)\n", + "title = 'random data'\n", + "\n", + "arr = LArray(data, axes, title)\n", + "arr" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Array creation functions\n", + "\n", + "Arrays can also be generated in an easier way through creation functions:\n", + "\n", + "- `ndtest` : creates a test array with increasing numbers as data\n", + "- `empty` : creates an array but leaves its allocated memory\n", + " unchanged (i.e., it contains \"garbage\". Be careful !)\n", + "- `zeros`: fills an array with 0\n", + "- `ones` : fills an array with 1\n", + "- `full` : fills an array with a given value\n", + "- `sequence` : creates an array from an axis by iteratively applying a function to a given initial value.\n", + "\n", + "Except for ndtest, a list of axes must be provided.\n", + "Axes can be passed in different ways:\n", + "\n", + "- as Axis objects\n", + "- as integers defining the lengths of auto-generated wildcard axes\n", + "- as a string : 'sex=M,F;time=2007,2008,2009' (name is optional)\n", + "- as pairs (name, labels)\n", + "\n", + "Optionally, the type of data stored by the array can be specified using argument dtype.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# start defines the starting value of data\n", + "ndtest(['age=0..2', 'sex=M,F', 'time=2007..2009'], start=-1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# start defines the starting value of data\n", + "# label_start defines the starting index of labels\n", + "ndtest((3, 3), start=-1, label_start=2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# empty generates uninitialised array with correct axes \n", + "# (much faster but use with care!).\n", + "# This not really random either, it just reuses a portion \n", + "# of memory that is available, with whatever content is there. \n", + "# Use it only if performance matters and make sure all data \n", + "# will be overridden. \n", + "empty(['age=0..2', 'sex=M,F', 'time=2007..2009'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# example with anonymous axes\n", + "zeros(['0..2', 'M,F', '2007..2009'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# dtype=int forces to store int data instead of default float\n", + "ones(['age=0..2', 'sex=M,F', 'time=2007..2009'], dtype=int)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "full(['age=0..2', 'sex=M,F', 'time=2007..2009'], 1.23)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All the above functions exist in *(func)_like* variants which take axes from another array\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ones_like(arr)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sequence\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# With initial=1.0 and inc=0.5, we generate the sequence 1.0, 1.5, 2.0, 2.5, 3.0, ... \n", + "sequence('sex=M,F', initial=1.0, inc=0.5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# With initial=1.0 and mult=2.0, we generate the sequence 1.0, 2.0, 4.0, 8.0, ... \n", + "sequence('age=0..2', initial=1.0, mult=2.0) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Using your own function\n", + "sequence('time=2007..2009', initial=2.0, func=lambda value: value**2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also create N-dimensional array by passing (N-1)-dimensional\n", + "array to initial, inc or mult argument\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "birth = LArray([1.05, 1.15], 'sex=M,F')\n", + "cumulate_newborns = sequence('time=2007..2009', initial=0.0, inc=birth)\n", + "cumulate_newborns" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "initial = LArray([90, 100], 'sex=M,F') \n", + "survival = LArray([0.96, 0.98], 'sex=M,F')\n", + "pop = sequence('age=80..83', initial=initial, mult=survival)\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load/Dump from files\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "nbsphinx": "hidden" + }, + "outputs": [], + "source": [ + "demography = load_example_data('demography')\n", + "household = demography.hh\n", + "pop = demography.pop\n", + "mortality = demography.qx" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load from files\n", + "\n", + "Arrays can be loaded from CSV files\n", + "\n", + "```python\n", + "# read_tsv is a shortcut when data are separated by tabs instead of commas (default separator of read_csv)\n", + "# read_eurostat is a shortcut to read EUROSTAT TSV files \n", + "household = read_csv('hh.csv')\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or Excel sheets\n", + "\n", + "```python\n", + "# loads array from the first sheet if no sheet is given\n", + "pop = read_excel('demography.xlsx', 'pop')\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or HDF5 files (HDF5 is file format designed to store and organize large amounts of data. \n", + "An HDF5 file can contain multiple arrays. \n", + "\n", + "```python\n", + "mortality = read_hdf('demography.h5','qx')\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "See documentation of reading functions for more details\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Dump in files\n", + "\n", + "Arrays can be dumped in CSV files \n", + "\n", + "```python\n", + "household.to_csv('hh2.csv')\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or in Excel files\n", + "\n", + "```python\n", + "# if the file does not already exist, it is created with a single sheet, \n", + "# otherwise a new sheet is added to it\n", + "household.to_excel('demography_2.xlsx', overwrite_file=True)\n", + "# it is usually better to specify the sheet explicitly (by name or position) though\n", + "household.to_excel('demography_2.xlsx', 'hh')\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or in HDF5 files\n", + "\n", + "```python\n", + "household.to_hdf('demography_2.h5', 'hh')\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "See documentation of writing methods for more details\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### more Excel IO\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Write Arrays\n", + "\n", + "Open an Excel file\n", + "\n", + "```python\n", + "wb = open_excel('test.xlsx', overwrite_file=True)\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Put an array in an Excel Sheet, **excluding** headers (labels)\n", + "\n", + "```python\n", + "# put arr at A1 in Sheet1, excluding headers (labels)\n", + "wb['Sheet1'] = arr\n", + "# same but starting at A9\n", + "# note that Sheet1 must exist\n", + "wb['Sheet1']['A9'] = arr\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Put an array in an Excel Sheet, **including** headers (labels)\n", + "\n", + "```python\n", + "# dump arr at A1 in Sheet2, including headers (labels)\n", + "wb['Sheet2'] = arr.dump()\n", + "# same but starting at A10\n", + "wb['Sheet2']['A10'] = arr.dump()\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Save file to disk \n", + "\n", + "```python\n", + "wb.save()\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Close file \n", + "\n", + "```python\n", + "wb.close()\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Read Arrays\n", + "\n", + "Open an Excel file \n", + "\n", + "```python\n", + "wb = open_excel('test.xlsx')\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load an array from a sheet (assuming the presence of (correctly formatted) headers and only one array in sheet)\n", + "\n", + "```python\n", + "# save one array in Sheet3 (including headers)\n", + "wb['Sheet3'] = arr.dump()\n", + "\n", + "# load array from the data starting at A1 in Sheet3\n", + "arr = wb['Sheet3'].load()\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load an array with its axes information from a range\n", + "\n", + "```python\n", + "# if you need to use the same sheet several times,\n", + "# you can create a sheet variable\n", + "sheet2 = wb['Sheet2']\n", + "\n", + "# load array contained in the 4 x 4 table defined by cells A10 and D14\n", + "arr2 = sheet2['A10:D14'].load()\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Read Ranges (experimental)\n", + "\n", + "Load an array (raw data) with no axis information from a range\n", + "\n", + "```python\n", + "arr3 = wb['Sheet1']['A1:B4']\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "in fact, this is not really an LArray ...\n", + "\n", + "```python\n", + "type(arr3)\n", + "\n", + "larray.io.excel.Range\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "... but it can be used as such \n", + "\n", + "```python\n", + "arr3.sum(axis=0)\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "... and it can be used for other stuff, like setting the formula instead of the value: \n", + "\n", + "```python\n", + "arr3.formula = '=D10+1'\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the future, we should also be able to set font name, size, style, etc. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Inspecting\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# load population array\n", + "pop = load_example_data('demography').pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get array summary : dimensions + description of axes\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.info" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get axes \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "time, geo, age, sex, nat = pop.axes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get array dimensions \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get number of elements \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.size" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get size in memory\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.memory_used" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Start viewer (graphical user interface) in read-only mode.\n", + "This will open a new window and block execution of the rest of code until the windows is closed! Required PyQt installed.\n", + "\n", + "```python\n", + "view(pop)\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load array in an Excel sheet\n", + "\n", + "```python\n", + "pop.to_excel()\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Selection (Subsets)\n", + "\n", + "LArray allows to select a subset of an array either by labels or positions\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Selection by Labels\n", + "\n", + "To take a subset of an array using labels, use brackets [ ].\n", + "\n", + "Let's start by selecting a single element:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# here we select the value associated with Belgian women \n", + "# of age 50 from Brussels region for the year 2015\n", + "pop[2015, 'BruCap', 50, 'F', 'BE']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Continue with selecting a subset using slices and lists of labels\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# here we select the subset associated with Belgian women of age 50, 51 and 52 \n", + "# from Brussels region for the years 2010 to 2016\n", + "pop[2010:2016, 'BruCap', 50:52, 'F', 'BE']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# slices bounds are optional: \n", + "# if not given start is assumed to be the first label and stop is the last one.\n", + "# Here we select all years starting from 2010\n", + "pop[2010:, 'BruCap', 50:52, 'F', 'BE']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Slices can also have a step (defaults to 1), to take every Nth labels\n", + "# Here we select all even years starting from 2010\n", + "pop[2010::2, 'BruCap', 50:52, 'F', 'BE']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# one can also use list of labels to take non-contiguous labels.\n", + "# Here we select years 2008, 2010, 2013 and 2015\n", + "pop[[2008, 2010, 2013, 2015], 'BruCap', 50:52, 'F', 'BE']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The order of indexing does not matter either, so you usually do not care/have to remember about axes positions during computation. It only matters for output.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# order of index doesn't matter\n", + "pop['F', 'BE', 'BruCap', [2008, 2010, 2013, 2015], 50:52]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "**Warning:** Selecting by labels as above works well as long as there is no ambiguity.\n", + " When two or more axes have common labels, it may lead to a crash.\n", + " The solution is then to precise to which axis belong the labels.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# let us now create an array with the same labels on several axes\n", + "age, weight, size = Axis('age=0..80'), Axis('weight=0..120'), Axis('size=0..200')\n", + "\n", + "arr_ws = ndtest([age, weight, size])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# let's try to select teenagers with size between 1 m 60 and 1 m 65 and weight > 80 kg.\n", + "# In this case the subset is ambiguous and this results in an error:\n", + "arr_ws[10:18, :80, 160:165]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# the solution is simple. You need to precise the axes on which you make a selection\n", + "arr_ws[age[10:18], weight[:80], size[160:165]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Special variable X\n", + "\n", + "When selecting, assiging or using aggregate functions, an axis can be\n", + "refered via the special variable ``X``:\n", + "\n", + "- pop[X.age[:20]]\n", + "- pop.sum(X.age)\n", + "\n", + "This gives you acces to axes of the array you are manipulating. The main\n", + "drawback of using **X** is that you lose the autocompletion available from\n", + "many editors. It only works with non-wildcard axes.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# the previous example could have been also written as \n", + "arr_ws[X.age[10:18], X.weight[:80], X.size[160:165]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Selection by Positions\n", + "\n", + "Sometimes it is more practical to use positions along the axis, instead of labels. \n", + "You need to add the character ``i`` before the brackets: ``.i[positions]``. \n", + "As for selection with labels, you can use single position or slice or list of positions. \n", + "Positions can be also negative (-1 represent the last element of an axis).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "**Note:** Remember that positions (indices) are always **0-based** in Python.\n", + "So the first element is at position 0, the second is at position 1, etc.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# here we select the subset associated with Belgian women of age 50, 51 and 52 \n", + "# from Brussels region for the first 3 years\n", + "pop[X.time.i[:3], 'BruCap', 50:52, 'F', 'BE']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# same but for the last 3 years\n", + "pop[X.time.i[-3:], 'BruCap', 50:52, 'F', 'BE']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using list of positions\n", + "pop[X.time.i[-9,-7,-4,-2], 'BruCap', 50:52, 'F', 'BE']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "**Warning:** The end *indice* (position) is EXCLUSIVE while the end label is INCLUSIVE.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# with labels (3 is included)\n", + "pop[2015, 'BruCap', X.age[:3], 'F', 'BE']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# with position (3 is out)\n", + "pop[2015, 'BruCap', X.age.i[:3], 'F', 'BE']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can use ``.i[]`` selection directly on array instead of axes. \n", + "In this context, if you want to select a subset of the first and third axes for example, you must use a full slice ``:`` for the second one.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# here we select the last year and first 3 ages\n", + "# equivalent to: pop.i[-1, :, :3, :, :]\n", + "pop.i[-1, :, :3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Assigning subsets\n", + "\n", + "#### Assigning value\n", + "\n", + "Assign a value to a subset\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# let's take a smaller array\n", + "pop = load_example_data('demography').pop[2016, 'BruCap', 100:105]\n", + "pop2 = pop\n", + "pop2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# set all data corresponding to age >= 102 to 0\n", + "pop2[102:] = 0\n", + "pop2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One very important gotcha though...\n", + "\n", + "
\n", + "**Warning:** Modifying a slice of an array in-place like we did above should be done with care otherwise you could have **unexpected effects**. The reason is that taking a **slice** subset of an array does not return a copy of that array, but rather a view on that array. To avoid such behavior, use ``.copy()`` method.\n", + "
\n", + " \n", + "Remember:\n", + "\n", + "- taking a slice subset of an array is extremely fast (no data is\n", + " copied)\n", + "- if one modifies that subset in-place, one also **modifies the\n", + " original array**\n", + "- **.copy()** returns a copy of the subset (takes speed and memory) but\n", + " allows you to change the subset without modifying the original array\n", + " in the same time\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# indeed, data from the original array have also changed\n", + "pop" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# the right way\n", + "pop = load_example_data('demography').pop[2016, 'BruCap', 100:105]\n", + "\n", + "pop2 = pop.copy()\n", + "pop2[102:] = 0\n", + "pop2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# now, data from the original array have not changed this time\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Assigning Arrays & Broadcasting\n", + "\n", + "Instead of a value, we can also assign an array to a subset. In that\n", + "case, that array can have less axes than the target but those which are\n", + "present must be compatible with the subset being targeted.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sex, nat = Axis('sex=M,F'), Axis('nat=BE,FO')\n", + "new_value = LArray([[1, -1], [2, -2]],[sex, nat])\n", + "new_value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# this assigns 1, -1 to Belgian, Foreigner men \n", + "# and 2, -2 to Belgian, Foreigner women for all \n", + "# people older than 100\n", + "pop[102:] = new_value\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "**Warning:** The array being assigned must have compatible axes with the target subset.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# assume we define the following array with shape 3 x 2 x 2\n", + "new_value = zeros(['age=0..2', sex, nat]) \n", + "new_value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# now let's try to assign the previous array in a subset with shape 7 x 2 x 2\n", + "pop[102:] = new_value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# but this works\n", + "pop[102:104] = new_value\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Boolean filtering\n", + "\n", + "Boolean filtering can be use to extract subsets.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#Let's focus on population living in Brussels during the year 2016\n", + "pop = load_example_data('demography').pop[2016, 'BruCap']\n", + "\n", + "# here we select all males and females with age less than 5 and 10 respectively\n", + "subset = pop[((X.sex == 'H') & (X.age <= 5)) | ((X.sex == 'F') & (X.age <= 10))]\n", + "subset" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "**Note:** Be aware that after boolean filtering, several axes may have merged.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 'age' and 'sex' axes have been merged together\n", + "subset.info" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This may be not what you because previous selections on merged axes are no longer valid\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# now let's try to calculate the proportion of females with age less than 10\n", + "subset['F'].sum() / pop['F'].sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Therefore, it is sometimes more useful to not select, but rather set to 0 (or another value) non matching elements\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "subset = pop.copy()\n", + "subset[((X.sex == 'F') & (X.age > 10))] = 0\n", + "subset['F', :20]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# now we can calculate the proportion of females with age less than 10\n", + "subset['F'].sum() / pop['F'].sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Boolean filtering can also mix axes and arrays. Example above could also have been written as\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_limit = sequence('sex=M,F', initial=5, inc=5)\n", + "age_limit" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age = pop.axes['age']\n", + "(age <= age_limit)[:20]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "subset = pop.copy()\n", + "subset[X.age > age_limit] = 0\n", + "subset['F'].sum() / pop['F'].sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, you can choose to filter on data instead of axes\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# let's focus on females older than 90\n", + "subset = pop['F', 90:110].copy()\n", + "subset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# here we set to 0 all data < 10\n", + "subset[subset < 10] = 0\n", + "subset" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Manipulates axes from arrays\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# let's start with\n", + "pop = load_example_data('demography').pop[2016, 'BruCap', 90:95]\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Relabeling\n", + "\n", + "Replace all labels of one axis\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# returns a copy by default\n", + "pop_new_labels = pop.set_labels('sex', ['Men', 'Women'])\n", + "pop_new_labels" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# inplace flag avoids to create a copy\n", + "pop.set_labels('sex', ['M', 'F'], inplace=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Renaming axes\n", + "\n", + "Rename one axis\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.info" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 'rename' returns a copy of the array\n", + "pop2 = pop.rename('sex', 'gender')\n", + "pop2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Rename several axes at once\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# No x. here because sex and nat are keywords and not actual axes\n", + "pop2 = pop.rename(sex='gender', nat='nationality')\n", + "pop2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Reordering axes\n", + "\n", + "Axes can be reordered using ``transpose`` method. \n", + "By default, *transpose* reverse axes, otherwise it permutes the axes according to the list given as argument.\n", + "Axes not mentioned come after those which are mentioned(and keep their relative order).\n", + "Finally, *transpose* returns a copy of the array.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# starting order : age, sex, nat\n", + "pop" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# no argument --> reverse axes\n", + "pop.transpose()\n", + "\n", + "# .T is a shortcut for .transpose()\n", + "pop.T" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# reorder according to list\n", + "pop.transpose('age', 'nat', 'sex')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# axes not mentioned come after those which are mentioned (and keep their relative order)\n", + "pop.transpose('sex')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Aggregates\n", + "\n", + "Calculate the sum along an axis\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop = load_example_data('demography').pop[2016, 'BruCap']\n", + "pop.sum('age')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or along all axes except one by appending `_by` to the aggregation function\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop[90:95].sum_by('age')\n", + "# is equivalent to \n", + "pop[90:95].sum('sex', 'nat')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are many other aggregation functions:\n", + "\n", + "- mean, min, max, median, percentile, var (variance), std (standard\n", + " deviation)\n", + "- labelofmin, labelofmax (label indirect minimum/maxium -- labels where the\n", + " value is minimum/maximum)\n", + "- indexofmin, indexofmax (positional indirect minimum/maxium -- position\n", + " along axis where the value is minimum/maximum)\n", + "- cumsum, cumprod (cumulative sum, cumulative product)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Groups\n", + "\n", + "One can define groups of labels (or indices)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age = pop.axes['age']\n", + "\n", + "# using indices (remember: 20 will not be included)\n", + "teens = age.i[10:20]\n", + "# using labels\n", + "pensioners = age[67:]\n", + "strange = age[[30, 55, 52, 25, 99]]\n", + "\n", + "strange" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or rename them\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# method 'named' returns a new group with the given name\n", + "teens = teens.named('children')\n", + "\n", + "# operator >> is a shortcut for 'named'\n", + "pensioners = pensioners >> 'pensioners'\n", + "\n", + "pensioners " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then, use them in selections\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop[strange]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or aggregations\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.sum(pensioners)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# several groups (here you see the interest of groups renaming)\n", + "pop.sum((teens, pensioners, strange))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# combined with other axes\n", + "pop.sum((teens, pensioners, strange), 'nat')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Arithmetic operations\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# go back to our 6 x 2 x 2 example array\n", + "pop = load_example_data('demography').pop[2016, 'BruCap', 90:95]\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One can do all usual arithmetic operations on an array, it will apply the operation to all elements individually\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# addition\n", + "pop + 200" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# multiplication\n", + "pop * 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# ** means raising to the power (squaring in this case)\n", + "pop ** 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# % means modulo (aka remainder of division)\n", + "pop % 10" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "More interestingly, it also works between two arrays\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# load mortality equivalent array\n", + "mortality = load_example_data('demography').qx[2016, 'BruCap', 90:95] \n", + "\n", + "# compute number of deaths\n", + "death = pop * mortality\n", + "death" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "**Note:** Be careful when mixing different data types.\n", + "You can use the method ``astype`` to change the data type of an array.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# to be sure to get number of deaths as integers\n", + "# one can use .astype() method\n", + "death = (pop * mortality).astype(int)\n", + "death" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But operations between two arrays only works when they have compatible axes (i.e. same labels)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop[90:92] * mortality[93:95]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can override that but at your own risk. \n", + "In that case only the position on the axis is used and not the labels.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop[90:92] * mortality[93:95].drop_labels('age')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Boolean Operations\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop2 = pop.copy()\n", + "pop2['F'] = -pop2['F']\n", + "pop2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# testing for equality is done using == (a single = assigns the value)\n", + "pop == pop2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# testing for inequality\n", + "pop != pop2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# what was our original array like again?\n", + "pop" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# & means (boolean array) and\n", + "(pop >= 500) & (pop <= 1000)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# | means (boolean array) or\n", + "(pop < 500) | (pop > 1000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Arithmetic operations with missing axes\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.sum('age')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# arr has 3 dimensions\n", + "pop.info" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# and arr.sum(age) has two\n", + "pop.sum('age').info" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# you can do operation with missing axes so this works\n", + "pop / pop.sum('age')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Axis order does not matter much (except for output)\n", + "\n", + "You can do operations between arrays having different axes order.\n", + "The axis order of the result is the same as the left array\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# let us change the order of axes\n", + "pop_transposed = pop.T\n", + "pop_transposed" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# mind blowing\n", + "pop_transposed + pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Combining arrays\n", + "\n", + "### Append/Prepend\n", + "\n", + "Append/prepend one element to an axis of an array\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop = load_example_data('demography').pop[2016, 'BruCap', 90:95] \n", + "\n", + "# imagine that you have now acces to the number of non-EU foreigners\n", + "data = [[25, 54], [15, 33], [12, 28], [11, 37], [5, 21], [7, 19]]\n", + "pop_non_eu = LArray(data, pop['FO'].axes)\n", + "\n", + "# you can do something like this\n", + "pop = pop.append(nat, pop_non_eu, 'NEU')\n", + "pop" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# you can also add something at the start of an axis\n", + "pop = pop.prepend('sex', pop.sum('sex'), 'B')\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The value being appended/prepended can have missing (or even extra) axes as long as common axes are compatible\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "aliens = zeros(pop.axes['sex'])\n", + "aliens" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop = pop.append('nat', aliens, 'AL')\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Extend\n", + "\n", + "Extend an array along an axis with another array *with* that axis (but other labels)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "_pop = load_example_data('demography').pop\n", + "pop = _pop[2016, 'BruCap', 90:95] \n", + "pop_next = _pop[2016, 'BruCap', 96:100]\n", + "\n", + "# concatenate along age axis\n", + "pop.extend('age', pop_next)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Stack\n", + "\n", + "Stack several arrays together to create an entirely new dimension\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# imagine you have loaded data for each nationality in different arrays (e.g. loaded from different Excel sheets)\n", + "pop_be, pop_fo = pop['BE'], pop['FO']\n", + "\n", + "# first way to stack them\n", + "nat = Axis('nat=BE,FO,NEU')\n", + "pop = stack([pop_be, pop_fo, pop_non_eu], nat)\n", + "\n", + "# second way\n", + "pop = stack([('BE', pop_be), ('FO', pop_fo), ('NEU', pop_non_eu)], 'nat')\n", + "\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sorting\n", + "\n", + "Sort an axis (alphabetically if labels are strings)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop_sorted = pop.sort_axes('nat')\n", + "pop_sorted" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Give labels which would sort the axis \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop_sorted.labelsofsorted('sex')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Sort according to values \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop_sorted.sort_values((90, 'F'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plotting\n", + "\n", + "Create a plot (last axis define the different curves to draw)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.plot()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# plot total of both sex\n", + "pop.sum('sex').plot()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Interesting methods\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# starting array\n", + "pop = load_example_data('demography').pop[2016, 'BruCap', 100:105]\n", + "pop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### with total\n", + "\n", + "Add totals to one axis\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.with_total('sex', label='B')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Add totals to all axes at once\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# by default label is 'total'\n", + "pop.with_total()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### where\n", + "\n", + "where can be used to apply some computation depending on a condition\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# where(condition, value if true, value if false)\n", + "where(pop < 10, 0, -pop)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### clip\n", + "\n", + "Set all data between a certain range\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# clip(min, max)\n", + "# values below 10 are set to 10 and values above 50 are set to 50\n", + "pop.clip(10, 50)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### divnot0\n", + "\n", + "Replace division by 0 to 0\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop['BE'] / pop['FO']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# divnot0 replaces results of division by 0 by 0. \n", + "# Using it should be done with care though\n", + "# because it can hide a real error in your data.\n", + "pop['BE'].divnot0(pop['FO'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### diff\n", + "\n", + "The ``diff`` method calculates the n-th order discrete difference along a given axis.\n", + "The first order difference is given by out[n+1] = in[n + 1] - in[n] along the given axis.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop = load_example_data('demography').pop[2005:2015, 'BruCap', 50]\n", + "pop" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# calculates 'pop[year+1] - pop[year]'\n", + "pop.diff('time')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# calculates 'pop[year+2] - pop[year]'\n", + "pop.diff('time', d=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ratio\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.ratio('nat')\n", + "\n", + "# which is equivalent to\n", + "pop / pop.sum('nat')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### percents\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# or, if you want the previous ratios in percents\n", + "pop.percent('nat')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### growth\\_rate\n", + "\n", + "using the same principle than `diff` \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.growth_rate('time')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### shift\n", + "\n", + "The ``shift`` method drops first label of an axis and shifts all subsequent labels\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pop.shift('time')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# when shift is applied on an (increasing) time axis, \n", + "# it effectively brings \"past\" data into the future\n", + "pop.shift('time').drop_labels('time') == pop[2005:2014].drop_labels('time')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# this is mostly useful when you want to do operations between the past and now\n", + "# as an example, here is an alternative implementation of the .diff method seen above:\n", + "pop.i[1:] - pop.shift('time')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Misc other interesting functions\n", + "\n", + "There are a lot more interesting functions available:\n", + "\n", + "- round, floor, ceil, trunc,\n", + "- exp, log, log10,\n", + "- sqrt, absolute, nan_to_num, isnan, isinf, inverse,\n", + "- sin, cos, tan, arcsin, arccos, arctan\n", + "- and many many more...\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sessions\n", + "\n", + "You can group several arrays in a Session\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# load several arrays\n", + "arr1, arr2, arr3 = ndtest((3, 3)), ndtest((4, 2)), ndtest((2, 4))\n", + "\n", + "# create and populate a 'session'\n", + "s1 = Session()\n", + "s1.arr1 = arr1\n", + "s1.arr2 = arr2\n", + "s1.arr3 = arr3\n", + "\n", + "s1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "nbsphinx": "hidden" + }, + "outputs": [], + "source": [ + "s2 = s1.copy()\n", + "s3 = s1.copy()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The advantage of sessions is that you can manipulate all of the arrays in them in one shot\n", + "\n", + "```python\n", + "# this saves all the arrays in a single excel file (each array on a different sheet)\n", + "s1.save('test.xlsx')\n", + "\n", + "# this saves all the arrays in a single HDF5 file (which is a very fast format)\n", + "s1.save('test.h5')\n", + "\n", + "# this creates a session out of all arrays in the .h5 file\n", + "s2 = Session('test.h5')\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```python\n", + "# this creates a session out of all arrays in the .xlsx file\n", + "s3 = Session('test.xlsx')\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can compare two sessions\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "s1.equals(s2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# let us introduce a difference (a variant, or a mistake perhaps)\n", + "s2.arr1['a0', 'b1':] = 0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "s1.equals(s2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "s_diff = s1 != s2\n", + "s_diff" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This a bit experimental but can be useful nonetheless (open a graphical interface)\n", + "\n", + "```python\n", + "compare(s1_diff.arr1, s2_diff.arr1)\n", + "```\n" + ] + } + ], + "metadata": { + "celltoolbar": "Edit Metadata", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + }, + "livereveal": { + "autolaunch": false, + "scroll": true + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/larray/__init__.py b/larray/__init__.py index 5b94b09ba..733e08b23 100644 --- a/larray/__init__.py +++ b/larray/__init__.py @@ -1,36 +1,10 @@ from __future__ import absolute_import, division, print_function from larray.core import * -from larray.session import * -from larray.ufuncs import * -# import larray.xw_compat +from larray.inout import * +from larray.util import * +from larray.example import * +from larray.extra import * +from larray.viewer import * -try: - import sys - - from PyQt4 import QtGui, QtCore - - from larray.viewer import view, edit, compare - - orig_hook = sys.displayhook - - def qt_display_hook(value): - if isinstance(value, LArray): - view(value) - else: - orig_hook(value) - - sys.displayhook = qt_display_hook - - # cleanup namespace - del QtGui, QtCore, sys -except ImportError: - def view(*args, **kwargs): - raise Exception('view() is not available because Qt is not installed') - - def edit(*args, **kwargs): - raise Exception('edit() is not available because Qt is not installed') - - def compare(*args, **kwargs): - raise Exception('compare() is not available because Qt is not ' - 'installed') +__version__ = '0.28' diff --git a/larray/combo.py b/larray/combo.py deleted file mode 100644 index 010f8ec98..000000000 --- a/larray/combo.py +++ /dev/null @@ -1,244 +0,0 @@ -from PyQt4 import QtGui, QtCore - - -class StandardItemModelIterator(object): - def __init__(self, model): - self.model = model - self.pos = 0 - - def __next__(self): - if self.pos < self.model.rowCount(): - item = self.model.item(self.pos) - self.pos += 1 - return item - else: - raise StopIteration - next = __next__ - - -class SequenceStandardItemModel(QtGui.QStandardItemModel): - """ - an iterable and indexable StandardItemModel - """ - def __iter__(self): - return StandardItemModelIterator(self) - - def __getitem__(self, key): - if isinstance(key, slice): - start, stop, step = key.start, key.stop, key.step - if start is None: - start = 0 - if stop is None: - stop = self.rowCount() - if step is None: - step = 1 - return [self.item(i) for i in range(start, stop, step)] - else: - if key >= self.rowCount(): - raise IndexError("index %d is out of range" % key) - return self.item(key) - - def __len__(self): - return self.rowCount() - - -class StandardItem(QtGui.QStandardItem): - def __init__(self, value): - super(StandardItem, self).__init__(value) - - def get_checked(self): - return self.checkState() == QtCore.Qt.Checked - - def set_checked(self, value): - if isinstance(value, bool): - qtvalue = (QtCore.Qt.Unchecked, QtCore.Qt.Checked)[value] - else: - qtvalue = QtCore.Qt.PartiallyChecked - self.setCheckState(qtvalue) - checked = property(get_checked, set_checked) - - -class FilterMenu(QtGui.QMenu): - activate = QtCore.pyqtSignal(int) - checkedItemsChanged = QtCore.pyqtSignal(list) - - def __init__(self, parent=None): - super(QtGui.QMenu, self).__init__(parent) - - self._list_view = QtGui.QListView(parent) - self._list_view.setFrameStyle(0) - model = SequenceStandardItemModel() - self._list_view.setModel(model) - self._model = model - self.addItem("(select all)") - model[0].setTristate(True) - - action = QtGui.QWidgetAction(self) - action.setDefaultWidget(self._list_view) - self.addAction(action) - self.installEventFilter(self) - self._list_view.installEventFilter(self) - self._list_view.window().installEventFilter(self) - - model.itemChanged.connect(self.on_model_item_changed) - self._list_view.pressed.connect(self.on_list_view_pressed) - self.activate.connect(self.on_activate) - - def on_list_view_pressed(self, index): - item = self._model.itemFromIndex(index) - # item is None when the button has not been used yet (and this is - # triggered via enter) - if item is not None: - item.checked = not item.checked - - def on_activate(self, row): - target_item = self._model[row] - for item in self._model[1:]: - item.checked = item is target_item - - def on_model_item_changed(self, item): - model = self._model - model.blockSignals(True) - if item.index().row() == 0: - # (un)check first => (un)check others - for other in model[1:]: - other.checked = item.checked - - items_checked = [item for item in model[1:] if item.checked] - num_checked = len(items_checked) - - if num_checked == 0 or num_checked == len(model) - 1: - model[0].checked = bool(num_checked) - elif num_checked == 1: - model[0].checked = 'partial' - else: - model[0].checked = 'partial' - model.blockSignals(False) - is_checked = [i for i, item in enumerate(model[1:]) if item.checked] - self.checkedItemsChanged.emit(is_checked) - - def addItem(self, text): - item = StandardItem(text) - # not editable - item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) - item.checked = True - self._model.appendRow(item) - - def addItems(self, items): - for item in items: - self.addItem(item) - - def eventFilter(self, obj, event): - event_type = event.type() - - if event_type == QtCore.QEvent.KeyRelease: - key = event.key() - - # tab key closes the popup - if obj == self._list_view.window() and key == QtCore.Qt.Key_Tab: - self.hide() - - # return key activates *one* item and closes the popup - # first time the key is sent to the menu, afterwards to - # list_view - elif (obj == self._list_view and - key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return)): - self.activate.emit(self._list_view.currentIndex().row()) - self.hide() - return True - - return False - - -class FilterComboBox(QtGui.QToolButton): - checkedItemsChanged = QtCore.pyqtSignal(list) - - def __init__(self, parent=None): - super(FilterComboBox, self).__init__(parent) - self.setText("(no filter)") - # QtGui.QToolButton.InstantPopup would be slightly less work (the - # whole button works by default, instead of only the arrow) but it is - # uglier - self.setPopupMode(QtGui.QToolButton.MenuButtonPopup) - - menu = FilterMenu(self) - self.setMenu(menu) - self._menu = menu - menu.checkedItemsChanged.connect(self.on_checked_items_changed) - self.installEventFilter(self) - - def on_checked_items_changed(self, indices_checked): - num_checked = len(indices_checked) - model = self._menu._model - if num_checked == 0 or num_checked == len(model) - 1: - self.setText("(no filter)") - elif num_checked == 1: - self.setText(model[indices_checked[0] + 1].text()) - else: - self.setText("multi") - self.checkedItemsChanged.emit(indices_checked) - - def addItem(self, text): - self._menu.addItem(text) - - def addItems(self, items): - self._menu.addItems(items) - - def eventFilter(self, obj, event): - event_type = event.type() - - # this is not enabled because it causes all kind of troubles - # if event_type == QtCore.QEvent.KeyPress: - # key = event.key() - # - # # allow opening the popup via enter/return - # if (obj == self and - # key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter)): - # self.showMenu() - # return True - - if event_type == QtCore.QEvent.KeyRelease: - key = event.key() - - # allow opening the popup with up/down - if (obj == self and - key in (QtCore.Qt.Key_Up, QtCore.Qt.Key_Down, - QtCore.Qt.Key_Space)): - self.showMenu() - return True - - # return key activates *one* item and closes the popup - # first time the key is sent to self, afterwards to list_view - elif (obj == self and - key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return)): - self._menu.activate.emit(self._list_view.currentIndex().row()) - self._menu.hide() - return True - - if event_type == QtCore.QEvent.MouseButtonRelease: - # clicking anywhere (not just arrow) on the button shows the popup - if obj == self: - self.showMenu() - - return False - - -if __name__ == '__main__': - import sys - - class TestDialog(QtGui.QDialog): - def __init__(self): - super(QtGui.QDialog, self).__init__() - layout = QtGui.QVBoxLayout() - self.setLayout(layout) - - combo = FilterComboBox(self) - for i in range(20): - combo.addItem('Item %s' % i) - layout.addWidget(combo) - - app = QtGui.QApplication(sys.argv) - dialog = TestDialog() - dialog.resize(200, 200) - dialog.show() - sys.exit(app.exec_()) diff --git a/larray/core.py b/larray/core.py deleted file mode 100644 index 5ac07a602..000000000 --- a/larray/core.py +++ /dev/null @@ -1,5807 +0,0 @@ -# -*- coding: utf8 -*- -from __future__ import absolute_import, division, print_function - -__version__ = "0.12" - -__all__ = [ - 'LArray', 'Axis', 'AxisCollection', 'LGroup', - 'union', 'stack', - 'read_csv', 'read_eurostat', 'read_excel', 'read_hdf', 'read_tsv', - 'read_sas', - 'x', - 'zeros', 'zeros_like', 'ones', 'ones_like', 'empty', 'empty_like', - 'full', 'full_like', 'create_sequential', 'ndrange', - 'identity', 'diag', 'eye', - 'larray_equal', - 'all', 'any', 'sum', 'prod', 'cumsum', 'cumprod', 'min', 'max', 'mean', - 'ptp', 'var', 'std', 'median', 'percentile', - '__version__' -] - -""" -Matrix class - -a(sex, age) -age_limit(sex) - -step 1: - -a[age > age_limit] -a[age + clength < age_limit] -b = a * (age > age_limit) - -step 2: - -a[x.age > age_limit] -# this is also possible ("x.age > age_limit" return an Expr, expr is evaluated -# during the binop (axes ref replace by real axe) -b = a * (x.age > age_limit) - -============== -in general: -1) match axes by Axis object => No axis.id because we need to be able to share - the same axis in several collections/arrays. - => this is slightly annoying for Group.__repr__ which uses axis.id - => we cannot have twice the same axis object in a collection - (we can have the same name twice though) -2) match axes by name if any, by position otherwise -3) match axes by position -""" -# TODO -# * axes with no name should display as (or even have their name assigned to?) -# their position. Assigning does not work because after aggregating axis 0, -# we get the first axis named "1" which is a no-go. -# it would be much easier to have a .id attribute/property on axis with -# either the name or position in it, but this requires that axes know about -# their AxisCollection. id might not be defined when axis is not attached -# to a Collection - -# * add check there is no duplicate label in axes! - -# * for NDGroups, we have two options: cross product or intersection. -# Technically, this is easy, we just need to store a boolean and in getitem -# act accordingly (use ix_ or not), but what is the best API for users? -# a different class or a flag? In fact, the same question applies to -# positional vs label (in total, we got 4 different possibilities). - -# ? how do you combine a cross-product group with an intersection group? -# a[cpgroup, igroup] -# -> no problem if they are on different dimensions: the igroup -# dimension(s) are collapsed into one, pgroup dimension(s) stay. -# The index need to be constructed carefully, but it can be done. See -# np_indexing.py -# -> if they are on the same dimensions, we have two options: -# * apply one then the other (left to right) -# * fail <-- I think this is safer at least to implement. One after the -# other can still be achieved by a[pgroup][igroup] - -# API for ND groups (my example is mixing label with positional): - -# union (bands): x.axis1[5:10] | x.axis2.i[3:4] -# intersection/cross/default: x.axis1[5:10] & x.axis2.i[3:4] -# points: x.axis1[5:10] ^ x.axis2.i[1:6] -# ----> this prevents symetric difference. this is little used but... -# ----> Points(x.axis[5:10], x.axis2.i[1:6]) - -# this is very nice and would have orderedset-like semantics - -# it does not seem to conflict with the axis methods (even though that might be -# confusing): - -# x.axis1 | x.axis2 would have a very different meaning than -# x.axis1[:] | x.axis2[:] - -# Note that cross sections is the default and it is useless to introduce -# another API **except to give a name**, so the & syntax is useless unless -# we allow naming groups after the fact - -# => NDGroup((x.axis1[5:10], x.axis2.i[2.5]), 'exports') -# => Group((x.axis1[5:10], x.axis2.i[2.5]), 'exports') -# => (x.axis1[5:10] | x.axis2.i[2.5]).named('exports') - -# generalizing "named" and suppressing .group seems like a good idea! -# => x.axis1.group([5, 7, 10], name='brussels') -# => x.axis1[[5, 7, 10]].named('brussels') - -# http://xarray.pydata.org/en/stable/indexing.html#pointwise-indexing -# http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.lookup.html#pandas.DataFrame.lookup - -# I think I would go for -# ARRAY.points[dim0_labels, ..., dimX_labels] -# and -# ARRAY.ipoints[dim0_indices, ..., dimX_indices] -# so that we can have a symmetrical API for get and set. - -# I wonder if, for axes subscripting, I could not allow tuples as sequences, -# which would make it a bit nicer: -# x.axis1[5, 7, 10].named('brussels') -# instead of -# x.axis1[[5, 7, 10]].named('brussels') -# since axes are always 1D, this is not a direct problem. However the -# question is whether this would lead to an inconsistent API/confuse users -# because they would still have to write the brackets when no axis is present -# a[[5, 7, 9]] -# a[x.axis1[5, 7, 9]] -# in practice, this syntax is little used anyway - -# also think about G (for group) or L (for label): - -# a[G[5:10]] -# a[G[5, 7, 9]] - -# a[G[5:10].named('brussels')] -# a[G[5, 7, 9].named('brussels')] - -# this is ugly -# a[G[5, 7, 9].axed('age')] -# a[G[5, 7, 9].x('age')] - -# nice for the simple cases, but cannot target anonymous axes G[0] or axes with -# strange names G['strange axis']. would both try to find labels on axes, not -# the axes themselves. - -# a[G.age[5, 7, 9]] -# a[G.geo[5, 7, 9].named('brussels')] - -# a[x.age[G[5, 7, 9]]] -# a[x.age[G[5, 7, 9].named('brussels')]] - -# a[G.get('strange axis')[5, 7, 9].named('Brussels')] - -# a[x.age[5, 7, 9]] - -# positional groups *without axis* (G.i, P[], or I[]) does not make much sense, -# because it will matches all axes, but might be useful as an intermediate -# construct: - -# g = G.i[2, 5, 7] -# g2 = X.age[g] - -# positional groups *with axis* can be useful as a shorter alternative (but -# not worth it IMO, unless the whole API is more consistent for users): - -# g = P.age[2, 5, 7] -# instead of -# g = X.age.i[2, 5, 7] - -# we might want to also consider multi-dimensional groups: -# using K (for key) or I (for indexer) or G (without axis obviously): - -# g = G[2:7, 'M', ['P01', 'P05']] - -# but it might be better to allow multiple slices from the same dimension in -# the same group: - -# g = G.age[:9, 10:14, 15:25] - -# it seems nifty, but that changes the semantic of a group (we would need -# multiple names???) - -# in that cases, having NDG to create N dimensional groups might be a good idea - -# g = NDG[2:7, 'M', ['P01', 'P05']] - -# we also need the best possible syntax to handle, "arbitrary" resampling - -# pure_min_w1_comp_agg = zeros(result_axes) -# pure_min_w1_comp_agg[x.LBMosesXLS[1]] = pure_min_w1_comp.sum(x.clength[1:15]) -# pure_min_w1_comp_agg[x.LBMosesXLS[2]] = pure_min_w1_comp.sum(x.clength[16:25]) -# pure_min_w1_comp_agg[x.LBMosesXLS[3]] = pure_min_w1_comp.sum(x.clength[26:30]) -# pure_min_w1_comp_agg[x.LBMosesXLS[4]] = pure_min_w1_comp.sum(x.clength[31:35]) -# pure_min_w1_comp_agg[x.LBMosesXLS[5]] = pure_min_w1_comp.sum(x.clength[36:40]) -# pure_min_w1_comp_agg[x.LBMosesXLS[6]] = pure_min_w1_comp.sum(x.clength[41:50]) -# -# clength_groups = (x.clength[1:15], x.clength[16:25], x.clength[26:30], -# x.clength[31:35], x.clength[36:40], x.clength[41:50]) -# pure_min_w1_comp_agg2 = pure_min_w1_comp.sum(clength_groups).rename( -# x.clength, x.LBMosesXLS) -# -# clength_groups = x.clength[1:15, 16:25, 26:30, 31:35, 36:40, 41:50] -# pure_min_w1_comp_agg2 = pure_min_w1_comp.sum(clength_groups) -# -# clength_groups = G[1:15, 16:25, 26:30, 31:35, 36:40, 41:50] -# pure_min_w1_comp_agg2 = pure_min_w1_comp.sum(clength_groups) \ -# .replace(x.clength, LBMosesXLS) -# XXX: what if I want to sum on all the slices (as if it was a single slice) -# clength_groups = G[1:15] | G[16:25] | G[26:30] | G[31:35] | G[36:40] | G[41:50] -# OR -# G.clength.union[1:15, 16:25, 26:30, 31:35, 36:40, 41:50] -# -# pure_min_w1_comp_agg2 = pure_min_w1_comp.sum(clength_groups) \ - -# I would also like to have a nice syntax for assigning (multiple) values to -# multiple slices (example courtesy of MOSES) - -# clength = Axis('clength', range(1, 51)) -# year = Axis('year', range(2010, 2050)) -# result_axes = AxisCollection([ -# clength, -# year -# ]) -# -# multip_mat_min = zeros([clength, year]) -# multip_mat_min[x.clength[1:15], x.year[first_year_p:2024]] = 7 / 7 -# multip_mat_min[x.clength[16:25], x.year[first_year_p:2024]] = 20 / 20 -# multip_mat_min[x.clength[26:30], x.year[first_year_p:2024]] = 27 / 27 -# multip_mat_min[x.clength[31:35], x.year[first_year_p:2024]] = 32 / 32 -# multip_mat_min[x.clength[36:40], x.year[first_year_p:2024]] = 37 / 37 -# multip_mat_min[x.clength[41:50], x.year[first_year_p:2024]] = 42 / 42 -# multip_mat_min[x.clength[1:15], x.year[2025:2029]] = 8 / 7 -# multip_mat_min[x.clength[16:25], x.year[2025:2029]] = 21 / 20 -# multip_mat_min[x.clength[26:30], x.year[2025:2029]] = 28 / 27 -# multip_mat_min[x.clength[31:35], x.year[2025:2029]] = 33 / 32 -# multip_mat_min[x.clength[36:40], x.year[2025:2029]] = 38 / 37 -# multip_mat_min[x.clength[41:50], x.year[2025:2029]] = 43 / 42 -# multip_mat_min[x.clength[1:15], x.year[2030:]] = 9 / 7 -# multip_mat_min[x.clength[16:25], x.year[2030:]] = 22 / 20 -# multip_mat_min[x.clength[26:30], x.year[2030:]] = 29 / 27 -# multip_mat_min[x.clength[31:35], x.year[2030:]] = 34 / 32 -# multip_mat_min[x.clength[36:40], x.year[2030:]] = 39 / 37 -# multip_mat_min[x.clength[41:50], x.year[2030:]] = 44 / 42 -# -# # already possible -# m = zeros(clength) -# m[x.clength[1:15]] = 7 -# m[x.clength[16:25]] = 20 -# m[x.clength[26:30]] = 27 -# m[x.clength[31:35]] = 32 -# m[x.clength[36:40]] = 37 -# m[x.clength[41:50]] = 42 -# multip_mat_min = zeros([clength, year]) -# multip_mat_min[x.year[:2024]] = m / m -# multip_mat_min[x.year[2025:2029]] = (m + 1) / m -# multip_mat_min[x.year[2030:]] = (m + 2) / m - -# TODO: it would be nice to be able to say: -# m[x.clength[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]] = [7, 20, 27, 32, 37, 42] -# but I am unsure it is possible/unambiguous - -# this kind of pattern is not supported by numpy -# in numpy, you can assign multiple slices to the SAME value (not one value per -# slice, using m[np._r[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]] = 7, but -# this actually construct a single array of indices, and ultimately, -# it is much slower than repeatedly doing m[slice()] = value -# %timeit j = np.r_[tuple(slice(i, i+5) for i in range(0, 1000, 10))]; a[j] = 9 -# 1000 loops, best of 3: 307 µs per loop -# %timeit for i in range(0, 1000, 10): a[i:i+5] = i -# 10000 loops, best of 3: 45.9 µs per loop - -# m[x.clength[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]] = \ -# [7, 20, 27, 32, 37, 42] -# multip_mat_min[x.year[:2024, 2025:2029, 2030:]] = [m / m, (m + 1) / m, -# (m + 2) / m] - -# for the multi-value case to work I would probably have to make -# m[x.clength[1:15, 16:25, 26:30, 31:35, 36:40, 41:50]] -# return multiple arrays (as a tuple of arrays or an array of arrays) -# with pandas/MI support, we could just return an array with -# a (second) clength axis - -# * when trying to aggregate on an non existing Axis (using x.blabla), -# the error message is awful - -# ? implement named groups in strings -# eg "vla=A01,A02;bru=A21;wal=A55,A56" - -# ? implement multi group in one axis getitem: -# lipro['P01,P02;P05'] <=> (lipro.group('P01,P02'), lipro.group('P05')) -# <=> (lipro['P01,P02'], lipro['P05']) - -# discuss VG with Geert: -# I do not "expand" key (eg :) upon group creation for perf reason -# VG[:] is much faster than [A01,A02,...,A99] -# I could make that all "contiguous" ranges are conv to slices (return views) -# but that might introduce confusing differences if they update/setitem their -# arrays - -# * implement keepaxes=True for _group_aggregate instead of/in addition to -# group tuples - -# ? implement newaxis - -# * split unit tests - -# * reindex array (ie make it conform to another index, eg of another -# array). This can be used both for doing operations (add, divide, ...) -# involving arrays with incompatible axes and to (manually) reorder one axis -# labels - -# * test to_csv: does it consume too much mem? -# ---> test pandas (one dimension horizontally) - -# * add labels in LGroups.__str__ - -# ? allow naming "one-shot" groups? e.g: -# regsum = bel.sum(lipro='P01,P02 = P01P02; : = all') - -# * docstring for all methods - -# * IO functions: csv/hdf/excel?/...? -# >> needs discussion of the formats (users involved in the discussion?) -# + check pandas dialects -# * plotting (see plot.py) -# >> check pandas API -# * implement more Axis functions: -# - arithmetic operations: + - -# - regexp functions: geo.group('A3*') -# - sequence?: geo.seq('A31', 'A38') -# this NOT exactly equivalent to geo['A31':'A38'] because the later -# can contain A22 if it is defined between A31 and A38 -# * re-implement row_totals/col_totals? or what do we do with them? -# * all the other TODO/XXX in the code -# * time specific API so that we know if we go for a subclass or not -# * data alignment in arithmetic methods -# * test structured arrays -# * review all method & argument names -# ? move "utils" to its own project (so that it is not duplicated between -# larray and liam2) -# OR -# include utils only in larray project and make larray a dependency of liam2 -# (and potentially rename it to reflect the broader scope) -# ? move "excelcom" to its own project (so that it is not duplicated between -# potential projects using it) - -import csv -import os -from itertools import product, chain, groupby, islice -import sys -try: - import builtins -except ImportError: - import __builtin__ as builtins - -import numpy as np -import pandas as pd - -from larray.utils import (table2str, unique, csv_open, unzip, long, - decode, basestring, izip, rproduct, ReprString, - duplicates, array_lookup2, skip_comment_cells, - strip_rows, PY3) -try: - import xlwings as xw -except ImportError: - xw = None - -try: - from numpy import nanprod as np_nanprod -except ImportError: - np_nanprod = None - -# TODO: return a generator, not a list -def srange(*args): - return list(map(str, range(*args))) - - -def range_to_slice(seq, length=None): - """ - seq is a sequence-like (list, tuple or ndarray) of integers - returns a slice if possible (including for sequences of 1 element) - otherwise returns the input sequence itself - - >>> range_to_slice([3, 4, 5]) - slice(3, 6, None) - >>> range_to_slice([3, 5, 7]) - slice(3, 9, 2) - >>> range_to_slice([-3, -2]) - slice(-3, -1, None) - >>> range_to_slice([-1, -2]) - slice(-1, -3, -1) - >>> range_to_slice([2, 1]) - slice(2, 0, -1) - >>> range_to_slice([1, 0], 4) - slice(-3, -5, -1) - >>> range_to_slice([1, 0]) - [1, 0] - >>> range_to_slice([1]) - slice(1, 2, None) - >>> range_to_slice([]) - [] - """ - if len(seq) < 1: - return seq - start = seq[0] - if len(seq) == 1: - return slice(start, start + 1) - second = seq[1] - step = second - start - prev_value = second - for value in seq[2:]: - if value != prev_value + step: - return seq - prev_value = value - stop = prev_value + step - if prev_value == 0 and step < 0: - if length is None: - return seq - else: - stop -= length - start -= length - if step == 1: - step = None - return slice(start, stop, step) - - -def slice_to_str(key, use_repr=False): - """ - converts a slice to a string - >>> slice_to_str(slice(None)) - ':' - >>> slice_to_str(slice(24)) - ':24' - >>> slice_to_str(slice(25, None)) - '25:' - >>> slice_to_str(slice(5, 10)) - '5:10' - >>> slice_to_str(slice(None, 5, 2)) - ':5:2' - """ - # examples of result: ":24" "25:" ":" ":5:2" - func = repr if use_repr else str - start = func(key.start) if key.start is not None else '' - stop = func(key.stop) if key.stop is not None else '' - step = (":" + func(key.step)) if key.step is not None else '' - return '%s:%s%s' % (start, stop, step) - - -def slice_str_to_range(s): - """ - converts a slice string to a list of (string) values. The end point is - included. - >>> slice_str_to_range(':3') - ['0', '1', '2', '3'] - >>> slice_str_to_range('2:5') - ['2', '3', '4', '5'] - >>> slice_str_to_range('2:6:2') - ['2', '4', '6'] - """ - numcolons = s.count(':') - assert 1 <= numcolons <= 2 - fullstr = s + ':1' if numcolons == 1 else s - start, stop, step = [int(a) if a else None for a in fullstr.split(':')] - if start is None: - start = 0 - if stop is None: - raise ValueError("no stop bound provided in range: %r" % s) - stop += 1 - return srange(start, stop, step) - - -def to_string(v): - """ - converts a (group of) tick(s) to a string - """ - if isinstance(v, slice): - return slice_to_str(v) - elif isinstance(v, (tuple, list)): - if len(v) == 1: - return str(v) + ',' - else: - return ','.join(str(k) for k in v) - else: - return str(v) - - -def to_tick(e): - """ - make it hashable, and acceptable as an ndarray element - scalar & VG -> not modified - slice -> 'start:stop' - list|tuple -> 'v1,v2,v3' - other -> str(v) - """ - # the fact that an "aggregated tick" is passed as a LGroup or as a - # string should be as irrelevant as possible. The thing is that we cannot - # (currently) use the more elegant to_tick(e.key) that means the - # LGroup is not available in Axis.__init__ after to_ticks, and we - # need it to update the mapping if it was named. Effectively, - # this creates two entries in the mapping for a single tick. Besides, - # I like having the LGroup as the tick, as it provides extra info as - # to where it comes from. - if np.isscalar(e) or isinstance(e, LGroup): - return e - else: - return to_string(e) - - -def to_ticks(s): - """ - Makes a (list of) value(s) usable as the collection of labels for an - Axis (ie hashable). Strip strings, split them on ',' and translate - "range strings" to list of values **including the end point** ! - This function is only used in Axis.__init__ and union(). - - >>> to_ticks('H , F') - ['H', 'F'] - - # XXX: we might want to return real int instead, because if we ever - # want to have more complex queries, such as: - # arr.filter(age > 10 and age < 20) - # this would break for string values (because '10' < '2') - >>> to_ticks(':3') - ['0', '1', '2', '3'] - """ - if isinstance(s, Group): - # a single LGroup used for all ticks of an Axis - raise NotImplementedError("not sure what to do with it yet") - elif isinstance(s, pd.Index): - return s.values - elif isinstance(s, np.ndarray): - # we assume it has already been translated - # XXX: Is it a safe assumption? - return s - elif isinstance(s, (list, tuple)): - return [to_tick(e) for e in s] - elif sys.version >= '3' and isinstance(s, range): - return list(s) - else: - assert isinstance(s, basestring), "%s is not a supported type for " \ - "ticks" % type(s) - - if ':' in s: - return slice_str_to_range(s) - else: - return [v.strip() for v in s.split(',')] - - -def to_key(v): - """ - Converts a value to a key usable for indexing (slice object, list of values, - ...). Strings are split on ',' and stripped. Colons (:) are interpreted - as slices. "int strings" are not converted to int. - >>> to_key('a:c') - slice('a', 'c', None) - >>> to_key('a, b,c ,') - ['a', 'b', 'c'] - >>> to_key('a,') - ['a'] - >>> to_key(' a ') - 'a' - >>> to_key(10) - 10 - """ - if isinstance(v, tuple): - return list(v) - elif isinstance(v, Group): - return v.__class__(to_key(v.key), v.name, v.axis) - elif v is Ellipsis or isinstance(v, (int, list, slice, LArray)): - return v - elif isinstance(v, basestring): - numcolons = v.count(':') - if numcolons: - assert numcolons <= 2 - # can be of len 2 or 3 (if step is provided) - bounds = [a if a else None for a in v.split(':')] - return slice(*bounds) - else: - if ',' in v: - # strip extremity commas to avoid empty string keys - v = v.strip(',') - return [v.strip() for v in v.split(',')] - else: - return v.strip() - else: - raise TypeError("%s has an invalid type (%s) for a key" - % (v, type(v).__name__)) - - -def to_keys(value): - """ - converts a (collection of) group(s) to a structure usable for indexing. - 'label' or ['l1', 'l2'] or [['l1', 'l2'], ['l3']] - - It is only used for .sum(axis=xxx) - >>> to_keys('P01,P02') # <-- one group => collapse dimension - ['P01', 'P02'] - >>> to_keys(('P01,P02',)) # <-- do not collapse dimension - (['P01', 'P02'],) - >>> to_keys('P01;P02;:') - ('P01', 'P02', slice(None, None, None)) - - # >>> to_keys('P01,P02,:') # <-- INVALID ! - # it should have an explicit failure - - # we allow this, even though it is a dubious syntax - >>> to_keys(('P01', 'P02', ':')) - ('P01', 'P02', slice(None, None, None)) - - # it is better to use explicit groups - >>> to_keys(('P01,', 'P02,', ':')) - (['P01'], ['P02'], slice(None, None, None)) - - # or even the ugly duck... - >>> to_keys((('P01',), ('P02',), ':')) - (['P01'], ['P02'], slice(None, None, None)) - """ - if isinstance(value, basestring): - if ';' in value: - return tuple([to_key(group) for group in value.split(';')]) - else: - return to_key(value) - elif isinstance(value, tuple): - return tuple([to_key(group) for group in value]) - else: - return to_key(value) - - -def union(*args): - # TODO: add support for LGroup and lists - """ - returns the union of several "value strings" as a list - """ - if args: - return list(unique(chain(*(to_ticks(arg) for arg in args)))) - else: - return [] - - -def larray_equal(first, other): - if not isinstance(first, LArray) or not isinstance(other, LArray): - return False - return (first.axes == other.axes and - np.array_equal(np.asarray(first), np.asarray(other))) - - -def isnoneslice(v): - return isinstance(v, slice) and v == slice(None) - -def seq_summary(seq, num=3, func=repr): - def shorten(l): - return l if len(l) <= 2 * num else l[:num] + ['...'] + list(l[-num:]) - - return ' '.join(shorten([func(l) for l in seq])) - - -class PGroupMaker(object): - def __init__(self, axis): - assert isinstance(axis, Axis) - self.axis = axis - - def __getitem__(self, key): - return PGroup(key, None, self.axis) - - -class Axis(object): - # ticks instead of labels? - # XXX: make name and labels optional? - def __init__(self, name, labels): - """ - labels should be an array-like (convertible to an ndarray) - or a int (the size of the Axis) - """ - if isinstance(name, Axis): - name = name.name - self.name = name - self._labels = None - self.__mapping = None - self.__sorted_keys = None - self.__sorted_values = None - self._length = None - self._iswildcard = False - self.labels = labels - - @property - def _mapping(self): - mapping = self.__mapping - if mapping is None: - labels = self._labels - # TODO: this would be more efficient for wildcard axes but - # does not work in all cases - # mapping = labels - mapping = {label: i for i, label in enumerate(labels)} - if not self._iswildcard: - # we have no choice but to do that! - # otherwise we could not make geo['Brussels'] work efficiently - # (we could have to traverse the whole mapping checking for each - # name, which is not an option) - # TODO: only do this if labels.dtype is object, or add "contains_lgroup" - # flag in above code (if any(...)) - # 0.179 - mapping.update({label.name: i for i, label in enumerate(labels) - if isinstance(label, Group)}) - self.__mapping = mapping - return mapping - - def _update_key_values(self): - mapping = self._mapping - if mapping: - sorted_keys, sorted_values = tuple(zip(*sorted(mapping.items()))) - else: - sorted_keys, sorted_values = (), () - keys, values = np.array(sorted_keys), np.array(sorted_values) - self.__sorted_keys = keys - self.__sorted_values = values - return keys, values - - @property - def _sorted_keys(self): - if self.__sorted_keys is None: - keys, _ = self._update_key_values() - return self.__sorted_keys - - @property - def _sorted_values(self): - values = self.__sorted_values - if values is None: - _, values = self._update_key_values() - return values - - @property - def i(self): - return PGroupMaker(self) - - @property - def labels(self): - return self._labels - - @labels.setter - def labels(self, labels): - if labels is None: - raise TypeError("labels should be ndarray or int") - if isinstance(labels, (int, long)): - length = labels - labels = np.arange(length) - iswildcard = True - else: - # TODO: move this to to_ticks???? - # we convert to an ndarray to save memory for scalar ticks (for - # LGroup ticks, it does not make a difference since a list of VG - # and an ndarray of VG are both arrays of pointers) - ticks = to_ticks(labels) - object_array = isinstance(ticks, np.ndarray) and \ - ticks.dtype.type == np.object_ - can_have_groups = object_array or isinstance(ticks, (tuple, list)) - if can_have_groups and any( - isinstance(tick, LGroup) for tick in ticks): - # avoid getting a 2d array if all LGroup have the same length - labels = np.empty(len(ticks), dtype=object) - labels[:] = ticks - else: - labels = np.asarray(ticks) - length = len(labels) - iswildcard = False - - self._length = length - self._labels = labels - self._iswildcard = iswildcard - - @property - def iswildcard(self): - return self._iswildcard - - # XXX: not sure I should offer an *args version - def group(self, *args, **kwargs): - """ - key is label-based (slice and fancy indexing are supported) - returns a LGroup usable in .sum or .filter - """ - name = kwargs.pop('name', None) - if kwargs: - raise ValueError("invalid keyword argument(s): %s" - % list(kwargs.keys())) - key = args[0] if len(args) == 1 else args - if isinstance(key, LGroup): - # XXX: I am not sure this test even makes sense. eg if we have two - # axes arr_from and arr_to, we might want to reuse groups - if key.axis != self.name: - raise ValueError("cannot subset an axis with a LGroup of " - "an incompatible axis") - # FIXME: we should respect the given name (overrides key.name) - return key - return LGroup(key, name, self) - - def all(self, name=None): - return self.group(slice(None), name=name if name is not None else "all") - - def subaxis(self, key, name=None): - """ - returns an Axis for a sub-array - key is index-based (slice and fancy indexing are supported) - - if key is a None slice and name is None, returns the original Axis - """ - if (name is None and isinstance(key, slice) and - key.start is None and key.stop is None and key.step is None): - return self - # we must NOT modify the axis name, even though this creates a new axis - # that is independent from the original one because the original - # name is probably what users will want to use to filter - if name is None: - name = self.name - if isinstance(key, LArray): - return tuple(key.axes) - return Axis(name, self.labels[key]) - - def iscompatible(self, other): - if not isinstance(other, Axis) or self.name != other.name: - return False - # wildcard axes of length 1 match with anything - if self.iswildcard: - return len(self) == 1 or len(self) == len(other) - elif other.iswildcard: - return len(other) == 1 or len(self) == len(other) - else: - return np.array_equal(self.labels, other.labels) - - def equals(self, other): - return (isinstance(other, Axis) and self.name == other.name and - self.iswildcard == other.iswildcard and - np.array_equal(self.labels, other.labels)) - - def __len__(self): - return self._length - - def __iter__(self): - return iter(self.labels) - - def __getitem__(self, key): - """ - key is a label-based key (slice and fancy indexing are supported) - """ - return self.group(key) - - def __contains__(self, key): - return to_tick(key) in self._mapping - - def __hash__(self): - return id(self) - - def _is_key_type_compatible(self, key): - label_kind = self.labels.dtype.kind - key_kind = np.dtype(type(key)).kind - str_key = key_kind in ('S', 'U') - # on Python2, ascii-only unicode string can match byte strings, - # so we shouldn't be more picky here than dict hashing - allowed_str_kinds = ('O',) if PY3 else ('O', 'S', 'U') - str_match = str_key and label_kind in allowed_str_kinds - return key_kind == label_kind or str_match - - def translate(self, key, bool_passthrough=True): - """ - translates a label key to its numerical index counterpart - fancy index with boolean vectors are passed through unmodified - """ - mapping = self._mapping - - # first, try the key as-is, so that we can target elements in aggregated - # arrays (those are either strings containing comas or LGroups) - try: - # avoid matching 0 against False or 0.0 - if self._is_key_type_compatible(key): - return mapping[key] - # we must catch TypeError because key might not be hashable (eg slice) - # IndexError is for when mapping is an ndarray - except (KeyError, TypeError, IndexError): - pass - - if isinstance(key, PGroup): - return key.key - - if isinstance(key, LGroup): - # at this point we do not care about the axis nor the name - key = key.key - - if isinstance(key, basestring): - # transform "specially formatted strings" for slices and lists to - # actual objects - key = to_key(key) - - if isinstance(key, slice): - start = mapping[key.start] if key.start is not None else None - # stop is inclusive in the input key and exclusive in the output ! - stop = mapping[key.stop] + 1 if key.stop is not None else None - return slice(start, stop, key.step) - # XXX: bool LArray do not pass through??? - elif isinstance(key, np.ndarray) and key.dtype.kind is 'b' and \ - bool_passthrough: - return key - elif isinstance(key, (tuple, list)): - # TODO: the result should be cached - # Note that this is faster than array_lookup(np.array(key), mapping) - res = np.empty(len(key), int) - for i, label in enumerate(key): - res[i] = mapping[label] - return res - elif isinstance(key, np.ndarray): - # handle fancy indexing with a ndarray of labels - # TODO: the result should be cached - # TODO: benchmark this against the tuple/list version above when - # mapping is large - # array_lookup is O(len(key) * log(len(mapping))) - # vs - # tuple/list version is O(len(key)) (dict.getitem is O(1)) - # XXX: we might want to special case dtype bool, because in that - # case the mapping will in most case be {False: 0, True: 1} or - # {False: 1, True: 0} and in those case key.astype(int) and - # (~key).astype(int) are MUCH faster - # see C:\Users\gdm\devel\lookup_methods.py and - # C:\Users\gdm\Desktop\lookup_methods.html - return array_lookup2(key, self._sorted_keys, self._sorted_values) - elif isinstance(key, LArray): - pkey = array_lookup2(key.data, self._sorted_keys, self._sorted_values) - return LArray(pkey, key.axes) - else: - # the first mapping[key] above will cover most cases. This code - # path is only used if the key was given in "non normalized form" - assert np.isscalar(key), "%s (%s) is not scalar" % (key, type(key)) - # key is scalar (integer, float, string, ...) - if np.dtype(type(key)).kind == self.labels.dtype.kind: - return mapping[key] - else: - # print("diff dtype", ) - raise KeyError(key) - - # FIXME: remove id - @property - def id(self): - if self.name is not None: - return self.name - else: - raise ValueError('Axis has no name, so no id') - - def __str__(self): - name = str(self.name) if self.name is not None else '{?}' - return (name + '*') if self.iswildcard else name - - def __repr__(self): - labels = len(self) if self.iswildcard else list(self.labels) - return 'Axis(%r, %r)' % (self.name, labels) - - def labels_summary(self): - def repr_on_strings(v): - if isinstance(v, str): - return repr(v) - else: - return str(v) - return seq_summary(self.labels, func=repr_on_strings) - - # method factory - def _binop(opname): - fullname = '__%s__' % opname - - def opmethod(self, other): - self_array = labels_array(self) - if isinstance(other, Axis): - other = labels_array(other) - return getattr(self_array, fullname)(other) - opmethod.__name__ = fullname - return opmethod - - __lt__ = _binop('lt') - __le__ = _binop('le') - __eq__ = _binop('eq') - __ne__ = _binop('ne') - __gt__ = _binop('gt') - __ge__ = _binop('ge') - __add__ = _binop('add') - __radd__ = _binop('radd') - __sub__ = _binop('sub') - __rsub__ = _binop('rsub') - __mul__ = _binop('mul') - __rmul__ = _binop('rmul') - if sys.version < '3': - __div__ = _binop('div') - __rdiv__ = _binop('rdiv') - __truediv__ = _binop('truediv') - __rtruediv__ = _binop('rtruediv') - __floordiv__ = _binop('floordiv') - __rfloordiv__ = _binop('rfloordiv') - __mod__ = _binop('mod') - __rmod__ = _binop('rmod') - __divmod__ = _binop('divmod') - __rdivmod__ = _binop('rdivmod') - __pow__ = _binop('pow') - __rpow__ = _binop('rpow') - __lshift__ = _binop('lshift') - __rlshift__ = _binop('rlshift') - __rshift__ = _binop('rshift') - __rrshift__ = _binop('rrshift') - __and__ = _binop('and') - __rand__ = _binop('rand') - __xor__ = _binop('xor') - __rxor__ = _binop('rxor') - __or__ = _binop('or') - __ror__ = _binop('ror') - __matmul__ = _binop('matmul') - - def copy(self): - new_axis = Axis(self.name, []) - # XXX: I wonder if we should make a copy of the labels + mapping. - # There should at least be an option. - new_axis._labels = self._labels - new_axis.__mapping = self.__mapping - new_axis._length = self._length - new_axis._iswildcard = self._iswildcard - new_axis.__sorted_keys = self.__sorted_keys - new_axis.__sorted_values = self.__sorted_values - return new_axis - - def rename(self, name): - """Renames the axis. - - Parameters - ---------- - newname : str - the new name for the axis. - - Returns - ------- - Axis - a new Axis with the same labels but a different name. - - Example - ------- - >>> sex = Axis('sex', ['M', 'F']) - >>> sex - Axis('sex', ['M', 'F']) - >>> sex.rename('gender') - Axis('gender', ['M', 'F']) - """ - res = self.copy() - if isinstance(name, Axis): - name = name.name - res.name = name - return res - - def _rename(self, name): - raise TypeError("Axis._rename is deprecated, use Axis.rename instead") - - -# We need a separate class for LGroup and cannot simply create a -# new Axis with a subset of values/ticks/labels: the subset of -# ticks/labels of the LGroup need to correspond to its *Axis* -# indices -class Group(object): - def __init__(self, key, name=None, axis=None): - if isinstance(key, tuple): - key = list(key) - self.key = key - - # we do NOT assign a name automatically when missing because that - # makes it impossible to know whether a name was explicitly given or - # not - self.name = name - assert axis is None or isinstance(axis, (basestring, int, Axis)), \ - "invalid axis '%s' (%s)" % (axis, type(axis).__name__) - - # we could check the key is valid but this can be slow and could be - # useless - # TODO: for performance reasons, we should cache the result. This will - # need to be invalidated correctly - # axis.translate(key) - - # we store the Axis object and not its name like we did previously - # so that groups on anonymous axes are more meaningful and that we - # can iterate on a slice of an axis (an LGroup). The reason to store - # the name instead of the object was to make sure that a Group from an - # axis (or without axis) could be used on another axis with the same - # name. See test_la.py:test_... - self.axis = axis - - def __repr__(self): - name = ", name=%r" % self.name if self.name is not None else '' - axis = ", axis=%r" % self.axis if self.axis is not None else '' - return "%s(%r%s%s)" % (self.__class__.__name__, self.key, name, axis) - - def __len__(self): - return len(self.key) - - def __iter__(self): - if isinstance(self.axis, Axis): - # the only interest is to expand slices - pos = self.axis.translate(self) - return iter(self.axis.labels[pos]) - else: - raise Exception('not iterable') - - def named(self, name): - """Returns group with a different name. - - Parameters - ---------- - name : str - new name for group - - Returns - ------- - Group - """ - return self.__class__(self.key, name, self.axis) - - -# TODO: factorize as much as possible between LGroup & PGroup (move stuff to -# Group) -class LGroup(Group): - """ - key should be either a sequence of labels, a slice with label bounds - or a string - axis can be an int, str or Axis - """ - # this makes range(LGroup(int)) possible - def __index__(self): - return self.key.__index__() - - def __int__(self): - return self.key.__int__() - - def __float__(self): - return self.key.__float__() - - def __hash__(self): - # to_tick & to_key are partially opposite operations but this - # standardize on a single notation so that they can all target each - # other. eg, this removes spaces in "list strings", instead of - # hashing them directly - # XXX: but we might want to include that normalization feature in - # to_tick directly, instead of using to_key explicitly here - # XXX: we probably want to include this normalization in __init__ - # instead - return hash(to_tick(to_key(self.key))) - - def __eq__(self, other): - # different name or axis compare equal ! - # XXX: we might want to compare "expanded" keys, so that slices - # can match lists and vice-versa. - other_key = other.key if isinstance(other, LGroup) else other - return to_tick(to_key(self.key)) == to_tick(to_key(other_key)) - - def __str__(self): - key = to_key(self.key) - if isinstance(key, slice): - str_key = slice_to_str(key, use_repr=True) - elif isinstance(key, (tuple, list, np.ndarray)): - str_key = '[%s]' % seq_summary(key, 1) - else: - str_key = repr(key) - - return '%r (%s)' % (self.name, str_key) if self.name is not None \ - else str_key - - def __lt__(self, other): - other_key = other.key if isinstance(other, LGroup) else other - return self.key.__lt__(other_key) - - def __gt__(self, other): - other_key = other.key if isinstance(other, LGroup) else other - return self.key.__gt__(other_key) - - def __getitem__(self, key): - return self.key[key] - - -class PGroup(Group): - """ - Positional Group - """ - pass - - -def index_by_id(seq, value): - for i, item in enumerate(seq): - if item is value: - return i - raise ValueError("%s is not in list" % value) - - -# not using OrderedDict because it does not support indices-based getitem -# not using namedtuple because we have to know the fields in advance (it is a -# one-off class) and we need more functionality than just a named tuple -class AxisCollection(object): - def __init__(self, axes=None): - """ - :param axes: sequence of Axis (or int) objects - """ - if axes is None: - axes = [] - if isinstance(axes, (int, long, str, Axis)): - axes = [axes] - axes = [axis if isinstance(axis, Axis) else Axis(None, axis) - for axis in axes] - assert all(isinstance(a, Axis) for a in axes) - dupe_axes = list(duplicates(axes)) - if dupe_axes: - axis = dupe_axes[0] - raise ValueError("Cannot have multiple occurences of the same axis " - "object in a collection ('%s' -- %s with id %d). " - "Several axes with the same name are allowed " - "though (but not recommended)." - % (axis.name, axis.labels_summary(), id(axis))) - self._list = axes - self._map = {axis.name: axis for axis in axes if axis.name is not None} - - def __iter__(self): - return iter(self._list) - - def __getattr__(self, key): - try: - return self._map[key] - except KeyError: - return self.__getattribute__(key) - - def __getitem__(self, key): - if isinstance(key, Axis): - try: - key = self.index(key) - # transform ValueError to KeyError - except ValueError: - if key.name is None: - raise KeyError("axis '%s' not found in %s" % (key, self)) - else: - # we should NOT check that the object is the same, so that we can - # use AxisReference objects to target real axes - key = key.name - - if isinstance(key, int): - return self._list[key] - elif isinstance(key, (tuple, list)): - # XXX: also use get_by_pos if tuple/list of Axis? - return AxisCollection([self[k] for k in key]) - elif isinstance(key, AxisCollection): - return AxisCollection([self.get_by_pos(k, i) - for i, k in enumerate(key)]) - elif isinstance(key, slice): - return AxisCollection(self._list[key]) - elif key is None: - raise KeyError("axis '%s' not found in %s" % (key, self)) - else: - assert isinstance(key, basestring), type(key) - if key in self._map: - return self._map[key] - else: - raise KeyError("axis '%s' not found in %s" % (key, self)) - - # XXX: I wonder if this whole positional crap should really be part of - # AxisCollection or the default behavior. It could either be moved to - # make_numpy_broadcastable or made non default - def get_by_pos(self, key, i): - """ - returns axis corresponding to key, or to i if key has no name and - key object not found - - Parameters - ---------- - key - i - - Returns - ------- - - """ - if isinstance(key, Axis) and key.name is None: - try: - # try by object - return self[key] - except KeyError: - if i in self: - res = self[i] - if res.iscompatible(key): - return res - else: - raise ValueError("axis %s is not compatible with %s" - % (res, key)) - # XXX: KeyError instead? - raise ValueError("axis %s not found in %s" - % (key, self)) - else: - return self[key] - - def __setitem__(self, key, value): - if isinstance(key, slice): - assert isinstance(value, (tuple, list, AxisCollection)) - def slice_bound(bound): - if bound is None or isinstance(bound, int): - # out of bounds integer bounds are allowed in slice setitem - # so we cannot use .index - return bound - else: - return self.index(bound) - start_idx = slice_bound(key.start) - # XXX: we might want to make the stop bound inclusive, which makes - # more sense for label bounds (but prevents inserts via setitem) - stop_idx = slice_bound(key.stop) - old = self._list[start_idx:stop_idx:key.step] - for axis in old: - if axis.name is not None: - del self._map[axis.name] - for axis in value: - if axis.name is not None: - self._map[axis.name] = axis - self._list[start_idx:stop_idx:key.step] = value - elif isinstance(key, (tuple, list, AxisCollection)): - assert isinstance(value, (tuple, list, AxisCollection)) - if len(key) != len(value): - raise ValueError('must have as many old axes as new axes') - for k, v in zip(key, value): - self[k] = v - else: - assert isinstance(value, Axis) - idx = self.index(key) - step = 1 if idx >= 0 else -1 - self[idx:idx + step:step] = [value] - - def __delitem__(self, key): - if isinstance(key, slice): - self[key] = [] - else: - idx = self.index(key) - axis = self._list.pop(idx) - if axis.name is not None: - del self._map[axis.name] - - def union(self, *args, **kwargs): - validate = kwargs.pop('validate', True) - replace_wildcards = kwargs.pop('replace_wildcards', True) - result = self[:] - for a in args: - if not isinstance(a, AxisCollection): - a = AxisCollection(a) - result.extend(a, validate=validate, replace_wildcards=replace_wildcards) - return result - __or__ = union - __add__ = union - - def __and__(self, other): - """ - returns the intersection of this collection and other - """ - if not isinstance(other, AxisCollection): - other = AxisCollection(other) - - # XXX: add iscompatible when matching by position? - # TODO: move this to a class method (possibly private) so that - # we make sure we use same heuristic than in .extend - def contains(col, i, axis): - return axis in col or (axis.name is None and i in col) - - return AxisCollection([axis for i, axis in enumerate(self) - if contains(other, i, axis)]) - - def __eq__(self, other): - """ - other collection compares equal if all axes compare equal and in the - same order. Works with a list. - """ - if not isinstance(other, list): - other = list(other) - return len(self._list) == len(other) and \ - all(a.equals(b) for a, b in zip(self._list, other)) - - # for python2, we need to define it explicitly - def __ne__(self, other): - return not self == other - - def __contains__(self, key): - if isinstance(key, int): - return -len(self) <= key < len(self) - elif isinstance(key, Axis): - if key.name is None: - # XXX: use only this in all cases? - try: - self.index(key) - return True - except ValueError: - return False - else: - key = key.name - return key in self._map - - def isaxis(self, value): - # this is tricky. 0 and 1 can be both axes indices and axes ticks. - # not sure what's worse: - # 1) disallow aggregates(axis_num) - # users could still use arr.sum(arr.axes[0]) - # we could also provide an explicit kwarg (ie this would - # effectively forbid having an axis named "axis"). - # arr.sum(axis=0). I think this is the sanest option. The - # error message in case we use it without the keyword needs to - # be clearer though. - return isinstance(value, Axis) or (isinstance(value, basestring) and - value in self) - # 2) slightly inconsistent API: allow aggregate over single labels - # if they are string, but not int - # arr.sum(0) would sum on the first axis, but arr.sum('H') would - # sum a single tick. I don't like this option. - # 3) disallow single tick aggregates. Single labels make little - # sense in the context of an aggregate, but you don't always - # know/want to differenciate the code in that case anyway. - # It would be annoying for e.g. Brussels - # 4) give priority to axes, - # arr.sum(0) would sum on the first axis but arr.sum(5) would - # sum a single tick (assuming there is a int axis and less than - # six axes). - # return value in self - - def __len__(self): - return len(self._list) - ndim = property(__len__) - - def __str__(self): - return "{%s}" % ', '.join(self.display_names) - - def __repr__(self): - axes_repr = (repr(axis) for axis in self._list) - return "AxisCollection([\n %s\n])" % ',\n '.join(axes_repr) - - def get(self, key, default=None, name=None): - # XXX: use if key in self? - try: - return self[key] - except KeyError: - if name is None: - return default - else: - return Axis(name, 1) - - def get_all(self, key): - """ - returns all axes from key if present and length 1 wildcard axes - otherwise - - Parameters - ---------- - key : AxisCollection - - Returns - ------- - AxisCollection - """ - assert isinstance(key, AxisCollection) - def get_pos_default(k, i): - try: - return self.get_by_pos(k, i) - except (ValueError, KeyError): - # XXX: is having i as name really helps? - return Axis(k.name if k.name is not None else i, 1) - - return AxisCollection([get_pos_default(k, i) - for i, k in enumerate(key)]) - - def keys(self): - # XXX: include id/num for anonymous axes? I think I should - return [a.name for a in self._list] - - def pop(self, axis=-1): - axis = self[axis] - del self[axis] - return axis - - def append(self, axis): - """ - append axis at the end of the collection - """ - self[len(self):len(self)] = [axis] - - def check_compatible(self, axes): - for i, axis in enumerate(axes): - # XXX: use self.get_by_pos? - # if axis in self: - # local_axis = self[axis] - # else: - # local_axis = self[i] if i < len(self) else None - - if axis.name is not None: - local_axis = self._map.get(axis.name) - else: - local_axis = self[i] if i < len(self) else None - if local_axis is not None: - if not local_axis.iscompatible(axis): - raise ValueError("incompatible axes:\n%r\nvs\n%r" - % (axis, local_axis)) - - def extend(self, axes, validate=True, replace_wildcards=False): - """ - extend the collection by appending the axes from axes - """ - # axes should be a sequence - if not isinstance(axes, (tuple, list, AxisCollection)): - raise TypeError("AxisCollection can only be extended by a " - "sequence of Axis, not %s" % type(axes).__name__) - # check that common axes are the same - # if validate: - # self.check_compatible(axes) - - # TODO: factorize with get_by_pos - def get_axis(col, i, axis): - if axis in col: - return col[axis] - elif axis.name is None and i in col: - return col[i] - else: - return None - - for i, axis in enumerate(axes): - old_axis = get_axis(self, i, axis) - if old_axis is None: - # append axis - self[len(self):len(self)] = [axis] - # elif replace_wildcards and old_axis.iswildcard: - # self[old_axis] = axis - else: - # check that common axes are the same - if validate and not old_axis.iscompatible(axis): - raise ValueError("incompatible axes:\n%r\nvs\n%r" - % (axis, old_axis)) - if replace_wildcards and old_axis.iswildcard: - self[old_axis] = axis - - def index(self, axis): - """ - returns the index of axis. - - axis can be a name or an Axis object (or an index) - if the Axis object itself exists in the list, index() will return it - otherwise, it will return the index of the local axis with the same - name than the key (whether it is compatible or not). - - Raises ValueError if the axis is not present. - """ - if isinstance(axis, int): - if -len(self) <= axis < len(self): - return axis - else: - raise ValueError("axis %d is not in collection" % axis) - elif isinstance(axis, Axis): - try: - # first look by id. This avoids testing labels of each axis - # and makes sure the result is correct even if there are - # several axes with no name and the same labels. - return index_by_id(self._list, axis) - except ValueError: - name = axis.name - else: - name = axis - if name is None: - raise ValueError("%r is not in collection" % axis) - return self.names.index(name) - - # XXX: we might want to return a new AxisCollection (same question for - # other inplace operations: append, extend, pop, __delitem__, __setitem__) - def insert(self, index, axis): - """ - insert axis before index - """ - self[index:index] = [axis] - - def copy(self): - return self[:] - - def replace(self, old, new): - res = self[:] - res[old] = new - return res - - # XXX: kill this method? - def without(self, axes): - """ - returns a new collection without some axes - you can use a comma separated list of names - set operations so axes can contain axes not present in self - """ - return self - axes - - def __sub__(self, axes): - """ - returns a new collection without some axes - you can use a comma separated list of names - set operations so axes can contain axes not present in self - """ - if isinstance(axes, basestring): - axes = axes.split(',') - elif isinstance(axes, Axis): - axes = [axes] - - # only keep indices (as this works for unnamed axes too) - to_remove = set(self.index(axis) for axis in axes if axis in self) - return AxisCollection([axis for i, axis in enumerate(self) - if i not in to_remove]) - - def translate_full_key(self, key): - """ - Parameters - ---------- - key : tuple - a full label-based key. All dimensions must be present and in - the correct order. - - Returns - ------- - tuple - a full positional key - """ - assert len(key) == len(self) - return tuple(axis.translate(axis_key) - for axis_key, axis in zip(key, self)) - - @property - def labels(self): - """Returns the list of labels of the axes""" - return [axis.labels for axis in self._list] - - @property - def names(self): - """Returns the list of (raw) names of the axes - - Returns - ------- - List - List of names of the axes - - Example - ------- - >>> a = Axis('a', ['a1', 'a2']) - >>> b = Axis('b', 2) - >>> c = Axis(None, ['c1', 'c2']) - >>> arr = zeros([a, b, c]) - >>> arr.axes.names - ['a', 'b', None] - """ - return [axis.name for axis in self._list] - - @property - def display_names(self): - """Returns the list of (display) names of the axes - - Returns - ------- - List - List of names of the axes - - Example - ------- - >>> a = Axis('a', ['a1', 'a2']) - >>> b = Axis('b', 2) - >>> c = Axis(None, ['c1', 'c2']) - >>> d = Axis(None, 3) - >>> col = AxisCollection([a, b, c, d]) - >>> col.display_names - ['a', 'b*', '{2}', '{3}*'] - """ - def display_name(i, axis): - name = axis.name if axis.name is not None else '{%d}' % i - return (name + '*') if axis.iswildcard else name - - return [display_name(i, axis) for i, axis in enumerate(self._list)] - - @property - def ids(self): - """Returns the list of ids of the axes - - Returns - ------- - list - List of ids of the axes - - Example - ------- - >>> a = Axis('a', 2) - >>> b = Axis(None, 2) - >>> c = Axis('c', 2) - >>> col = AxisCollection([a, b, c]) - >>> col.ids - ['a', 1, 'c'] - """ - return [axis.name if axis.name is not None else i - for i, axis in enumerate(self._list)] - - def axis_id(self, axis): - """Returns the id of an axis - - Returns - ------- - str or int - id of axis, which is its name if defined and its position otherwise - - Example - ------- - >>> a = Axis('a', 2) - >>> b = Axis(None, 2) - >>> c = Axis('c', 2) - >>> col = AxisCollection([a, b, c]) - >>> col.axis_id(a) - 'a' - >>> col.axis_id(b) - 1 - >>> col.axis_id(c) - 'c' - """ - axis = self[axis] - return axis.name if axis.name is not None else self.index(axis) - - @property - def shape(self): - return tuple(len(axis) for axis in self._list) - - @property - def size(self): - return np.prod(self.shape) - - @property - def info(self): - """Describes an AxisCollection (shape and labels for each axis). - - Returns - ------- - String - Description of the AxisCollection (shape and labels for each axis). - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> axes = AxisCollection([xnat, xsex]) - >>> axes.info - 2 x 2 - nat [2]: 'BE' 'FO' - sex [2]: 'H' 'F' - """ - lines = [" %s [%d]: %s" % (name, len(axis), axis.labels_summary()) - for name, axis in zip(self.display_names, self._list)] - shape = " x ".join(str(s) for s in self.shape) - return ReprString('\n'.join([shape] + lines)) - - -def all(values, axis=None): - """Test whether all array elements along given axes evaluate to True. - - Parameters - ---------- - axis : None, int, str or Axis, tuple of int, str or Axis, optional - axes over which to aggregate. Defaults to None (all axes). - - Returns - ------- - LArray or scalar - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> a = ndrange([xnat, xsex]) >= 1 - >>> a - nat\\sex | H | F - BE | False | True - FO | True | True - >>> all(a) - False - >>> all(a, xnat) - sex | H | F - | False | True - """ - if isinstance(values, LArray): - return values.all(axis) - else: - return builtins.all(values) - - -def any(values, axis=None): - """Test whether any array elements along given axes evaluate to True. - - Parameters - ---------- - axis : int, str or Axis, tuple of int, str or Axis, optional - axes over which to aggregate. Defaults to None (all axes). - - Returns - ------- - LArray or scalar - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> a = ndrange([xnat, xsex]) >= 3 - >>> a - nat\\sex | H | F - BE | False | False - FO | False | True - >>> any(a) - True - >>> any(a, xnat) - sex | H | F - | False | True - """ - if isinstance(values, LArray): - return values.any(axis) - else: - return builtins.any(values) - - -# commutative modulo float precision errors -def sum(array, *args, **kwargs): - """ - Sum of array elements over a given axis. - - Parameters - ---------- - array : iterable or array-like or LArray - Elements to sum. - axis : None or int or str or Axis or tuple of those, optional - Axis or axes along which a sum is performed. - The default (`axis` = `None`) is to perform a sum over all - axes of the input array. `axis` may be negative, in - which case it counts from the last to the first axis. - - If this is a tuple, a sum is performed on multiple axes. - - Returns - ------- - LArray - - See Also - -------- - LArray.sum : Equivalent method. - - Notes - ----- - The sum of an empty array is the neutral element 0: - - >>> sum([]) - 0.0 - - Examples - -------- - >>> a = ndrange((2, 3)) - >>> a - {0}*\\{1}* | 0 | 1 | 2 - 0 | 0 | 1 | 2 - 1 | 3 | 4 | 5 - >>> sum(a) - 15 - >>> sum(a, axis=0) - {0}* | 0 | 1 | 2 - | 3 | 5 | 7 - >>> sum(a, axis=1) - {0}* | 0 | 1 - | 3 | 12 - """ - # XXX: we might want to be more aggressive here (more types to convert), - # however, generators should still be computed via the builtin. - if isinstance(array, (np.ndarray, list)): - array = LArray(array) - if isinstance(array, LArray): - return array.sum(*args, **kwargs) - else: - return builtins.sum(array, *args, **kwargs) - - -def prod(array, *args, **kwargs): - return array.prod(*args, **kwargs) - - -def cumsum(array, *args, **kwargs): - return array.cumsum(*args, **kwargs) - - -def cumprod(array, *args, **kwargs): - return array.cumprod(*args, **kwargs) - - -def min(array, *args, **kwargs): - if isinstance(array, LArray): - return array.min(*args, **kwargs) - else: - return builtins.min(array, *args, **kwargs) - - -def max(array, *args, **kwargs): - if isinstance(array, LArray): - return array.max(*args, **kwargs) - else: - return builtins.max(array, *args, **kwargs) - - -def mean(array, *args, **kwargs): - return array.mean(*args, **kwargs) - - -def median(array, *args, **kwargs): - """ - Parameters - ---------- - array : iterable or array-like or LArray - axis : None or int or str or Axis or tuple of those, optional - - Returns - ------- - LArray - - See Also - -------- - LArray.median : Equivalent method. - - Examples - -------- - - >>> a = LArray([[10, 7, 4], [3, 2, 1]]) - >>> a - {0}*\\{1}* | 0 | 1 | 2 - 0 | 10 | 7 | 4 - 1 | 3 | 2 | 1 - >>> median(a) - 3.5 - >>> median(a, axis=0) - {0}* | 0 | 1 | 2 - | 6.5 | 4.5 | 2.5 - >>> median(a, axis=1) - {0}* | 0 | 1 - | 7.0 | 2.0 - """ - return array.median(*args, **kwargs) - - -def percentile(array, *args, **kwargs): - """ - Examples - -------- - - >>> a = LArray([[10, 7, 4], [3, 2, 1]]) - >>> a - {0}*\\{1}* | 0 | 1 | 2 - 0 | 10 | 7 | 4 - 1 | 3 | 2 | 1 - >>> # this is a bug in numpy: np.nanpercentile(all axes) returns an ndarray, - >>> # instead of a scalar. - >>> percentile(a, 50) - array(3.5) - >>> percentile(a, 50, axis=0) - {0}* | 0 | 1 | 2 - | 6.5 | 4.5 | 2.5 - >>> percentile(a, 50, axis=1) - {0}* | 0 | 1 - | 7.0 | 2.0 - """ - return array.percentile(*args, **kwargs) - - -# not commutative -def ptp(array, *args, **kwargs): - return array.ptp(*args, **kwargs) - - -def var(array, *args, **kwargs): - return array.var(*args, **kwargs) - - -def std(array, *args, **kwargs): - return array.std(*args, **kwargs) - - -def concat_empty(axis, array_axes, other_axes, dtype): - array_axis = array_axes[axis] - # Get axis by name, so that we do *NOT* check they are "compatible", - # because it makes sense to append axes of different length - other_axis = other_axes[axis] - new_labels = np.append(array_axis.labels, other_axis.labels) - new_axis = Axis(array_axis.name, new_labels) - array_axes = array_axes.replace(array_axis, new_axis) - other_axes = other_axes.replace(other_axis, new_axis) - # combine axes from both sides (using labels from either side if any) - result_axes = array_axes | other_axes - result_data = np.empty(result_axes.shape, dtype=dtype) - result = LArray(result_data, result_axes) - l = len(array_axis) - # XXX: wouldn't it be nice to be able to say that? ie translation - # from position to label on the original axis then translation to - # position on the actual result axis? - # result[:axis.i[-1]] - return result, result[new_axis.i[:l]], result[new_axis.i[l:]] - - -class LArrayIterator(object): - def __init__(self, array): - self.array = array - self.position = 0 - - def __iter__(self): - return self - - def __next__(self): - array = self.array - if self.position == len(self.array): - raise StopIteration - # result = array.i[array.axes[0].i[self.position]] - result = array.i[self.position] - self.position += 1 - return result - # Python 2 - next = __next__ - - -class LArrayPositionalIndexer(object): - def __init__(self, array): - self.array = array - - def translate_key(self, key): - if not isinstance(key, tuple): - key = (key,) - if len(key) > self.array.ndim: - raise IndexError("key has too many indices (%d) for array with %d " - "dimensions" % (len(key), self.array.ndim)) - # no need to create a full nd key as that will be done later anyway - return tuple(axis.i[axis_key] - for axis_key, axis in zip(key, self.array.axes)) - - def __getitem__(self, key): - return self.array[self.translate_key(key)] - - def __setitem__(self, key, value): - self.array[self.translate_key(key)] = value - - -class LArrayPointsIndexer(object): - def __init__(self, array): - self.array = array - - def __getitem__(self, key): - # TODO: this should generate an "intersection"/points NDGroup and simply - # do return self.array[nd_group] - data = np.asarray(self.array) - translated_key = self.array.translated_key(key, bool_stuff=True) - - axes = self.array._bool_key_new_axes(translated_key) - data = data[translated_key] - # drop length 1 dimensions created by scalar keys - # data = data.reshape(tuple(len(axis) for axis in axes)) - if not axes: - # scalars do not need to be wrapped in LArray - return data - else: - return LArray(data, axes) - - # FIXME - def __setitem__(self, key, value): - raise NotImplementedError() - - -class LArrayPositionalPointsIndexer(object): - def __init__(self, array): - self.array = array - - def __getitem__(self, key): - data = np.asarray(self.array) - - axes = self.array._bool_key_new_axes(key, wildcard_allowed=False) - data = data[key] - # drop length 1 dimensions created by scalar keys - # data = data.reshape(tuple(len(axis) for axis in axes)) - if not axes: - # scalars do not need to be wrapped in LArray - return data - else: - return LArray(data, axes) - - def __setitem__(self, key, value): - data = np.asarray(self.array) - data[key] = value - - -def get_axis(obj, i): - return obj.axes[i] if isinstance(obj, LArray) else Axis(None, obj.shape[i]) - - -class LArray(object): - """ - LArray class - """ - def __init__(self, data, axes=None): - data = np.asarray(data) - ndim = data.ndim - if axes is None: - axes = AxisCollection(data.shape) - else: - if not isinstance(axes, AxisCollection): - axes = AxisCollection(axes) - if axes.ndim != ndim: - raise ValueError("number of axes (%d) does not match " - "number of dimensions of data (%d)" - % (axes.ndim, ndim)) - if axes.shape != data.shape: - raise ValueError("length of axes %s does not match " - "data shape %s" % (axes.shape, data.shape)) - - object.__setattr__(self, 'data', data) - object.__setattr__(self, 'axes', axes) - - def __getattr__(self, key): - try: - return self.__getitem__(key) - # XXX: maybe I should only catch KeyError here and be more aggressive - # in __getitem__ to raise KeyError on any exception - except Exception: - return self.__getattribute__(key) - - def __setattr__(self, key, value): - return self.__setitem__(key, value) - - @property - def i(self): - return LArrayPositionalIndexer(self) - - @property - def points(self): - return LArrayPointsIndexer(self) - - @property - def ipoints(self): - return LArrayPositionalPointsIndexer(self) - - def to_frame(self, fold_last_axis_name=False, dropna=None): - columns = pd.Index(self.axes[-1].labels) - if not fold_last_axis_name: - columns.name = self.axes[-1].name - if self.ndim > 1: - axes_names = self.axes.names[:-1] - if fold_last_axis_name: - tmp = axes_names[-1] if axes_names[-1] is not None else '' - if self.axes[-1].name: - axes_names[-1] = "{}\\{}".format(tmp, self.axes[-1].name) - - index = pd.MultiIndex.from_product(self.axes.labels[:-1], - names=axes_names) - else: - index = pd.Index(['']) - if fold_last_axis_name: - index.name = self.axes.names[-1] - data = np.asarray(self).reshape(len(index), len(columns)) - df = pd.DataFrame(data, index, columns) - if dropna is not None: - dropna = dropna if dropna is not True else 'all' - df.dropna(inplace=True, how=dropna) - return df - df = property(to_frame) - - def to_series(self, dropna=False): - index = pd.MultiIndex.from_product([axis.labels for axis in self.axes], - names=self.axes.names) - series = pd.Series(np.asarray(self).reshape(self.size), index) - if dropna: - series.dropna(inplace=True) - return series - series = property(to_series) - - #noinspection PyAttributeOutsideInit - # def __array_finalize__(self, obj): - # """ - # used when arrays are allocated from subclasses of ndarrays - # """ - # return np.ndarray.__array_finalize__(self.data, obj) - - # def __array_prepare__(self, arr, context=None): - # """ - # called before ufuncs (must return an ndarray) - # """ - # return np.ndarray.__array_prepare__(self.data, arr, context) - - def __array_wrap__(self, out_arr, context=None): - """ - Called after numpy ufuncs. This is never called during our wrapped - ufuncs, but if somebody uses raw numpy function, this works in some - cases. - """ - data = np.ndarray.__array_wrap__(self.data, out_arr, context) - return LArray(data, self.axes) - - def __bool__(self): - return bool(self.data) - # Python 2 - __nonzero__= __bool__ - - def rename(self, axis, newname): - """Renames an axis of the array. - - Parameters - ---------- - axis : int, str or Axis - axis. - newname : str - the new name for the axis. - - Returns - ------- - LArray - LArray with one of the axis renamed. - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> a = ones([xnat, xsex]) - >>> a - nat\\sex | H | F - BE | 1.0 | 1.0 - FO | 1.0 | 1.0 - >>> a.rename('nat', 'newnat') - newnat\\sex | H | F - BE | 1.0 | 1.0 - FO | 1.0 | 1.0 - """ - axis = self.axes[axis] - axes = [axis.rename(newname) if a is axis else a - for a in self.axes] - return LArray(self.data, axes) - - def sort_values(self, key): - """Sorts values of the LArray. - - Parameters - ---------- - key : scalar or tuple or Group - key along which to sort. Must have exactly one dimension less than - ndim. - - Returns - ------- - LArray - LArray with sorted values. - - Example - ------- - >>> xsex = Axis('sex', ['H', 'F']) - >>> xnat = Axis('nat', ['EU', 'FO', 'BE']) - >>> xtype = Axis('type', ['type1', 'type2']) - >>> a = LArray([[10, 2, 4], [3, 7, 1]], [xsex, xnat]) - >>> a - sex\\nat | EU | FO | BE - H | 10 | 2 | 4 - F | 3 | 7 | 1 - >>> a.sort_values('F') - sex\\nat | BE | EU | FO - H | 4 | 10 | 2 - F | 1 | 3 | 7 - >>> b = LArray([[[10, 2, 4], [3, 7, 1]], [[5, 1, 6], [2, 8, 9]]], - ... [xsex, xtype, xnat]) - >>> b - sex | type\\nat | EU | FO | BE - H | type1 | 10 | 2 | 4 - H | type2 | 3 | 7 | 1 - F | type1 | 5 | 1 | 6 - F | type2 | 2 | 8 | 9 - >>> b.sort_values(('H', 'type2')) - sex | type\\nat | BE | EU | FO - H | type1 | 4 | 10 | 2 - H | type2 | 1 | 3 | 7 - F | type1 | 6 | 5 | 1 - F | type2 | 9 | 2 | 8 - """ - subset = self[key] - if subset.ndim > 1: - raise NotImplementedError("sort_values key must have one " - "dimension less than array.ndim") - assert subset.ndim == 1 - axis = subset.axes[0] - posargsort = subset.posargsort() - - # FIXME: .data shouldn't be necessary, but currently, if we do not do - # it, we get - # PGroup(nat | EU | FO | BE - # | 1 | 2 | 0, axis='nat') - # which sorts the *data* correctly, but the labels on the nat axis are - # not sorted (because the __getitem__ in that case reuse the key - # axis as-is -- like it should). - # Both use cases have value, but I think reordering the ticks - # should be the default. Now, I am unsure where to change this. - # Probably in PGroupMaker.__getitem__, but then how do I get the - # "not reordering labels" behavior that I have now? - # FWIW, using .data, I get PGroup([1, 2, 0], axis='nat'), which works. - sorter = axis.i[posargsort.data] - return self[sorter] - - # XXX: rename to sort_axes? - def sort_axis(self, axes=None, reverse=False): - """Sorts axes of the LArray. - - Parameters - ---------- - axes : axis reference (Axis, string, int) or list of them - axis to sort. If None, sorts all axes. - reverse : bool - descending sort (default: False -- ascending) - - Returns - ------- - LArray - LArray with sorted axes. - - Example - ------- - >>> xnat = Axis('nat', ['EU', 'FO', 'BE']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> a = ndrange([xnat, xsex]) - >>> a - nat\\sex | H | F - EU | 0 | 1 - FO | 2 | 3 - BE | 4 | 5 - >>> a.sort_axis(x.sex) - nat\\sex | F | H - EU | 1 | 0 - FO | 3 | 2 - BE | 5 | 4 - >>> a.sort_axis() - nat\\sex | F | H - BE | 5 | 4 - EU | 1 | 0 - FO | 3 | 2 - >>> a.sort_axis((x.sex, x.nat)) - nat\\sex | F | H - BE | 5 | 4 - EU | 1 | 0 - FO | 3 | 2 - >>> a.sort_axis(reverse=True) - nat\\sex | H | F - FO | 2 | 3 - EU | 0 | 1 - BE | 4 | 5 - """ - if axes is None: - axes = self.axes - elif not isinstance(axes, (tuple, list, AxisCollection)): - axes = [axes] - - if not isinstance(axes, AxisCollection): - axes = self.axes[axes] - - def sort_key(axis): - key = np.argsort(axis.labels) - if reverse: - key = key[::-1] - return axis.i[key] - - return self[tuple(sort_key(axis) for axis in axes)] - - def _translate_axis_key_chunk(self, axis_key, bool_passthrough=True): - if isinstance(axis_key, Group): - return axis_key - - # TODO: instead of checking all axes, we should have a big mapping - # (in AxisCollection or LArray): - # label -> (axis, index) - # but for Pandas, this wouldn't work, we'd need label -> axis - valid_axes = [] - # TODO: use axis_key dtype to only check compatible axes - for axis in self.axes: - try: - axis_pos_key = axis.translate(axis_key, bool_passthrough) - valid_axes.append(axis) - except KeyError: - continue - if not valid_axes: - raise ValueError("%s is not a valid label for any axis" - % axis_key) - elif len(valid_axes) > 1: - # FIXME: .id - valid_axes = ', '.join(str(a.id) for a in valid_axes) - raise ValueError('%s is ambiguous (valid in %s)' % - (axis_key, valid_axes)) - return valid_axes[0].i[axis_pos_key] - - def _translate_axis_key(self, axis_key, bool_passthrough=True): - # TODO: do it for LArray key too (but using .i[] instead) - if isinstance(axis_key, (tuple, list, np.ndarray)): - axis = None - for size in (1, 10, 100, 1000): - # TODO: do not recheck already checked elements - key_chunk = axis_key[:size] - try: - tkey = self._translate_axis_key_chunk(key_chunk, - bool_passthrough) - axis = tkey.axis - break - except ValueError: - continue - if axis is not None: - # make sure we have an Axis object - axis = self.axes[axis] - # wrap key in LGroup - axis_key = axis[axis_key] - # XXX: reuse tkey chunks and only translate the rest? - return self._translate_axis_key_chunk(axis_key, - bool_passthrough) - else: - return self._translate_axis_key_chunk(axis_key, bool_passthrough) - - def _guess_axis(self, axis_key): - if isinstance(axis_key, Group): - return axis_key - - # TODO: instead of checking all axes, we should have a big mapping - # (in AxisCollection or LArray): - # label -> (axis, index) - # but for Pandas, this wouldn't work, we'd need label -> axis - valid_axes = [] - for axis in self.axes: - try: - axis.translate(axis_key) - valid_axes.append(axis) - except KeyError: - continue - if not valid_axes: - raise ValueError("%s is not a valid label for any axis" - % axis_key) - elif len(valid_axes) > 1: - # FIXME: .id - valid_axes = ', '.join(str(a.id) for a in valid_axes) - raise ValueError('%s is ambiguous (valid in %s)' % - (axis_key, valid_axes)) - return valid_axes[0][axis_key] - - # TODO: move this to AxisCollection - def translated_key(self, key, bool_stuff=False): - """Complete and translate key - - Parameters - ---------- - key : single axis key or tuple of keys or dict {axis_name: axis_key} - each axis key can be either a scalar, a list of scalars or - an LKey - - Returns - ------- - Returns a full N dimensional positional key - """ - - if isinstance(key, np.ndarray) and np.issubdtype(key.dtype, np.bool_) \ - and not bool_stuff: - return key.nonzero() - if isinstance(key, LArray) and np.issubdtype(key.dtype, np.bool_) \ - and not bool_stuff: - # if only the axes order is wrong, transpose - # FIXME: if the key has both missing and extra axes, it could be - # the correct size (or even shape, see below) - if key.size == self.size and key.shape != self.shape: - return np.asarray(key.transpose(self.axes)).nonzero() - # otherwise we need to transform the key to integer - elif key.size != self.size: - extra_key_axes = key.axes - self.axes - if extra_key_axes: - raise ValueError("subset key %s contains more axes than " - "array %s" % (key.axes, self.axes)) - - # do I want to allow key_axis.name to match against - # axis.num? does not seem like a good idea. - # but this should work - # >>> a = ndrange((3, 4)) - # >>> x1, x2 = a.axes - # >>> a[x2 > 2] - - # the current solution with hash = (name, labels) works - # but is slow for large axes and broken if axis labels are - # modified in-place, which I am unsure I want to support - # anyway - - map_key = dict(zip(key.axes, np.asarray(key).nonzero())) - return tuple(map_key.get(axis, slice(None)) - for axis in self.axes) - else: - # correct shape - # FIXME: if the key has both missing and extra axes (at the - # position of the missing axes), the shape could be the same - # while the result should not - return np.asarray(key).nonzero() - - # convert scalar keys to 1D keys - if not isinstance(key, (tuple, dict)): - key = (key,) - - if isinstance(key, tuple): - # handle keys containing an Ellipsis - # cannot use key.count(Ellipsis) because that calls == on each - # element and this breaks if there are ndarrays/LArrays in there. - num_ellipses = sum(isinstance(k, type(Ellipsis)) for k in key) - if num_ellipses > 1: - raise ValueError("cannot use more than one Ellipsis (...)") - elif num_ellipses == 1: - # XXX: we might want to just ignore them, since their - # position do not matter anymore (guess axis) - pos = key.index(Ellipsis) - none_slices = (slice(None),) * (self.ndim - len(key) + 1) - key = key[:pos] + none_slices + key[pos + 1:] - - # translate non LKey to PGroup and drop slice(None) since - # they are meaningless at this point - # XXX: we might want to raise an exception when we find (most) - # slice(None) because except for a single slice(None) a[:], I don't - # think there is any point. - key = tuple( - self._translate_axis_key(axis_key, - bool_passthrough=not bool_stuff) - for axis_key in key if not isnoneslice(axis_key)) - - assert all(isinstance(axis_key, Group) for axis_key in key) - - # handle keys containing LGroups (at potentially wrong places) - - # XXX: - # Q: support LGroup without axis? - # A: we should support them, but that should be done before. - # at this point they should all have an axis (not necessarily - # valid though) - - # extract axis from Group keys - dupe_axes = list(duplicates(axis_key.axis for axis_key in key)) - if dupe_axes: - dupe_axes = ', '.join(str(axis) for axis in dupe_axes) - raise ValueError("key with duplicate axis: %s" % dupe_axes) - - key = dict((axis_key.axis, axis_key) for axis_key in key) - - # keys could be strings or axis references and we want real axes - key = {self.axes[k]: v for k, v in key.items()} - - # dict -> tuple (complete and order key) - assert isinstance(key, dict) and all(isinstance(k, Axis) for k in key) - # XXX: probably useless (due to new code above) - for axis in key: - if axis not in self.axes: - raise KeyError("{} is not a valid axis".format(repr(axis))) - key = tuple(key[axis] if axis in key else slice(None) - for axis in self.axes) - - # label -> raw positional - return tuple(axis.translate(axis_key, bool_passthrough=not bool_stuff) - for axis, axis_key in zip(self.axes, key)) - - # TODO: we only need axes length => move this to AxisCollection - # (but this backend/numpy-specific so we'll probably need to create a - # subclass of it) - def cross_key(self, key, collapse_slices=False): - """ - :param key: a complete (contains all dimensions) index-based key - :param collapse_slices: convert contiguous ranges to slices - :return: a key for indexing the cross product - """ - # isinstance(ndarray, collections.Sequence) is False but it - # behaves like one - sequence = (tuple, list, np.ndarray) - if collapse_slices: - key = [range_to_slice(axis_key, len(axis)) - if isinstance(axis_key, sequence) - else axis_key - for axis_key, axis in zip(key, self.axes)] - - # count number of indexing arrays (ie non scalar/slices) in tuple - num_ix_arrays = sum(isinstance(axis_key, sequence) for axis_key in key) - num_scalars = sum(np.isscalar(axis_key) for axis_key in key) - num_slices = sum(isinstance(axis_key, slice) for axis_key in key) - assert len(key) == num_ix_arrays + num_scalars + num_slices - - # handle advanced indexing with more than one indexing array: - # basic indexing (only integer and slices) and advanced indexing - # with only one indexing array are handled fine by numpy - if num_ix_arrays > 1 or (num_ix_arrays > 0 and num_scalars): - # np.ix_ wants only lists so: - - # 1) transform scalar-key to lists of 1 element. In that case, - # ndarray.__getitem__ leaves length 1 dimensions instead of - # dropping them like we would like so we will need to drop - # them later ourselves (via reshape) - noscalar_key = [[axis_key] if np.isscalar(axis_key) else axis_key - for axis_key in key] - - # 2) expand slices to lists (ranges) - # XXX: cache the range in the axis? - # TODO: fork np.ix_ to allow for slices directly - # it will be tricky to get right though because in that case the - # result of a[key] can have its dimensions in the wrong order - # (if the ix_arrays are not next to each other, the corresponding - # dimensions are moved to the front). It is probably worth the - # trouble though because it is much faster than the current - # solution (~5x in my simple test) but this case (num_ix_arrays > - # 1) is rare in the first place (at least in demo) so it is not a - # priority. - listkey = tuple(np.arange(*axis_key.indices(len(axis))) - if isinstance(axis_key, slice) - else axis_key - for axis_key, axis in zip(noscalar_key, self.axes)) - # np.ix_ computes the cross product of all lists - return np.ix_(*listkey) - else: - return tuple(key) - - def __getitem__(self, key, collapse_slices=False): - # move this to getattr - # if isinstance(key, str) and key in ('__array_struct__', - # '__array_interface__'): - # raise KeyError("bla") - data = np.asarray(self.data) - translated_key = self.translated_key(key) - - # FIXME: I have a huge problem with boolean labels + non points - if isinstance(key, (LArray, np.ndarray)) and \ - np.issubdtype(key.dtype, np.bool_): - return LArray(data[translated_key], - self._bool_key_new_axes(translated_key)) - - if any(isinstance(axis_key, LArray) for axis_key in translated_key): - k2 = [k.data if isinstance(k, LArray) else k - for k in translated_key] - data = data[k2] - axes = [axis.subaxis(axis_key) - for axis, axis_key in zip(self.axes, translated_key) - if not np.isscalar(axis_key)] - - # subaxis can return tuple of axes and we want a single list of axes - # not a nested structure. We could do both in one step but it's - # awfully unreadable. - def flatten(l): - return [e for sublist in l for e in sublist] - - def to2d(l): - return [mixed if isinstance(mixed, (tuple, list)) else [mixed] - for mixed in l] - - axes = flatten(to2d(axes)) - return LArray(data, axes) - - # TODO: if the original key was a list of labels, - # subaxis(translated_key).labels == orig_key, so we should use - # orig_axis_key.copy() - axes = [axis.subaxis(axis_key) - for axis, axis_key in zip(self.axes, translated_key) - if not np.isscalar(axis_key)] - - cross_key = self.cross_key(translated_key, collapse_slices) - data = data[cross_key] - if not axes: - # scalars do not need to be wrapped in LArray - return data - else: - # drop length 1 dimensions created by scalar keys - data = data.reshape(tuple(len(axis) for axis in axes)) - return LArray(data, axes) - - def __setitem__(self, key, value, collapse_slices=True): - # TODO: if key or value has more axes than self, we should use - # total_axes = self.axes + key.axes + value.axes - # expanded = self.expand(total_axes) - # data = np.asarray(expanded.data) - - # concerning keys this can make sense in several cases: - # single bool LArray key with extra axes. - # tuple of bool LArray keys (eg one for each axis). each could have - # extra axes. Common axes between keys are not a problem, we can - # simply "and" them. Though we should avoid explicitly "and"ing them - # if there is no common axis because that is less efficient than - # the implicit "and" that is done by numpy __getitem__ (and the fact we - # need to combine dimensions when any key has more than 1 dim). - - # the bool value represents whether the axis label is taken or not - # if any bool key (part) has more than one axis, we get combined - # dimensions out of it. - - # int LArray keys - # the int value represent a position along ONE particular axis, - # even if the key has more than one axis. - data = np.asarray(self.data) - translated_key = self.translated_key(key) - - if isinstance(key, (LArray, np.ndarray)) and \ - np.issubdtype(key.dtype, np.bool_): - if isinstance(value, LArray): - new_axes = self._bool_key_new_axes(translated_key, - wildcard_allowed=True) - value = value.broadcast_with(new_axes) - data[translated_key] = value - return - - # XXX: we might want to create fakes (or wildcard?) axes in this case, - # as we only use axes names and axes length, not the ticks, and those - # could theoretically take a significant time to compute - axes = [axis.subaxis(axis_key) - for axis, axis_key in zip(self.axes, translated_key) - if not np.isscalar(axis_key)] - - cross_key = self.cross_key(translated_key, collapse_slices) - - # if value is a "raw" ndarray we rely on numpy broadcasting - data[cross_key] = value.broadcast_with(axes) \ - if isinstance(value, LArray) else value - - def _bool_key_new_axes(self, key, wildcard_allowed=False): - """ - - Parameters - ---------- - key : tuple - position-based key - wildcard_allowed : bool - - Returns - ------- - AxisCollection - """ - combined_axes = [axis for axis_key, axis in zip(key, self.axes) - if not isnoneslice(axis_key) and - not np.isscalar(axis_key)] - # scalar axes are not taken, since we want to kill them - other_axes = [axis for axis_key, axis in zip(key, self.axes) - if isnoneslice(axis_key)] - assert len(key) > 0 - axes_indices = [self.axes.index(axis) for axis in combined_axes] - diff = np.diff(axes_indices) - # this can happen if key has only None slices and scalars - if not len(combined_axes): - combined_axis_pos = None - elif np.any(diff > 1): - # combined axes in front - combined_axis_pos = 0 - else: - combined_axis_pos = axes_indices[0] - # XXX: I am not sure we should keep axis.id (when axis had no name), - # especially if there was only one combined axis because that - # transforms an anonymous axis into a "normal" name. On the other - # hand, not keeping it loose information. The question is whether - # that information is worth keeping :) - combined_name = ','.join(str(self.axes.axis_id(axis)) - for axis in combined_axes) - new_axes = other_axes - if combined_axis_pos is not None: - if wildcard_allowed: - lengths = [len(axis_key) for axis_key in key - if not isnoneslice(axis_key) and - not np.isscalar(axis_key)] - combined_axis_len = lengths[0] - assert all(l == combined_axis_len for l in lengths) - combined_axis = Axis(combined_name, combined_axis_len) - else: - # TODO: the combined keys should be objects which display as: - # (axis1_label, axis2_label, ...) but which should also store - # the axis (names?) - # Q: Should it be the same object as the NDLGroup?/NDKey? - # A: yes, probably. On the Pandas backend, we could/should have - # separate axes. On the numpy backend we cannot. - axes_labels = [axis.labels[axis_key] - for axis_key, axis in zip(key, self.axes) - if not isnoneslice(axis_key) and - not np.isscalar(axis_key)] - if len(combined_axes) == 1: - # Q: if axis is a wildcard axis, should the result be a - # wildcard axis (and axes_labels discarded?) - combined_labels = axes_labels[0] - else: - combined_labels = list(zip(*axes_labels)) - - # CRAP, this can lead to duplicate labels (especially using - # .points) - combined_axis = Axis(combined_name, combined_labels) - new_axes.insert(combined_axis_pos, combined_axis) - return AxisCollection(new_axes) - - def set(self, value, **kwargs): - """ - sets a subset of LArray to value - - * all common axes must be either 1 or the same length - * extra axes in value must be of length 1 - * extra axes in self can have any length - """ - self.__setitem__(kwargs, value) - - def reshape(self, target_axes): - """ - self.size must be equal to prod([len(axis) for axis in target_axes]) - """ - # this is a dangerous operation, because except for adding - # length 1 axes (which is safe), it potentially modifies data - # TODO: add a check/flag? for "unsafe" reshapes (but allow merging - # several axes & "splitting" axes) etc. - # eg 4, 3, 2 -> 2, 3, 4 is wrong (even if size is respected) - # 4, 3, 2 -> 12, 2 is potentially ok (merging adjacent dimensions) - # -> 4, 6 is potentially ok (merging adjacent dimensions) - # -> 24 is potentially ok (merging adjacent dimensions) - # -> 3, 8 WRONG (non adjacent dimentsions) - # -> 8, 3 WRONG - # 4, 3, 2 -> 2, 2, 3, 2 is potentially ok (splitting dim) - data = np.asarray(self).reshape([len(axis) for axis in target_axes]) - return LArray(data, target_axes) - - def reshape_like(self, target): - """ - target is an LArray, total size must be compatible - """ - return self.reshape(target.axes) - - def broadcast_with(self, other): - """ - returns an LArray that is (numpy) broadcastable with target - target can be either an LArray or any collection of Axis - - * all common axes must be either 1 or the same length - * extra axes in source can have any length and will be moved to the - front - * extra axes in target can have any length and the result will have axes - of length 1 for those axes - - this is different from reshape which ensures the result has exactly the - shape of the target. - """ - if isinstance(other, LArray): - other_axes = other.axes - else: - other_axes = other - if not isinstance(other, AxisCollection): - other_axes = AxisCollection(other_axes) - # other_names = [a.name for a in other_axes] - - # XXX: this breaks la['1,5,9'] = la['2,7,3'] - # but that use case should use drop_labels - # self.axes.check_compatible(other_axes) - - # 1) append length-1 axes for other-only axes - # TODO: factorize with make_numpy_broadcastable - otheronly_axes = [Axis(axis.name, 1) if len(axis) != 1 else axis - for axis in other_axes if axis not in self.axes] - array = self.reshape(self.axes + otheronly_axes) - # 2) reorder axes to target order (move source-only axes to the front) - sourceonly_axes = self.axes - other_axes - # axes_other_order = [array.axes[name] for name in other_names] - axes_other_order = array.axes[other_axes] - return array.transpose(sourceonly_axes + axes_other_order) - - def drop_labels(self, axes=None): - """drop the labels from axes (replace those axes by "wildcard" axes) - - Parameters - ---------- - axes : Axis or list/tuple/AxisCollection of Axis - - Returns - ------- - LArray - - Examples - -------- - >>> a = Axis('a', ['a1', 'a2']) - >>> b = Axis('b', ['b1', 'b2']) - >>> b2 = Axis('b', ['b2', 'b3']) - >>> arr1 = ndrange([a, b]) - >>> arr1 - a\\b | b1 | b2 - a1 | 0 | 1 - a2 | 2 | 3 - >>> arr1.drop_labels(b) - a\\b* | 0 | 1 - a1 | 0 | 1 - a2 | 2 | 3 - >>> arr1.drop_labels([a, b]) - a*\\b* | 0 | 1 - 0 | 0 | 1 - 1 | 2 | 3 - >>> arr2 = ndrange([a, b2]) - >>> arr2 - a\\b | b2 | b3 - a1 | 0 | 1 - a2 | 2 | 3 - >>> arr1 * arr2 - Traceback (most recent call last): - ... - ValueError: incompatible axes: - Axis('b', ['b2', 'b3']) - vs - Axis('b', ['b1', 'b2']) - >>> arr1 * arr2.drop_labels() - a\\b | b1 | b2 - a1 | 0 | 1 - a2 | 4 | 9 - >>> arr1.drop_labels() * arr2 - a\\b | b2 | b3 - a1 | 0 | 1 - a2 | 4 | 9 - >>> arr1.drop_labels('a') * arr2.drop_labels('b') - a\\b | b1 | b2 - a1 | 0 | 1 - a2 | 4 | 9 - """ - if axes is None: - axes = self.axes - if not isinstance(axes, (tuple, list, AxisCollection)): - axes = [axes] - old_axes = self.axes[axes] - new_axes = [Axis(axis.name, len(axis)) for axis in old_axes] - res_axes = self.axes.replace(axes, new_axes) - return LArray(self.data, res_axes) - - def __str__(self): - if not self.ndim: - return str(np.asscalar(self)) - elif not len(self): - return 'LArray([])' - else: - return table2str(list(self.as_table()), 'nan', True, - keepcols=self.ndim - 1) - __repr__ = __str__ - - def __iter__(self): - return LArrayIterator(self) - - def as_table(self, maxlines=200, edgeitems=5): - if not self.ndim: - return - - # ert | unit | geo\time | 2012 | 2011 | 2010 - # NEER27 | I05 | AT | 101.41 | 101.63 | 101.63 - # NEER27 | I05 | AU | 134.86 | 125.29 | 117.08 - width = self.shape[-1] - height = int(np.prod(self.shape[:-1])) - data = np.asarray(self).reshape(height, width) - - axes_names = self.axes.display_names[:] - if len(axes_names) > 1: - axes_names[-2] = '\\'.join(axes_names[-2:]) - axes_names.pop() - labels = self.axes.labels[:-1] - if self.ndim == 1: - # There is no vertical axis, so the axis name should not have - # any "tick" below it and we add an empty "tick". - ticks = [['']] - else: - ticks = product(*labels) - yield axes_names + list(self.axes.labels[-1]) - - # summary if needed - if height > maxlines: - data = chain(data[:edgeitems], [["..."] * width], data[-edgeitems:]) - if height > maxlines: - startticks = islice(ticks, edgeitems) - midticks = [["..."] * (self.ndim - 1)] - endticks = list(islice(rproduct(*labels), edgeitems))[::-1] - ticks = chain(startticks, midticks, endticks) - - for tick, dataline in izip(ticks, data): - yield list(tick) + list(dataline) - - # XXX: should filter(geo=['W']) return a view by default? (collapse=True) - # I think it would be dangerous to make it the default - # behavior, because that would introduce a subtle difference between - # filter(dim=[a, b]) and filter(dim=[a]) even though it would be faster - # and uses less memory. Maybe I should have a "view" argument which - # defaults to 'auto' (ie collapse by default), can be set to False to - # force a copy and to True to raise an exception if a view is not possible. - def filter(self, collapse=False, **kwargs): - """ - filters the array along the axes given as keyword arguments. - The *collapse* argument determines whether consecutive ranges should - be collapsed to slices, which is more efficient and returns a view - (and not a copy) if possible (if all ranges are consecutive). - Only use this argument if you do not intent to modify the resulting - array, or if you know what you are doing. - It is similar to np.take but works with several axes at once. - """ - return self.__getitem__(kwargs, collapse) - - def _axis_aggregate(self, op, axes=(), keepaxes=False, out=None, **kwargs): - """ - Parameters - ---------- - op : function - a aggregate function with this signature: - func(a, axis=None, dtype=None, out=None, keepdims=False) - axes : tuple of axes, optional - each axis can be an Axis object, str or int - out : LArray, optional - keepaxes : bool or scalar, optional - - Returns - ------- - LArray or scalar - """ - src_data = np.asarray(self) - axes = list(axes) if axes else self.axes - axes_indices = tuple(self.axes.index(a) for a in axes) - keepdims = bool(keepaxes) - if out is not None: - assert isinstance(out, LArray) - kwargs['out'] = out.data - res_data = op(src_data, axis=axes_indices, keepdims=keepdims, **kwargs) - - if keepaxes: - label = op.__name__.replace('nan', '') if keepaxes is True \ - else keepaxes - axes_to_kill = [self.axes[axis] for axis in axes] - new_axes = [Axis(axis.name, [label]) for axis in axes_to_kill] - res_axes = self.axes.replace(axes_to_kill, new_axes) - else: - res_axes = self.axes - axes_indices - if not res_axes: - # scalars don't need to be wrapped in LArray - return res_data - else: - return LArray(res_data, res_axes) - - def _cum_aggregate(self, op, axis): - """ - op is a numpy cumulative aggregate function: func(arr, axis=0) - axis is an Axis object, a str or an int. Contrary to other aggregate - functions this only supports one axis at a time. - """ - # TODO: accept a single group in axis, to filter & aggregate in one shot - return LArray(op(np.asarray(self), axis=self.axes.index(axis)), - self.axes) - - # TODO: now that items is never a (k, v), it should be renamed to - # something else: args? (groups would be misleading because each "item" - # can contain several groups) - # TODO: experiment implementing this using ufunc.reduceat - # http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.ufunc.reduceat.html - # XXX: rename keepaxes to label=value? For group_aggregates we might - # want to keep the VG label if any - def _group_aggregate(self, op, items, keepaxes=False, out=None, **kwargs): - assert out is None - res = self - # TODO: when working with several "axes" at the same times, we should - # not produce the intermediary result at all. It should be faster and - # consume a bit less memory. - for item in items: - res_axes = res.axes[:] - res_shape = list(res.shape) - - if isinstance(item, tuple): - assert all(isinstance(g, Group) for g in item) - groups = item - axis = groups[0].axis - killaxis = False - else: - # item is in fact a single group - assert isinstance(item, Group), type(item) - groups = (item,) - axis = item.axis - # it is easier to kill the axis after the fact - killaxis = True - - axis, axis_idx = res.axes[axis], res.axes.index(axis) - res_shape[axis_idx] = len(groups) - res_dtype = res.dtype if op not in (np.mean, np.nanmean) else float - res_data = np.empty(res_shape, dtype=res_dtype) - - group_idx = [slice(None) for _ in res_shape] - for i, group in enumerate(groups): - group_idx[axis_idx] = i - # this is only useful for ndim == 1 because - # a[(0,)] (equivalent to a[0] which kills the axis) - # is different from a[[0]] (which does not kill the axis) - idx = tuple(group_idx) - - # we need only lists of ticks, not single ticks, otherwise the - # dimension is discarded too early (in __getitem__ instead of in - # the aggregate func) - if isinstance(group, PGroup) and np.isscalar(group.key): - group = PGroup([group.key], axis=group.axis) - elif isinstance(group, LGroup): - key = to_key(group.key) - if np.isscalar(key): - key = [key] - # we do not care about the name at this point - group = LGroup(key, axis=group.axis) - - arr = res.__getitem__({axis.name: group}, collapse_slices=True) - if res_data.ndim == 1: - assert len(idx) == 1 and idx[0] == i - - # res_data[idx] but instead of returning a scalar (eg - # np.int32), it returns a 0d array which is a view on - # res_data, which can thus be used as out - out = res_data[i:i + 1].reshape(()) - else: - out = res_data[idx] - - arr = np.asarray(arr) - op(arr, axis=axis_idx, out=out, **kwargs) - del arr - if killaxis: - assert group_idx[axis_idx] == 0 - res_data = res_data[idx] - del res_axes[axis_idx] - else: - # We do NOT modify the axis name (eg append "_agg" or "*") even - # though this creates a new axis that is independent from the - # original one because the original name is what users will - # want to use to access that axis (eg in .filter kwargs) - res_axes[axis_idx] = Axis(axis.name, groups) - - if isinstance(res_data, np.ndarray): - res = LArray(res_data, res_axes) - else: - res = res_data - return res - - def _prepare_aggregate(self, op, args, kwargs=None, commutative=False): - """converts args to keys & VG and kwargs to VG""" - - if kwargs is None: - kwargs_items = [] - else: - explicit_axis = kwargs.pop('axis', None) - if explicit_axis is not None: - explicit_axis = self.axes[explicit_axis] - if isinstance(explicit_axis, Axis): - args += (explicit_axis,) - else: - assert isinstance(explicit_axis, AxisCollection) - args += tuple(explicit_axis) - kwargs_items = kwargs.items() - if not commutative and len(kwargs_items) > 1: - raise ValueError("grouping aggregates on multiple axes at the same " - "time using keyword arguments is not supported " - "for '%s' (because it is not a commutative" - "operation and keyword arguments are *not* " - "ordered in Python)" % op.__name__) - - # Sort kwargs by axis name so that we have consistent results - # between runs because otherwise rounding errors could lead to - # slightly different results even for commutative operations. - sorted_kwargs = sorted(kwargs_items) - - # convert kwargs to LGroup so that we can only use args afterwards - # but still keep the axis information - def standardise_kw_arg(axis_name, key): - if isinstance(key, str): - key = to_keys(key) - if isinstance(key, tuple): - return tuple(standardise_kw_arg(axis_name, k) for k in key) - if isinstance(key, LGroup): - return key - return self.axes[axis_name][key] - - def to_labelgroup(key): - if isinstance(key, str): - key = to_keys(key) - if isinstance(key, tuple): - # a tuple is supposed to be several groups on the same axis - # XXX: we might want to use self._translate_axis_key directly - # (so that we do not need to do the label -> position - # translation twice) - groups = tuple(self._guess_axis(k) for k in key) - axis = groups[0].axis - if not all(g.axis.equals(axis) for g in groups[1:]): - raise ValueError("group with different axes: %s" - % str(key)) - return groups - if isinstance(key, Group): - return key - elif isinstance(key, (int, basestring, list, slice)): - return self._guess_axis(key) - else: - raise NotImplementedError("%s has invalid type (%s) for a " - "group aggregate key" - % (key, type(key).__name__)) - - def standardise_arg(arg): - if self.axes.isaxis(arg): - return self.axes[arg] - else: - return to_labelgroup(to_keys(arg)) - - operations = [standardise_arg(a) for a in args if a is not None] + \ - [standardise_kw_arg(k, v) for k, v in sorted_kwargs] - if not operations: - # op() without args is equal to op(all_axes) - operations = self.axes - return operations - - def _aggregate(self, op, args, kwargs=None, keepaxes=False, - commutative=False, out=None, extra_kwargs={}): - operations = self._prepare_aggregate(op, args, kwargs, commutative) - res = self - # group *consecutive* same-type (group vs axis aggregates) operations - # we do not change the order of operations since we only group - # consecutive operations. - for are_axes, axes in groupby(operations, self.axes.isaxis): - func = res._axis_aggregate if are_axes else res._group_aggregate - res = func(op, axes, keepaxes=keepaxes, out=out, **extra_kwargs) - return res - - def with_total(self, *args, **kwargs): - """ - Parameters - ---------- - args - kwargs - op : aggregate function - Defaults to `sum()`. - label : scalar value - label to use for the total. Defaults to "total". - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> arr = ndrange([xnat, xsex]) - >>> arr.with_total() - nat\\sex | H | F | total - BE | 0 | 1 | 1 - FO | 2 | 3 | 5 - total | 2 | 4 | 6 - >>> arr = ndrange([Axis('a', 2), Axis('b', 3)]) - >>> arr.with_total() - a\\b | 0 | 1 | 2 | total - 0 | 0 | 1 | 2 | 3 - 1 | 3 | 4 | 5 | 12 - total | 3 | 5 | 7 | 15 - """ - # TODO: default to op.__name__ - label = kwargs.pop('label', 'total') - op = kwargs.pop('op', sum) - npop = { - sum: np.sum, - prod: np.prod, - min: np.min, - max: np.max, - mean: np.mean, - ptp: np.ptp, - var: np.var, - std: np.std, - median: np.median, - percentile: np.percentile, - } - # TODO: commutative should be known for usual ops - operations = self._prepare_aggregate(op, args, kwargs, False) - res = self - # TODO: we should allocate the final result directly and fill it - # progressively, so that the original array is only copied once - for axis in operations: - # TODO: append/extend first with an empty array then - # _aggregate with out= - if self.axes.isaxis(axis): - value = res._axis_aggregate(npop[op], (axis,), keepaxes=label) - else: - # groups - if not isinstance(axis, tuple): - # assume a single group - axis = (axis,) - vgkey = axis - axis = vgkey[0].axis - value = res._aggregate(npop[op], (vgkey,)) - res = res.extend(axis, value) - return res - - # TODO: make sure we can do - # arr[x.sex.i[arr.posargmin(x.sex)]] - # and - # arr[arr.argmin(x.sex)] - # should both be equal to arr.min(x.sex) - def argmin(self, axis): - """ - Return labels of the minimum values along the given axis of `a`. - - Parameters - ---------- - axis : int or str or Axis - Axis along which to work. - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FR', 'IT']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> arr = LArray([[0, 1], [3, 2], [2, 5]], [xnat, xsex]) - >>> arr - nat\\sex | H | F - BE | 0 | 1 - FR | 3 | 2 - IT | 2 | 5 - >>> arr.argmin(x.sex) - nat | BE | FR | IT - | H | F | H - """ - axis, axis_idx = self.axes[axis], self.axes.index(axis) - data = axis.labels[self.data.argmin(axis_idx)] - return LArray(data, self.axes - axis) - - def posargmin(self, axis): - """ - Return indices of the minimum values along the given axis of `a`. - - Parameters - ---------- - axis : int or str or Axis - Axis along which to work. - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FR', 'IT']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> arr = LArray([[0, 1], [3, 2], [2, 5]], [xnat, xsex]) - >>> arr - nat\\sex | H | F - BE | 0 | 1 - FR | 3 | 2 - IT | 2 | 5 - >>> arr.posargmin(x.sex) - nat | BE | FR | IT - | 0 | 1 | 0 - """ - axis, axis_idx = self.axes[axis], self.axes.index(axis) - return LArray(self.data.argmin(axis_idx), self.axes - axis) - - def argmax(self, axis): - """ - Return labels of the maximum values along the given axis of `a`. - - Parameters - ---------- - axis : int or str or Axis - Axis along which to work. - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FR', 'IT']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> arr = LArray([[0, 1], [3, 2], [2, 5]], [xnat, xsex]) - >>> arr - nat\\sex | H | F - BE | 0 | 1 - FR | 3 | 2 - IT | 2 | 5 - >>> arr.argmax(x.sex) - nat | BE | FR | IT - | F | H | F - """ - axis, axis_idx = self.axes[axis], self.axes.index(axis) - data = axis.labels[self.data.argmax(axis_idx)] - return LArray(data, self.axes - axis) - - def posargmax(self, axis): - """ - Return indices of the maximum values along the given axis of `a`. - - Parameters - ---------- - axis : int or str or Axis - Axis along which to work. - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FR', 'IT']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> arr = LArray([[0, 1], [3, 2], [2, 5]], [xnat, xsex]) - >>> arr - nat\\sex | H | F - BE | 0 | 1 - FR | 3 | 2 - IT | 2 | 5 - >>> arr.posargmax(x.sex) - nat | BE | FR | IT - | 1 | 0 | 1 - """ - axis, axis_idx = self.axes[axis], self.axes.index(axis) - return LArray(self.data.argmax(axis_idx), self.axes - axis) - - def argsort(self, axis=None, kind='quicksort'): - """ - Returns the labels that would sort this array. - - Perform an indirect sort along the given axis using the algorithm - specified by the `kind` keyword. It returns an array of labels of the - same shape as `a` that index data along the given axis in sorted order. - - Parameters - ---------- - axis : int or str or Axis, optional - Axis along which to sort. - kind : {'quicksort', 'mergesort', 'heapsort'}, optional - Sorting algorithm. Defaults to 'quicksort'. - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FR', 'IT']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> arr = LArray([[0, 1], [3, 2], [2, 5]], [xnat, xsex]) - >>> arr - nat\\sex | H | F - BE | 0 | 1 - FR | 3 | 2 - IT | 2 | 5 - >>> arr.argsort(x.sex) - nat\\sex | 0 | 1 - BE | H | F - FR | F | H - IT | H | F - """ - if axis is None: - if self.ndim > 1: - raise ValueError("array has ndim > 1 and no axis specified for " - "argsort") - axis = self.axes[0] - axis, axis_idx = self.axes[axis], self.axes.index(axis) - data = axis.labels[self.data.argsort(axis_idx, kind=kind)] - new_axis = Axis(axis.name, np.arange(len(axis))) - return LArray(data, self.axes.replace(axis, new_axis)) - - def posargsort(self, axis=None, kind='quicksort'): - """ - Returns the indices that would sort this array. - - Perform an indirect sort along the given axis using the algorithm - specified by the `kind` keyword. It returns an array of indices - with the same axes as `a` that index data along the given axis in - sorted order. - - Parameters - ---------- - axis : int or str or Axis, optional - Axis along which to sort. - kind : {'quicksort', 'mergesort', 'heapsort'}, optional - Sorting algorithm. Defaults to 'quicksort'. - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FR', 'IT']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> arr = LArray([[0, 1], [3, 2], [2, 5]], [xnat, xsex]) - >>> arr - nat\\sex | H | F - BE | 0 | 1 - FR | 3 | 2 - IT | 2 | 5 - >>> arr.posargsort(x.sex) - nat\\sex | H | F - BE | 0 | 1 - FR | 1 | 0 - IT | 0 | 1 - """ - if axis is None: - if self.ndim > 1: - raise ValueError("array has ndim > 1 and no axis specified for " - "posargsort") - axis = self.axes[0] - axis, axis_idx = self.axes[axis], self.axes.index(axis) - return LArray(self.data.argsort(axis_idx, kind=kind), self.axes) - - def copy(self): - return LArray(self.data.copy(), axes=self.axes[:]) - - @property - def info(self): - """Describes a LArray (shape and labels for each axis). - - Returns - ------- - str - Description of the LArray (shape and labels for each axis). - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> mat0 = ones([xnat, xsex]) - >>> mat0.info - 2 x 2 - nat [2]: 'BE' 'FO' - sex [2]: 'H' 'F' - """ - return self.axes.info - - def ratio(self, *axes): - """Returns a LArray with values array / array.sum(axes). - - Parameters - ---------- - *axes - - Returns - ------- - LArray - array / array.sum(axes) - - Example - ------- - >>> age = Axis('age', range(3)) - >>> sex = Axis('sex', ['M', 'F']) - >>> a = ndrange([age, sex]) - >>> a - age\\sex | M | F - 0 | 0 | 1 - 1 | 2 | 3 - 2 | 4 | 5 - >>> a.sum() - 15 - >>> a.ratio() - age\\sex | M | F - 0 | 0.0 | 0.0666666666667 - 1 | 0.133333333333 | 0.2 - 2 | 0.266666666667 | 0.333333333333 - >>> a.ratio(sex) - age\\sex | M | F - 0 | 0.0 | 1.0 - 1 | 0.4 | 0.6 - 2 | 0.444444444444 | 0.555555555556 - >>> a.ratio('F') - age\\sex | M | F - 0 | 0.0 | 1.0 - 1 | 0.666666666667 | 1.0 - 2 | 0.8 | 1.0 - """ - # >>> FIXME, this does not work, but it should - # >>> NotImplementedError: an AxisReference (x.) cannot translate labels - # >>> b = a.sum((x.age[[0, 1]], x.age[[1, 2]])) - # This works though - # >>> a.sum(([0, 1], [1, 2])) - # age\\sex | M | F - # [0 1] | 2 | 4 - # [1 2] | 6 | 8 - # >>> a.sum((age[[0, 1]], age[2])) - # >>> a.sum(([0, 1], 2)) - # # this does not work, but I am unsure it should - # # >>> a.sum(age[[0, 1]], age[2]) / a.sum(age) - # >>> a.sum(([0, 1], 2)) / a.sum(age) - # # >>> a / a.sum(([0, 1], 2)) - # >>> a.sum(x.sex) - # >>> a.sum(x.age) - # >>> a.sum(x.sex) / a.sum(x.age) - # >>> a.ratio('F') - # could mean - # >>> a.sum('F') / a.sum(a.get_axis('F')) - # >>> a.sum('F') / a.sum(x.sex) - # age | 0 | 1 | 2 - # | 1.0 | 0.6 | 0.555555555556 - # OR (current meaning) - # >>> a / a.sum('F') - # age\\sex | M | F - # 0 | 0.0 | 1.0 - # 1 | 0.666666666667 | 1.0 - # 2 | 0.8 | 1.0 - # One solution is to add an argument - # >>> a.ratio(what='F', by=x.sex) - # age | 0 | 1 | 2 - # | 1.0 | 0.6 | 0.555555555556 - # >>> a.sum('F') / a.sum(x.sex) - - # >>> a.sum((age[[0, 1]], age[[1, 2]])) / a.sum(age) - # >>> a.ratio((age[[0, 1]], age[[1, 2]]), by=age) - - # >>> a.sum((x.age[[0, 1]], x.age[[1, 2]])) / a.sum(x.age) - # >>> a.ratio((x.age[[0, 1]], x.age[[1, 2]], by=x.age) - - # >>> lalala.sum(([0, 1], [1, 2])) / lalala.sum(x.age) - # >>> lalala.ratio(([0, 1], [1, 2]), by=x.age) - - # >>> b = a.sum((age[[0, 1]], age[[1, 2]])) - # >>> b - # age\sex | M | F - # [0 1] | 2 | 4 - # [1 2] | 6 | 8 - # >>> b / b.sum(x.age) - # age\\sex | M | F - # [0 1] | 0.25 | 0.333333333333 - # [1 2] | 0.75 | 0.666666666667 - # >>> b / a.sum(x.age) - # age\\sex | M | F - # [0 1] | 0.333333333333 | 0.444444444444 - # [1 2] | 1.0 | 0.888888888889 - # # >>> a.ratio([0, 1], [2]) - # # >>> a.ratio(x.age[[0, 1]], x.age[2]) - # >>> a.ratio((x.age[[0, 1]], x.age[2])) - # nat\\sex | H | F - # BE | 0.0 | 1.0 - # FO | 0.6666666666 | 1.0 - return self / self.sum(*axes) - - def percent(self, *axes): - """Returns a LArray with values LArray / LArray.sum(axes) * 100. - - Parameters - ---------- - *axes - - Returns - ------- - LArray - LArray = LArray / LArray.sum(axes) * 100 - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> mat = ndrange([xnat, xsex]) - >>> mat - nat\\sex | H | F - BE | 0 | 1 - FO | 2 | 3 - >>> mat.percent() - nat\\sex | H | F - BE | 0.0 | 16.6666666667 - FO | 33.3333333333 | 50.0 - >>> mat.percent(xsex) - nat\\sex | H | F - BE | 0.0 | 100.0 - FO | 40.0 | 60.0 - """ - # dividing by self.sum(*axes) * 0.01 would be faster in many cases but - # I suspect it loose more precision. - return self * 100 / self.sum(*axes) - - # aggregate method factory - def _agg_method(npfunc, nanfunc=None, name=None, commutative=False): - def method(self, *args, **kwargs): - keepaxes = kwargs.pop('keepaxes', False) - skipna = kwargs.pop('skipna', None) - if skipna is None: - skipna = nanfunc is not None - if skipna and nanfunc is None: - raise ValueError("skipna is not available for %s" % name) - func = nanfunc if skipna else npfunc - return self._aggregate(func, args, kwargs, - keepaxes=keepaxes, - commutative=commutative) - if name is None: - name = npfunc.__name__ - method.__name__ = name - return method - - all = _agg_method(np.all, commutative=True) - any = _agg_method(np.any, commutative=True) - # commutative modulo float precision errors - sum = _agg_method(np.sum, np.nansum, commutative=True) - # nanprod needs numpy 1.10 - prod = _agg_method(np.prod, np_nanprod, commutative=True) - min = _agg_method(np.min, np.nanmin, commutative=True) - max = _agg_method(np.max, np.nanmax, commutative=True) - mean = _agg_method(np.mean, np.nanmean, commutative=True) - median = _agg_method(np.median, np.nanmedian, commutative=True) - - # percentile needs an explicit method because it has not the same - # signature as other aggregate functions (extra argument) - def percentile(self, q, *args, **kwargs): - keepaxes = kwargs.pop('keepaxes', False) - skipna = kwargs.pop('skipna', None) - if skipna is None: - skipna = True - func = np.nanpercentile if skipna else np.percentile - return self._aggregate(func, args, kwargs, keepaxes=keepaxes, - commutative=True, extra_kwargs={'q': q}) - - # not commutative - ptp = _agg_method(np.ptp) - var = _agg_method(np.var, np.nanvar) - std = _agg_method(np.std, np.nanstd) - - # cumulative aggregates - def cumsum(self, axis): - return self._cum_aggregate(np.cumsum, axis) - - def cumprod(self, axis): - return self._cum_aggregate(np.cumprod, axis) - - # element-wise method factory - def _binop(opname): - fullname = '__%s__' % opname - super_method = getattr(np.ndarray, fullname) - - def opmethod(self, other): - res_axes = self.axes - if isinstance(other, LArray): - # TODO: first test if it is not already broadcastable - (self, other), res_axes = \ - make_numpy_broadcastable([self, other]) - other = other.data - elif isinstance(other, np.ndarray): - pass - elif other is None: - return False - elif not np.isscalar(other): - raise TypeError("unsupported operand type(s) for %s: '%s' " - "and '%s'" % (opname, type(self), type(other))) - return LArray(super_method(self.data, other), res_axes) - opmethod.__name__ = fullname - return opmethod - - __lt__ = _binop('lt') - __le__ = _binop('le') - __eq__ = _binop('eq') - __ne__ = _binop('ne') - __gt__ = _binop('gt') - __ge__ = _binop('ge') - __add__ = _binop('add') - __radd__ = _binop('radd') - __sub__ = _binop('sub') - __rsub__ = _binop('rsub') - __mul__ = _binop('mul') - __rmul__ = _binop('rmul') - if sys.version < '3': - __div__ = _binop('div') - __rdiv__ = _binop('rdiv') - __truediv__ = _binop('truediv') - __rtruediv__ = _binop('rtruediv') - __floordiv__ = _binop('floordiv') - __rfloordiv__ = _binop('rfloordiv') - __mod__ = _binop('mod') - __rmod__ = _binop('rmod') - __divmod__ = _binop('divmod') - __rdivmod__ = _binop('rdivmod') - __pow__ = _binop('pow') - __rpow__ = _binop('rpow') - __lshift__ = _binop('lshift') - __rlshift__ = _binop('rlshift') - __rshift__ = _binop('rshift') - __rrshift__ = _binop('rrshift') - __and__ = _binop('and') - __rand__ = _binop('rand') - __xor__ = _binop('xor') - __rxor__ = _binop('rxor') - __or__ = _binop('or') - __ror__ = _binop('ror') - - def __matmul__(self, other): - # TODO: implement for matrices of any dimensions - if not isinstance(other, (LArray, np.ndarray)): - raise NotImplementedError("matrix multiplication not " - "implemented for %s" % type(other)) - - if self.ndim != 2 or other.ndim != 2: - raise NotImplementedError("matrix multiplication not " - "implemented for ndim != 2 (%d @ %d)" - % (self.ndim, other.ndim)) - # 4,2 @ 2,3 = 4,3 - res_axes = [get_axis(self, 0), get_axis(other, 1)] - # TODO: implement AxisCollection.__init__(copy_duplicates=True) - if res_axes[1] is res_axes[0]: - res_axes[1] = res_axes[1].copy() - # XXX: check that other axes are compatible? - # other_axes = [get_axis(self, 1), get_axis(other, 0)] - # if not other_axes[0].iscompatible(other_axes[1]): - # raise ValueError("%s is not compatible with %s" - # % (other_axes[0], other_axes[1])) - return LArray(self.data.__matmul__(other.data), res_axes) - - def __rmatmul__(self, other): - if isinstance(other, np.ndarray): - other = LArray(other) - if not isinstance(other, LArray): - raise NotImplementedError("matrix multiplication not " - "implemented for %s" % type(other)) - return other.__matmul__(self) - - # element-wise method factory - def _unaryop(opname): - fullname = '__%s__' % opname - super_method = getattr(np.ndarray, fullname) - - def opmethod(self): - return LArray(super_method(self.data), self.axes) - opmethod.__name__ = fullname - return opmethod - - # unary ops do not need broadcasting so do not need to be overridden - __neg__ = _unaryop('neg') - __pos__ = _unaryop('pos') - __abs__ = _unaryop('abs') - __invert__ = _unaryop('invert') - - def __round__(self, n=0): - # XXX: use the ufuncs.round instead? - return np.round(self, decimals=n) - - def divnot0(self, other): - """divide array by other, but where other is 0 return 0.0 - - Parameters - ---------- - other : scalar or LArray - what to divide by - - Returns - ------- - LArray - array divided by other, 0.0 where other is 0 - - Example - ------- - >>> nat = Axis('nat', ['BE', 'FO']) - >>> sex = Axis('sex', ['M', 'F']) - >>> a = ndrange((nat, sex)) - >>> a - nat\\sex | M | F - BE | 0 | 1 - FO | 2 | 3 - >>> b = ndrange(sex) - >>> b - sex | M | F - | 0 | 1 - >>> a / b - nat\\sex | M | F - BE | nan | 1.0 - FO | inf | 3.0 - >>> a.divnot0(b) - nat\\sex | M | F - BE | 0.0 | 1.0 - FO | 0.0 | 3.0 - """ - if np.isscalar(other): - if other == 0: - return zeros_like(self, dtype=float) - else: - return self / other - else: - res = self / other - res[other == 0] = 0 - return res - - # XXX: rename/change to "add_axes" ? - # TODO: add a flag copy=True to force a new array. - def expand(self, target_axes=None, out=None, readonly=False): - """expands array to target_axes - - target_axes will be added to array if not present. In most cases this - function is not needed because LArray can do operations with arrays - having different (compatible) axes. - - Parameters - ---------- - target_axes : list of Axis or AxisCollection, optional - self can contain axes not present in target_axes. The result axes will be: - [self.axes not in target_axes] + target_axes - out : LArray, optional - output array, must have the correct shape - readonly : bool, optional - whether returning a readonly view is acceptable or not (this is - much faster) - - Returns - ------- - LArray - original array if possible (and out is None) - - Example - ------- - >>> a = Axis('a', ['a1', 'a2']) - >>> b = Axis('b', ['b1', 'b2']) - >>> arr = ndrange([a, b]) - >>> arr - a\\b | b1 | b2 - a1 | 0 | 1 - a2 | 2 | 3 - >>> c = Axis('c', ['c1', 'c2']) - >>> arr.expand([a, c, b]) - a | c\\b | b1 | b2 - a1 | c1 | 0 | 1 - a1 | c2 | 0 | 1 - a2 | c1 | 2 | 3 - a2 | c2 | 2 | 3 - >>> arr.expand([b, c]) - a | b\\c | c1 | c2 - a1 | b1 | 0 | 0 - a1 | b2 | 1 | 1 - a2 | b1 | 2 | 2 - a2 | b2 | 3 | 3 - """ - if (target_axes is None and out is None or - target_axes is not None and out is not None): - raise ValueError("either target_axes or out must be defined " - "(not both)") - if out is not None: - target_axes = out.axes - else: - if not isinstance(target_axes, AxisCollection): - target_axes = AxisCollection(target_axes) - target_axes = (self.axes - target_axes) | target_axes - if out is None and self.axes == target_axes: - return self - - # TODO: this is not necessary if out is not None ([:] already broadcast) - broadcasted = self.broadcast_with(target_axes) - # this can only happen if only the order of axes differed - if out is None and broadcasted.axes == target_axes: - return broadcasted - - if out is None: - if readonly: - # requires numpy 1.10 - return LArray(np.broadcast_to(broadcasted, target_axes.shape), - target_axes) - else: - out = LArray(np.empty(target_axes.shape, dtype=self.dtype), - target_axes) - out[:] = broadcasted - return out - - def append(self, axis, value, label=None): - """Adds a LArray to a LArray ('self') along an axis. - - Parameters - ---------- - axis : axis - the axis - value : LArray - LArray with compatible axes - label : string - optional - label for the new item in axis - - Returns - ------- - LArray - LArray expanded with 'value' along 'axis'. - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> xtype = Axis('type', ['type1', 'type2']) - >>> mat = ones([xnat, xsex]) - >>> mat - nat\\sex | H | F - BE | 1.0 | 1.0 - FO | 1.0 | 1.0 - >>> mat.append(x.sex, mat.sum(x.sex), 'H+F') - nat\\sex | H | F | H+F - BE | 1.0 | 1.0 | 2.0 - FO | 1.0 | 1.0 | 2.0 - >>> mat.append(x.nat, 2, 'Other') - nat\\sex | H | F - BE | 1.0 | 1.0 - FO | 1.0 | 1.0 - Other | 2.0 | 2.0 - >>> arr2 = zeros([xtype]) - >>> arr2 - type | type1 | type2 - | 0.0 | 0.0 - >>> mat.append(x.nat, arr2, 'Other') - nat | sex\\type | type1 | type2 - BE | H | 1.0 | 1.0 - BE | F | 1.0 | 1.0 - FO | H | 1.0 | 1.0 - FO | F | 1.0 | 1.0 - Other | H | 0.0 | 0.0 - Other | F | 0.0 | 0.0 - """ - axis = self.axes[axis] - if np.isscalar(value): - value = LArray(np.asarray(value, self.dtype), []) - # this does not prevent value to have more axes than self - target_axes = self.axes.replace(axis, Axis(axis.name, [label])) - value = value.broadcast_with(target_axes) - return self.extend(axis, value) - - def prepend(self, axis, value, label=None): - """Adds a LArray before 'self' along an axis. - - Parameters - ---------- - axis : axis - the axis - value : LArray - LArray with compatible axes - label : string - optional - label for the new item in axis - - Returns - ------- - LArray - LArray expanded with 'value' at the start of 'axis'. - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> xtype = Axis('type', ['type1', 'type2', 'type3']) - >>> mat = ones([xnat, xsex, xtype]) - >>> mat - nat | sex\\type | type1 | type2 | type3 - BE | H | 1.0 | 1.0 | 1.0 - BE | F | 1.0 | 1.0 | 1.0 - FO | H | 1.0 | 1.0 | 1.0 - FO | F | 1.0 | 1.0 | 1.0 - >>> mat.prepend(x.type, mat.sum(x.type), 'type0') - nat | sex\\type | type0 | type1 | type2 | type3 - BE | H | 3.0 | 1.0 | 1.0 | 1.0 - BE | F | 3.0 | 1.0 | 1.0 | 1.0 - FO | H | 3.0 | 1.0 | 1.0 | 1.0 - FO | F | 3.0 | 1.0 | 1.0 | 1.0 - >>> mat.prepend(x.type, 2, 'type0') - nat | sex\\type | type0 | type1 | type2 | type3 - BE | H | 2.0 | 1.0 | 1.0 | 1.0 - BE | F | 2.0 | 1.0 | 1.0 | 1.0 - FO | H | 2.0 | 1.0 | 1.0 | 1.0 - FO | F | 2.0 | 1.0 | 1.0 | 1.0 - """ - axis = self.axes[axis] - if np.isscalar(value): - value = LArray(np.asarray(value, self.dtype), []) - # this does not prevent value to have more axes than self - target_axes = self.axes.replace(axis, Axis(axis.name, [label])) - # we cannot simply add the "new" axis to value because in that case - # the resulting axes would not be in the correct order - value = value.broadcast_with(target_axes) - return value.extend(axis, self) - - def extend(self, axis, other): - """Adds a LArray to a LArray ('self') along an axis. - - Parameters - ---------- - axis : axis - the axis - other : LArray - LArray with compatible axes - - Returns - ------- - LArray - LArray expanded with 'other' along 'axis'. - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> xsex2 = Axis('sex', ['U']) - >>> xtype = Axis('type', ['type1', 'type2']) - >>> arr1 = ones([xsex, xtype]) - >>> arr1 - sex\\type | type1 | type2 - H | 1.0 | 1.0 - F | 1.0 | 1.0 - >>> arr2 = zeros([xsex2, xtype]) - >>> arr2 - sex\\type | type1 | type2 - U | 0.0 | 0.0 - >>> arr1.extend(x.sex, arr2) - sex\\type | type1 | type2 - H | 1.0 | 1.0 - F | 1.0 | 1.0 - U | 0.0 | 0.0 - >>> arr3 = zeros([xsex2, xnat]) - >>> arr3 - sex\\nat | BE | FO - U | 0.0 | 0.0 - >>> arr1.extend(x.sex, arr3) - sex | type\\nat | BE | FO - H | type1 | 1.0 | 1.0 - H | type2 | 1.0 | 1.0 - F | type1 | 1.0 | 1.0 - F | type2 | 1.0 | 1.0 - U | type1 | 0.0 | 0.0 - U | type2 | 0.0 | 0.0 - """ - result, self_target, other_target = \ - concat_empty(axis, self.axes, other.axes, self.dtype) - self.expand(out=self_target) - other.expand(out=other_target) - return result - - def transpose(self, *args): - """ - reorder axes - - accepts either a tuple of axes specs or axes specs as *args - - Parameters - ---------- - *args - accepts either a tuple of axes specs or axes specs as *args - - Returns - ------- - LArray - LArray with reordered axes. - - Example - ------- - >>> nat = Axis('nat', ['BE', 'FO']) - >>> sex = Axis('sex', ['M', 'F']) - >>> alive = Axis('alive', [False, True]) - >>> a = ndrange([nat, sex, alive]) - >>> a - nat | sex\\alive | False | True - BE | M | 0 | 1 - BE | F | 2 | 3 - FO | M | 4 | 5 - FO | F | 6 | 7 - >>> a.transpose(alive, sex, nat) - alive | sex\\nat | BE | FO - False | M | 0 | 4 - False | F | 2 | 6 - True | M | 1 | 5 - True | F | 3 | 7 - >>> a.transpose(alive) - alive | nat\\sex | M | F - False | BE | 0 | 2 - False | FO | 4 | 6 - True | BE | 1 | 3 - True | FO | 5 | 7 - """ - if len(args) == 1 and isinstance(args[0], - (tuple, list, AxisCollection)): - axes = args[0] - elif len(args) == 0: - axes = self.axes[::-1] - else: - axes = args - - axes_indices = [self.axes.index(axis) for axis in axes] - indices_present = set(axes_indices) - missing_indices = [i for i in range(len(self.axes)) - if i not in indices_present] - axes_indices = axes_indices + missing_indices - src_data = np.asarray(self) - res_data = src_data.transpose(axes_indices) - return LArray(res_data, self.axes[axes_indices]) - - # if len(args) == 1 and isinstance(args[0], - # (tuple, list, AxisCollection)): - # axes = args[0] - # else: - # axes = args - # # this SHOULD work but does not currently for positional axes - # # on anonymous axes. e.g. axes = (1, 2) because that ends up - # # trying to do: - # # self.axes[(1, 2)] | self.axes - # # self.axes[(1, 2)] | self.axes[0] - # # since self.axes[0] does not exist in self.axes[1, 2], BUT has - # # a position < len(self.axes[1, 2]), it tries to match - # # against self.axes[1, 2][0], (ie self.axes[1]) which breaks - # res_axes = (self.axes[axes] | self.axes) if axes else self.axes[::-1] - # axes_indices = [self.axes.index(axis) for axis in res_axes] - # res_data = np.asarray(self).transpose(axes_indices) - # return LArray(res_data, res_axes) - T = property(transpose) - - def clip(self, a_min, a_max, out=None): - from larray.ufuncs import clip - return clip(self, a_min, a_max, out) - - def to_csv(self, filepath, sep=',', na_rep='', transpose=True, - dropna=None, dialect='default', **kwargs): - """ - write LArray to a csv file. - - Parameters - ---------- - filepath : string - path where the csv file has to be written. - sep : string - seperator for the csv file. - na_rep : string - replace NA values with na_rep. - transpose : boolean - transpose = True => transpose over last axis. - transpose = False => no transpose. - dialect : 'default' | 'classic' - Whether or not to write the last axis name (using '\' ) - dropna : None, 'all', 'any' or True, optional - Drop lines if 'all' its values are NA, if 'any' value is NA or do - not drop any line (default). True is equivalent to 'all'. - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> mat = ndrange([xnat, xsex]) - >>> mat - nat\\sex | H | F - BE | 0 | 1 - FO | 2 | 3 - >>> mat.to_csv('test.csv') - >>> with open('test.csv') as f: - ... print(f.read().strip()) - nat\\sex,H,F - BE,0,1 - FO,2,3 - >>> mat.to_csv('test.csv', sep=';', transpose=False) - >>> with open('test.csv') as f: - ... print(f.read().strip()) - nat;sex;0 - BE;H;0 - BE;F;1 - FO;H;2 - FO;F;3 - >>> mat.to_csv('test.csv', dialect='classic') - >>> with open('test.csv') as f: - ... print(f.read().strip()) - nat,H,F - BE,0,1 - FO,2,3 - """ - fold = dialect == 'default' - if transpose: - frame = self.to_frame(fold, dropna) - frame.to_csv(filepath, sep=sep, na_rep=na_rep, **kwargs) - else: - series = self.to_series(dropna is not None) - series.to_csv(filepath, sep=sep, na_rep=na_rep, header=True, - **kwargs) - - def to_hdf(self, filepath, key, *args, **kwargs): - """ - write LArray to a HDF file - - a HDF file can contain multiple LArray's. The 'key' parameter - is a unique identifier for the LArray. - - Parameters - ---------- - filepath : string - path where the hdf file has to be written. - key : string - name of the matrix within the HDF file. - *args - **kargs - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> mat = ndrange([xnat, xsex]) - >>> mat.to_hdf('test.h5', 'mat') - """ - self.to_frame().to_hdf(filepath, key, *args, **kwargs) - - def to_excel(self, filepath=None, sheet_name=None, position='A1', - overwrite_file=False, clear_sheet=False, header=True, - transpose=False, engine=None, *args, **kwargs): - """ - write LArray in the specified sheet of specified excel workbook - - Parameters - ---------- - filepath : str or int or None, optional - path where the excel file has to be written. If None (default), - creates a new Excel Workbook in a live Excel instance - (Windows only). Use -1 to use the currently active Excel - Workbook. Use a name without extension (.xlsx) to use any - *unsaved* workbook. - sheet_name : str or int or None, optional - sheet where the data has to be written. Defaults to None, - Excel standard name if adding a sheet to an existing file, - "Sheet1" otherwise. sheet_name can also refer to the position of - the sheet (e.g. 0 for the first sheet, -1 for the last one). - position : str or tuple of integers, optional - Integer position (row, column) must be 1-based. Defaults to 'A1'. - overwrite_file : bool, optional - whether or not to overwrite the existing file (or just modify the - specified sheet). Defaults to False. - clear_sheet : bool, optional - whether or not to clear the existing sheet (if any) before writing. - Defaults to False. - header : bool, optional - whether or not to write a header (axes names and labels). - Defaults to True. - transpose : bool, optional - whether or not to transpose the resulting array. This can be used, - for example, for writing one dimensional arrays vertically. - Defaults to False. - engine : 'xlwings' | 'openpyxl' | 'xlsxwriter' | 'xlwt' | None, optional - engine to use to make the output. If None (default), it will use - 'xlwings' by default if the module is installed and relies on - Pandas default writer otherwise. - *args - **kargs - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> a = ndrange([xnat, xsex]) - >>> # write to a new (unnamed) sheet - >>> a.to_excel('test.xlsx') # doctest: +SKIP - >>> # write to top-left corner of an existing sheet - >>> a.to_excel('test.xlsx', 'Sheet1') # doctest: +SKIP - >>> # add to existing sheet starting at position A15 - >>> a.to_excel('test.xlsx', 'Sheet1', 'A15') # doctest: +SKIP - """ - df = self.to_frame(fold_last_axis_name=True) - if engine is None: - engine = 'xlwings' if xw is not None else None - - if engine == 'xlwings': - save = False - close = False - new_workbook = False - if filepath == -1: - wb = xw.Workbook.active() - elif filepath is None: - # creates a new/blank Workbook - wb = xw.Workbook(app_visible=True) - new_workbook = True - else: - basename, ext = os.path.splitext(filepath) - if ext: - # XXX: we might want to be more precise than .xl* because - # I am unsure writing anything else than .xlsx will - # work as intended - if not ext.startswith('.xl'): - raise ValueError("'%s' is not a supported file " - "extension" % ext) - - # This is necessary because otherwise we cannot open/save to - # a workbook in the current directory without giving the - # full/absolute path. By doing this, we basically loose the - # ability to target an already open workbook *of a saved - # file* not in the current directory without using its - # path. I can live with that restriction though because you - # usually either work with relative paths or with the - # currently active workbook. - filepath = os.path.abspath(filepath) - save = True - close = not xw.xlplatform.is_file_open(filepath) - if os.path.isfile(filepath) and overwrite_file: - os.remove(filepath) - - # file already exists (and is a file) - if os.path.isfile(filepath): - # do not change Excel visibility - wb = xw.Workbook(filepath, app_visible=None) - else: - # open new workbook, do not change Excel visibility - wb = xw.Workbook(app_visible=None) - new_workbook = True - else: - # try to open an existing unsaved workbook - # XXX: I wonder if app_visible=None wouldn't be better in this case? - wb = xw.Workbook(filepath, app_visible=True) - - def sheet_exists(wb, sheet): - if isinstance(sheet, int): - length = xw.Sheet.count(wb) - return -length <= sheet < length - else: - assert isinstance(sheet_name, str) - sheet_names = [i.name.lower() for i in xw.Sheet.all(wkb=wb)] - return sheet_name.lower() in sheet_names - - if new_workbook: - sheet = xw.Sheet(1, wkb=wb) - if sheet_name is not None: - sheet.name = sheet_name - elif sheet_name is not None and sheet_exists(wb, sheet_name): - if isinstance(sheet_name, int): - if sheet_name < 0: - sheet_name += xw.Sheet.count(wb) - sheet_name += 1 - sheet = xw.Sheet(sheet_name, wkb=wb) - if clear_sheet: - sheet.clear() - else: - sheet = xw.Sheet.add(sheet_name, wkb=wb) - - options = dict(header=header, index=header, transpose=transpose) - xw.Range(sheet, position).options(**options).value = df - if save: - wb.save(filepath) - if close: - wb.close() - # using app.quit() unconditionally is NOT a good idea because - # it quits excel even if there are other workbooks open. - # XXX: we might want to use: - # app = xw.Application(wb) - # wbs = xw.xlplatform.get_all_open_xl_workbooks(app.xl_app) - # if not wbs: - # app.quit() - # but it is not cross-platform (get_all_open_xl...) - else: - if sheet_name is None: - sheet_name = 'Sheet1' - # TODO: implement position in this case - # startrow, startcol - df.to_excel(filepath, sheet_name, *args, engine=engine, **kwargs) - - def to_clipboard(self, *args, **kwargs): - """ - sends the content of a LArray to clipboard - - using to_clipboard() makes it possible to paste the content of LArray - into a file (Excel, ascii file,...) - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> mat = ndrange([xnat, xsex]) - >>> mat.to_clipboard() # doctest: +SKIP - """ - self.to_frame().to_clipboard(*args, **kwargs) - - # XXX: sep argument does not seem very useful - # def to_excel(self, filename, sep=None): - # # Why xlsxwriter? Because it is faster than openpyxl and xlwt - # # currently does not .xlsx (only .xls). - # # PyExcelerate seem like a decent alternative too - # import xlsxwriter as xl - # - # if sep is None: - # sep = '_' - # #sep = self.sep - # workbook = xl.Workbook(filename) - # if self.ndim > 2: - # for key in product(*[axis.labels for axis in self.axes[:-2]]): - # sheetname = sep.join(str(k) for k in key) - # # sheet names must not: - # # * contain any of the following characters: : \ / ? * [ ] - # # XXX: this will NOT work for unicode strings ! - # table = string.maketrans('[:]', '(-)') - # todelete = r'\/?*' - # sheetname = sheetname.translate(table, todelete) - # # * exceed 31 characters - # # sheetname = sheetname[:31] - # # * be blank - # assert sheetname, "sheet name cannot be blank" - # worksheet = workbook.add_worksheet(sheetname) - # worksheet.write_row(0, 1, self.axes[-1].labels) - # worksheet.write_column(1, 0, self.axes[-2].labels) - # for row, data in enumerate(np.asarray(self[key])): - # worksheet.write_row(1+row, 1, data) - # - # else: - # worksheet = workbook.add_worksheet('Sheet1') - # worksheet.write_row(0, 1, self.axes[-1].labels) - # if self.ndim == 2: - # worksheet.write_column(1, 0, self.axes[-2].labels) - # for row, data in enumerate(np.asarray(self)): - # worksheet.write_row(1+row, 1, data) - - @property - def plot(self): - """ - plots the data of a LArray into a graph (window pop-up). - - the graph can be tweaked to achieve the desired formatting and can be - saved to a .png file - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> xtype = Axis('type',['type1', 'type2', 'type3']) - >>> mat = ndrange([xnat, xsex, xtype]) - >>> mat.plot() # doctest: +SKIP - """ - return self.to_frame().plot - - @property - def shape(self): - """ - returns string representation of current shape. - - Returns - ------- - returns string representation of current shape. - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> xtype = Axis('type',['type1', 'type2', 'type3']) - >>> mat = ndrange([xnat, xsex, xtype]) - >>> mat.shape # doctest: +SKIP - (2, 2, 3) - """ - return self.data.shape - - @property - def ndim(self): - """ - returns the number of dimensions of a LArray. - - Returns - ------- - returns the number of dimensions of a LArray. - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> xtype = Axis('type',['type1', 'type2', 'type3']) - >>> mat = ndrange([xnat, xsex, xtype]) - >>> mat.ndim - 3 - """ - return self.data.ndim - - @property - def size(self): - """ - returns the number of cells in a LArray. - - Returns - ------- - integer - returns the number of cells in a LArray. - - Example - ------- - >>> xsex = Axis('sex', ['H', 'F']) - >>> xtype = Axis('type', ['type1', 'type2', 'type3']) - >>> mat = ndrange([xsex, xtype]) - >>> mat.size - 6 - """ - return self.data.size - - @property - def nbytes(self): - """ - returns the number of bytes in a LArray. - - Returns - ------- - integer - returns the number of bytes in a LArray. - - Example - ------- - >>> xsex = Axis('sex', ['H', 'F']) - >>> xtype = Axis('type', ['type1', 'type2', 'type3']) - >>> mat = ndrange([xsex, xtype], dtype=float) - >>> mat.nbytes - 48 - """ - return self.data.nbytes - - @property - def dtype(self): - """ - returns the type of the data in the cells of LArray. - - Returns - ------- - string - returns the type of the data in the cells of LArray. - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> xtype = Axis('type',['type1', 'type2', 'type3']) - >>> mat = zeros([xnat, xsex, xtype]) - >>> mat.dtype - dtype('float64') - """ - return self.data.dtype - - @property - def item(self): - return self.data.item - - def __len__(self): - return len(self.data) - - def __array__(self, dtype=None): - return self.data - - __array_priority__ = 100 - - def set_labels(self, axis, labels, inplace=False): - """ - replaces the labels of axis of a LArray - - Parameters - ---------- - axis - the axis for which we want to replace the labels. - labels : list of axis labels - the new labels. - inplace : boolean - whether or not to modify the original object or return a new - LArray and leave the original intact. - - Returns - ------- - LArray - LArray with modified labels. - - Example - ------- - >>> nat = Axis('nat', ['BE', 'FO']) - >>> sex = Axis('sex', ['M', 'F']) - >>> a = ndrange([nat, sex]) - >>> a - nat\\sex | M | F - BE | 0 | 1 - FO | 2 | 3 - >>> a.set_labels(x.sex, ['Men', 'Women']) - nat\\sex | Men | Women - BE | 0 | 1 - FO | 2 | 3 - """ - axis = self.axes[axis] - if inplace: - axis.labels = labels - return self - else: - return LArray(self.data, - self.axes.replace(axis, Axis(axis.name, labels))) - - def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True): - return LArray(self.data.astype(dtype, order, casting, subok, copy), - self.axes) - astype.__doc__ = np.ndarray.astype.__doc__ - - def shift(self, axis, n=1): - """ - shifts the cells of a LArray n-times to the left along axis. - - Parameters - ---------- - axis : int, str or Axis - the axis for which we want to perform the shift. - n : int - the number of cells to shift. - - Returns - ------- - LArray - - Example - ------- - >>> sex = Axis('sex', ['M', 'F']) - >>> xtype = Axis('type',['type1', 'type2', 'type3']) - >>> mat = ndrange([sex, xtype]) - >>> mat - sex\\type | type1 | type2 | type3 - M | 0 | 1 | 2 - F | 3 | 4 | 5 - >>> mat.shift(x.type) - sex\\type | type2 | type3 - M | 0 | 1 - F | 3 | 4 - >>> mat.shift(x.type, n=-1) - sex\\type | type1 | type2 - M | 1 | 2 - F | 4 | 5 - """ - axis = self.axes[axis] - if n > 0: - return self[axis.i[:-n]].set_labels(axis, axis.labels[n:]) - elif n < 0: - return self[axis.i[-n:]].set_labels(axis, axis.labels[:n]) - else: - return self[:] - - def diff(self, axis=-1, d=1, n=1, label='upper'): - """ - Calculate the n-th order discrete difference along a given axis. - - The first order difference is given by out[n] = a[n + 1] - a[n] along the - given axis, higher order differences are calculated by using diff - recursively. - - Parameters - ---------- - axis : int, str or Axis, optional - The axis along which the difference is taken. Defaults to the last - axis. - - d : int, optional - Periods to shift for forming difference. Defaults to 1. - - n : int, optional - The number of times values are differenced. Defaults to 1. - - label : 'lower' or 'upper', optional - The new labels in `axis` will have the labels of either - the array being subtracted ('lower') or the array it is - subtracted from ('upper'). Defaults to 'upper'. - - Returns - ------- - LArray : The n-th order differences. The shape of the output is the same - as `a` except for `axis` which is smaller by `n` * `d`. - - Example - ------- - >>> sex = Axis('sex', ['M', 'F']) - >>> xtype = Axis('type', ['type1', 'type2', 'type3']) - >>> a = ndrange([sex, xtype]).cumsum(x.type) - >>> a - sex\\type | type1 | type2 | type3 - M | 0 | 1 | 3 - F | 3 | 7 | 12 - >>> a.diff() - sex\\type | type2 | type3 - M | 1 | 2 - F | 4 | 5 - >>> a.diff(n=2) - sex\\type | type3 - M | 1 - F | 1 - >>> a.diff(x.sex) - sex\\type | type1 | type2 | type3 - F | 3 | 6 | 9 - """ - array = self - for _ in range(n): - axis_obj = array.axes[axis] - left = array[axis_obj.i[d:]] - right = array[axis_obj.i[:-d]] - if label == 'upper': - right = right.drop_labels(axis) - else: - left = left.drop_labels(axis) - array = left - right - return array - - # XXX: this is called pct_change in Pandas (but returns the same results, - # not results * 100, which I find silly). Maybe change_rate would be - # better (because growth is not always positive)? - def growth_rate(self, axis=-1, d=1, label='upper'): - """ - Calculate the growth along a given axis. - - roughly equivalent to a.diff(axis, d, label) / a[axis.i[:-d]] - - Parameters - ---------- - axis : int, str or Axis, optional - The axis along which the difference is taken. Defaults to the last - axis. - - d : int, optional - Periods to shift for forming difference. Defaults to 1. - - label : 'lower' or 'upper', optional - The new labels in `axis` will have the labels of either - the array being subtracted ('lower') or the array it is - subtracted from ('upper'). Defaults to 'upper'. - - Returns - ------- - LArray - - Example - ------- - >>> sex = Axis('sex', ['M', 'F']) - >>> year = Axis('year', [2015, 2016, 2017]) - >>> a = ndrange([sex, year]).cumsum(x.year) - >>> a - sex\\year | 2015 | 2016 | 2017 - M | 0 | 1 | 3 - F | 3 | 7 | 12 - >>> a.growth_rate() - sex\\year | 2016 | 2017 - M | inf | 2.0 - F | 1.33333333333 | 0.714285714286 - >>> a.growth_rate(d=2) - sex\\year | 2017 - M | inf - F | 3.0 - """ - diff = self.diff(axis=axis, d=d, label=label) - axis_obj = self.axes[axis] - return diff / self[axis_obj.i[:-d]].drop_labels(axis) - - -def parse(s): - """ - used to parse the "folded" axis ticks (usually periods) - """ - # parameters can be strings or numbers - if isinstance(s, basestring): - s = s.strip() - low = s.lower() - if low == 'true': - return True - elif low == 'false': - return False - elif s.isdigit(): - return int(s) - else: - try: - return float(s) - except ValueError: - return s - else: - return s - - -def df_labels(df, sort=True): - """ - returns unique labels for each dimension - """ - idx = df.index - if isinstance(idx, pd.core.index.MultiIndex): - if sort: - return list(idx.levels) - else: - return [list(unique(idx.get_level_values(l))) for l in idx.names] - else: - assert isinstance(idx, pd.core.index.Index) - # use .values if needed - return [idx] - - -def cartesian_product_df(df, sort_rows=False, sort_columns=False, **kwargs): - labels = df_labels(df, sort=sort_rows) - if sort_rows: - new_index = pd.MultiIndex.from_product(labels) - else: - new_index = pd.MultiIndex.from_tuples(list(product(*labels))) - columns = sorted(df.columns) if sort_columns else list(df.columns) - # the prodlen test is meant to avoid the more expensive array_equal test - prodlen = np.prod([len(axis_labels) for axis_labels in labels]) - if prodlen == len(df) and columns == list(df.columns) and \ - np.array_equal(df.index.values, new_index.values): - return df, labels - return df.reindex(new_index, columns, **kwargs), labels - - -def df_aslarray(df, sort_rows=False, sort_columns=False, **kwargs): - axes_names = [decode(name, 'utf8') for name in df.index.names] - if isinstance(axes_names[-1], basestring) and '\\' in axes_names[-1]: - last_axes = [name.strip() for name in axes_names[-1].split('\\')] - axes_names = axes_names[:-1] + last_axes - elif len(df) == 1 and axes_names == [None]: - axes_names = [df.columns.name] - elif len(df) > 1: - axes_names += [df.columns.name] - - if len(axes_names) > 1: - df, axes_labels = cartesian_product_df(df, sort_rows=sort_rows, - sort_columns=sort_columns, - **kwargs) - else: - axes_labels = [] - - # we could inline df_aslarray into the functions that use it, so that the - # original (non-cartesian) df is freed from memory at this point, but it - # would be much uglier and would not lower the peak memory usage which - # happens during cartesian_product_df.reindex - - # pandas treats the "time" labels as column names (strings) so we need - # to convert them to values - axes_labels.append([parse(cell) for cell in df.columns.values]) - - axes = [Axis(name, labels) for name, labels in zip(axes_names, axes_labels)] - data = df.values.reshape([len(axis) for axis in axes]) - return LArray(data, axes) - - -def read_csv(filepath, nb_index=0, index_col=[], sep=',', headersep=None, - na=np.nan, sort_rows=False, sort_columns=False, - dialect='larray', **kwargs): - """ - reads csv file and returns a Larray with the contents - - Note - ---- - csv file format: - arr,ages,sex,nat\time,1991,1992,1993 - A1,BI,H,BE,1,0,0 - A1,BI,H,FO,2,0,0 - A1,BI,F,BE,0,0,1 - A1,BI,F,FO,0,0,0 - A1,A0,H,BE,0,0,0 - - Parameters - ---------- - filepath : str - path where the csv file has to be written. - nb_index : int, optional - number of leading index columns (ex. 4). - index_col : list, optional - list of columns for the index (ex. [0, 1, 2, 3]). - sep : str, optional - separator. - headersep : str or None, optional - ???. - na : ??? - ???. - sort_rows : bool, optional - Whether or not to sort the row dimensions alphabetically (sorting is - more efficient than not sorting). Defaults to False. - sort_columns : bool, optional - Whether or not to sort the column dimension alphabetically (sorting is - more efficient than not sorting). Defaults to False. - dialect : 'classic' | 'larray' | 'liam2', optional - Name of dialect. Defaults to 'larray'. - **kwargs - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> mat = ndrange([xnat, xsex]) - >>> mat.to_csv('test.csv') - >>> read_csv('test.csv') - nat\\sex | H | F - BE | 0 | 1 - FO | 2 | 3 - >>> read_csv('test.csv', sort_columns=True) - nat\\sex | F | H - BE | 1 | 0 - FO | 3 | 2 - >>> mat.to_csv('no_axis_name.csv', dialect='classic') - >>> read_csv('no_axis_name.csv', nb_index=1) - nat\\{1} | H | F - BE | 0 | 1 - FO | 2 | 3 - """ - # read the first line to determine how many axes (time excluded) we have - with csv_open(filepath) as f: - reader = csv.reader(f, delimiter=sep) - line_stream = skip_comment_cells(strip_rows(reader)) - header = next(line_stream) - if headersep is not None and headersep != sep: - combined_axes_names = header[0] - header = combined_axes_names.split(headersep) - try: - # take the first cell which contains '\' - pos_last = next(i for i, v in enumerate(header) if '\\' in v) - except StopIteration: - # if there isn't any, assume 1d array, unless "liam2 dialect" - pos_last = 0 if dialect != 'liam2' else len(header) - 1 - axes_names = header[:pos_last + 1] - - if len(index_col) == 0 and nb_index == 0: - nb_index = len(axes_names) - if dialect == 'liam2': - nb_index -= 1 - - if len(index_col) > 0: - nb_index = len(index_col) - else: - index_col = list(range(nb_index)) - - if headersep is not None: - # we will set the index after having split the tick values - index_col = None - - if dialect == 'liam2': - if len(axes_names) < 2: - index_col = None - # FIXME: add number of lines skipped by comments (or not, pandas - # might skip them by default) - kwargs['skiprows'] = 1 - kwargs['comment'] = '#' - df = pd.read_csv(filepath, index_col=index_col, sep=sep, **kwargs) - if dialect == 'liam2': - if len(axes_names) > 1: - df.index.names = axes_names[:-1] - df.columns.name = axes_names[-1] - if headersep is not None: - labels_column = df[combined_axes_names] - label_columns = unzip(label.split(headersep) for label in labels_column) - for name, column in zip(axes_names, label_columns): - df[name] = column - del df[combined_axes_names] - df.set_index(axes_names, inplace=True) - - return df_aslarray(df, sort_rows=sort_rows, sort_columns=sort_columns, - fill_value=na) - - -def read_tsv(filepath, **kwargs): - return read_csv(filepath, sep='\t', **kwargs) - - -def read_eurostat(filepath, **kwargs): - """Read EUROSTAT TSV (tab-separated) file into an LArray - - EUROSTAT TSV files are special because they use tabs as data - separators but comas to separate headers. - - Parameters - ---------- - filepath : str - Path to the file - kwargs - Arbitrary keyword arguments are passed through to read_csv - - Returns - ------- - LArray - """ - return read_csv(filepath, sep='\t', headersep=',', **kwargs) - - -def read_hdf(filepath, key, na=np.nan, sort_rows=False, sort_columns=False, - **kwargs): - """Reads a LArray named key from a h5 file in filepath (path+name) - - Parameters - ---------- - filepath : str - the filepath and name where the h5 file is stored. - key : str - the name of the LArray - - Returns - ------- - LArray - """ - df = pd.read_hdf(filepath, key, **kwargs) - return df_aslarray(df, sort_rows=sort_rows, sort_columns=sort_columns, - fill_value=na) - - -def read_excel(filepath, sheetname=0, nb_index=0, index_col=[], - na=np.nan, sort_rows=False, sort_columns=False, **kwargs): - """ - reads excel file from sheet name and returns an LArray with the contents - nb_index: number of leading index columns (e.g. 4) - or - index_col: list of columns for the index (e.g. [0, 1, 3]) - """ - if isinstance(index_col, list) and len(index_col) == 0: - index_col = list(range(nb_index)) - df = pd.read_excel(filepath, sheetname, index_col=index_col, **kwargs) - return df_aslarray(df, sort_rows=sort_rows, sort_columns=sort_columns, - fill_value=na) - - -def read_sas(filepath, nb_index=0, index_col=[], - na=np.nan, sort_rows=False, sort_columns=False, **kwargs): - """ - reads sas file and returns an LArray with the contents - nb_index: number of leading index columns (e.g. 4) - or - index_col: list of columns for the index (e.g. [0, 1, 3]) - """ - if len(index_col) == 0: - index_col = list(range(nb_index)) - df = pd.read_sas(filepath, index=index_col, **kwargs) - return df_aslarray(df, sort_rows=sort_rows, sort_columns=sort_columns, - fill_value=na) - - -def zeros(axes, dtype=float, order='C'): - """Returns a LArray with the specified axes and filled with zeros. - - Parameters - ---------- - axes : int, tuple of int or tuple/list/AxisCollection of Axis - a collection of axes or a shape. - dtype : data-type, optional - The desired data-type for the array, e.g., `numpy.int8`. Default is - `numpy.float64`. - order : {'C', 'F'}, optional - Whether to store multidimensional data in C- (default) or - Fortran-contiguous (row- or column-wise) order in memory. - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> zeros([xnat, xsex]) - nat\sex | H | F - BE | 0.0 | 0.0 - FO | 0.0 | 0.0 - """ - axes = AxisCollection(axes) - return LArray(np.zeros(axes.shape, dtype, order), axes) - - -def zeros_like(array, dtype=None, order='K'): - """Returns a LArray with the same axes as array and filled with zeros. - - Parameters - ---------- - array : LArray - is an array object. - dtype : data-type, optional - Overrides the data type of the result. - order : {'C', 'F', 'A', or 'K'}, optional - Overrides the memory layout of the result. 'C' means C-order, - 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, - 'C' otherwise. 'K' (default) means match the layout of `a` as closely - as possible. - - Returns - ------- - LArray - - Example - ------- - >>> a = ndrange((2, 3)) - >>> zeros_like(a) - {0}*\\{1}* | 0 | 1 | 2 - 0 | 0 | 0 | 0 - 1 | 0 | 0 | 0 - """ - axes = array.axes - return LArray(np.zeros_like(array, dtype, order), axes) - - -def ones(axes, dtype=float, order='C'): - """Returns a LArray with the specified axes and filled with ones. - - Parameters - ---------- - axes : int, tuple of int or tuple/list/AxisCollection of Axis - a collection of axes or a shape. - dtype : data-type, optional - The desired data-type for the array, e.g., `numpy.int8`. Default is - `numpy.float64`. - order : {'C', 'F'}, optional - Whether to store multidimensional data in C- (default) or - Fortran-contiguous (row- or column-wise) order in memory. - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> ones([xnat, xsex]) - nat\\sex | H | F - BE | 1.0 | 1.0 - FO | 1.0 | 1.0 - """ - axes = AxisCollection(axes) - return LArray(np.ones(axes.shape, dtype, order), axes) - - -def ones_like(array, dtype=None, order='K'): - """Returns a LArray with the same axes as array and filled with ones. - - Parameters - ---------- - array : LArray - is an array object. - dtype : data-type, optional - Overrides the data type of the result. - order : {'C', 'F', 'A', or 'K'}, optional - Overrides the memory layout of the result. 'C' means C-order, - 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, - 'C' otherwise. 'K' (default) means match the layout of `a` as closely - as possible. - - Returns - ------- - LArray - - Example - ------- - >>> a = ndrange((2, 3)) - >>> ones_like(a) - {0}*\\{1}* | 0 | 1 | 2 - 0 | 1 | 1 | 1 - 1 | 1 | 1 | 1 - """ - axes = array.axes - return LArray(np.ones_like(array, dtype, order), axes) - - -def empty(axes, dtype=float, order='C'): - """Returns a LArray with the specified axes and uninitialized (arbitrary) - data. - - Parameters - ---------- - axes : int, tuple of int or tuple/list/AxisCollection of Axis - a collection of axes or a shape. - dtype : data-type, optional - The desired data-type for the array, e.g., `numpy.int8`. Default is - `numpy.float64`. - order : {'C', 'F'}, optional - Whether to store multidimensional data in C- (default) or - Fortran-contiguous (row- or column-wise) order in memory. - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> empty([xnat, xsex]) # doctest: +SKIP - nat\\sex | H | F - BE | 2.47311483356e-315 | 2.47498446195e-315 - FO | 0.0 | 6.07684618082e-31 - """ - axes = AxisCollection(axes) - return LArray(np.empty(axes.shape, dtype, order), axes) - - -def empty_like(array, dtype=None, order='K'): - """Returns a LArray with the same axes as array and uninitialized - (arbitrary) data. - - Parameters - ---------- - array : LArray - is an array object. - dtype : data-type, optional - Overrides the data type of the result. - order : {'C', 'F', 'A', or 'K'}, optional - Overrides the memory layout of the result. 'C' means C-order, - 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, - 'C' otherwise. 'K' (default) means match the layout of `a` as closely - as possible. - - Returns - ------- - LArray - - Example - ------- - >>> a = ndrange((3, 2)) - >>> empty_like(a) # doctest: +SKIP - -\- | 0 | 1 - 0 | 2.12199579097e-314 | 6.36598737388e-314 - 1 | 1.06099789568e-313 | 1.48539705397e-313 - 2 | 1.90979621226e-313 | 2.33419537056e-313 - """ - # cannot use empty() because order == 'K' is not understood - return LArray(np.empty_like(array.data, dtype, order), array.axes) - - -def full(axes, fill_value, dtype=None, order='C'): - """Returns a LArray with the specified axes and filled with fill_value. - - Parameters - ---------- - axes : int, tuple of int or tuple/list/AxisCollection of Axis - a collection of axes or a shape. - fill_value : scalar or LArray - value to fill the array - dtype : data-type, optional - The desired data-type for the array. Default is the data type of - fill_value. - order : {'C', 'F'}, optional - Whether to store multidimensional data in C- (default) or - Fortran-contiguous (row- or column-wise) order in memory. - - Returns - ------- - LArray - - Examples - ======== - - >>> nat = Axis('nat', ['BE', 'FO']) - >>> sex = Axis('sex', ['M', 'F']) - >>> full([nat, sex], 42.0) - nat\\sex | M | F - BE | 42.0 | 42.0 - FO | 42.0 | 42.0 - >>> initial_value = ndrange([sex]) - >>> initial_value - sex | M | F - | 0 | 1 - >>> full([nat, sex], initial_value) - nat\\sex | M | F - BE | 0 | 1 - FO | 0 | 1 - """ - dtype = np.asarray(fill_value).dtype - res = empty(axes, dtype, order) - res[:] = fill_value - return res - - -def full_like(array, fill_value, dtype=None, order='K'): - """Returns a LArray with the same axes as array and filled with fill_value. - - Parameters - ---------- - array : LArray - is an array object. - fill_value : scalar or LArray - value to fill the array - dtype : data-type, optional - Overrides the data type of the result. - order : {'C', 'F', 'A', or 'K'}, optional - Overrides the memory layout of the result. 'C' means C-order, - 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, - 'C' otherwise. 'K' (default) means match the layout of `a` as closely - as possible. - - Returns - ------- - LArray - - Example - ------- - >>> a = ndrange((2, 3)) - >>> full_like(a, 5) - {0}*\\{1}* | 0 | 1 | 2 - 0 | 5 | 5 | 5 - 1 | 5 | 5 | 5 - """ - # cannot use full() because order == 'K' is not understood - # cannot use np.full_like() because it would not handle LArray fill_value - dtype = np.asarray(fill_value).dtype - res = empty_like(array, dtype, order) - res[:] = fill_value - return res - - -# XXX: would it be possible to generalize to multiple axes and deprecate -# ndrange (or rename this one to ndrange)? ndrange is only ever used to -# create test data (except for 1d) -# see https://github.com/pydata/pandas/issues/4567 -def create_sequential(axis, initial=0, inc=None, mult=1, func=None, axes=None): - """ - Creates an array by sequentially applying modifications to the array along - axis. - - The value for each label in axis will be given by sequentially transforming - the value for the previous label. This transformation on the previous label - value consists of applying the function "func" on that value if provided, or - to multiply it by mult and increment it by inc otherwise. - - Parameters - ---------- - axis : axis reference (Axis, string, int) - axis along which to apply mod. - initial : scalar or LArray, optional - value for the first label of axis. Defaults to 0. - inc : scalar, LArray, optional - value to increment the previous value by. Defaults to 0 if mult is - provided, 1 otherwise. - mult : scalar, LArray, optional - value to multiply the previous value by. Defaults to 1. - func : function/callable, optional - function to apply to the previous value. Defaults to None. - axes : int, tuple of int or tuple/list/AxisCollection of Axis, optional - axes of the result. Defaults to the union of axes present in other - arguments. - - Example - ------- - >>> year = Axis('year', range(2016, 2020)) - >>> sex = Axis('sex', ['M', 'F']) - >>> create_sequential(year) - year | 2016 | 2017 | 2018 | 2019 - | 0 | 1 | 2 | 3 - >>> create_sequential(year, 1.0, 0.1) - year | 2016 | 2017 | 2018 | 2019 - | 1.0 | 1.1 | 1.2 | 1.3 - >>> create_sequential(year, 1.0, mult=1.1) - year | 2016 | 2017 | 2018 | 2019 - | 1.0 | 1.1 | 1.21 | 1.331 - >>> inc = LArray([1, 2], [sex]) - >>> inc - sex | M | F - | 1 | 2 - >>> create_sequential(year, 1.0, inc) - sex\\year | 2016 | 2017 | 2018 | 2019 - M | 1.0 | 2.0 | 3.0 | 4.0 - F | 1.0 | 3.0 | 5.0 | 7.0 - >>> mult = LArray([2, 3], [sex]) - >>> mult - sex | M | F - | 2 | 3 - >>> create_sequential(year, 1.0, mult=mult) - sex\\year | 2016 | 2017 | 2018 | 2019 - M | 1.0 | 2.0 | 4.0 | 8.0 - F | 1.0 | 3.0 | 9.0 | 27.0 - >>> initial = LArray([3, 4], [sex]) - >>> initial - sex | M | F - | 3 | 4 - >>> create_sequential(year, initial, inc, mult) - sex\\year | 2016 | 2017 | 2018 | 2019 - M | 3 | 7 | 15 | 31 - F | 4 | 14 | 44 | 134 - >>> def modify(prev_value): - ... return prev_value / 2 - >>> create_sequential(year, 8, func=modify) - year | 2016 | 2017 | 2018 | 2019 - | 8 | 4 | 2 | 1 - >>> create_sequential(3) - {0}* | 0 | 1 | 2 - | 0 | 1 | 2 - >>> create_sequential(x.year, axes=(sex, year)) - sex\\year | 2016 | 2017 | 2018 | 2019 - M | 0 | 1 | 2 | 3 - F | 0 | 1 | 2 | 3 - - create_sequential can be used as the inverse of growth_rate: - - >>> a = ndrange([sex, year], start=1, dtype=float) - >>> a - sex\year | 2016 | 2017 | 2018 | 2019 - M | 1.0 | 2.0 | 3.0 | 4.0 - F | 5.0 | 6.0 | 7.0 | 8.0 - >>> g = a.growth_rate() + 1 - >>> g - sex\year | 2017 | 2018 | 2019 - M | 2.0 | 1.5 | 1.33333333333 - F | 1.2 | 1.16666666667 | 1.14285714286 - >>> create_sequential(a.axes.year, a[2016], mult=g) - sex\year | 2016 | 2017 | 2018 | 2019 - M | 1.0 | 2.0 | 3.0 | 4.0 - F | 5.0 | 6.0 | 7.0 | 8.0 - """ - if inc is None: - inc = 1 if mult is 1 else 0 - if isinstance(axis, int): - axis = Axis(None, axis) - if axes is None: - def strip_axes(col): - return get_axes(col) - axis - # we need to remove axis if present, because it might be incompatible - axes = strip_axes(initial) | strip_axes(inc) | strip_axes(mult) | axis - else: - axes = AxisCollection(axes) - axis = axes[axis] - # FIXME: we should compute combined dtype for inital, inc, mult - res = empty(axes, dtype=np.asarray(initial).dtype) - res[axis.i[0]] = initial - if func is not None: - for i in range(1, len(axis)): - res[axis.i[i]] = func(res[axis.i[i - 1]]) - else: - def index_if_exists(a, axis, i): - if isinstance(a, LArray) and axis in a.axes: - a_axis = a.axes[axis] - return a[a_axis[axis.labels[i]]] - else: - return a - for i in range(1, len(axis)): - i_mult = index_if_exists(mult, axis, i) - i_inc = index_if_exists(inc, axis, i) - res[axis.i[i]] = res[axis.i[i - 1]] * i_mult + i_inc - return res - - -def ndrange(axes, start=0, dtype=int): - """Returns a LArray with the specified axes and filled with increasing int. - - Parameters - ---------- - axes : int, tuple of int or tuple/list/AxisCollection of Axis - a collection of axes or a shape. - start : number, optional - dtype : dtype, optional - The type of the output array. Defaults to int. - - Returns - ------- - LArray - - Example - ------- - >>> xnat = Axis('nat', ['BE', 'FO']) - >>> xsex = Axis('sex', ['H', 'F']) - >>> ndrange([xnat, xsex]) - nat\\sex | H | F - BE | 0 | 1 - FO | 2 | 3 - >>> ndrange([2, 3], dtype=float) - {0}*\\{1}* | 0 | 1 | 2 - 0 | 0.0 | 1.0 | 2.0 - 1 | 3.0 | 4.0 | 5.0 - >>> ndrange(3, start=2) - {0}* | 0 | 1 | 2 - | 2 | 3 | 4 - - potential alternate syntaxes: - ndrange((2, 3), names=('a', 'b')) - ndrange(2, 3, names=('a', 'b')) - ndrange([('a', 2), ('b', 3)]) - ndrange(('a', 2), ('b', 3)) - ndrange((2, 3)).rename([0, 1], ['a', 'b']) - ndrange((2, 3)).rename({0: 'a', 1: 'b'}) - # current syntaxes - ndrange((2, 3)).rename(0, 'a').rename(1, 'b') - ndrange([Axis('a', 2), Axis('b', 3)]) - """ - # XXX: try to come up with a syntax where start is before "end". For ndim - # > 1, I cannot think of anything nice. - axes = AxisCollection(axes) - data = np.arange(start, start + axes.size, dtype=dtype) - return LArray(data.reshape(axes.shape), axes) - - -def kth_diag_indices(shape, k): - indices = np.diag_indices(min(shape), ndim=len(shape)) - if len(shape) == 2 and k != 0: - rows, cols = indices - if k < 0: - return rows[-k:], cols[:k] - elif k > 0: - return rows[:-k], cols[k:] - elif k != 0: - raise NotImplementedError("k != 0 and len(axes) != 2") - else: - return indices - - -def diag(a, k=0, axes=(0, 1), ndim=2, split=True): - """ - Extract a diagonal or construct a diagonal array. - - Parameters - ---------- - a : LArray - If `a` has 2 dimensions or more, return a copy of its `k`-th diagonal. - If `a` has 1 dimension, return an array with `ndim` dimensions on the - `k`-th diagonal. - k : int, optional - Offset of the diagonal from the main diagonal. Can be positive or - negative. Defaults to main diagonal (0). - axes : tuple or list or AxisCollection of axes references, optional - Axes along which the diagonals should be taken. Use None for all axes. - Defaults to the first two axes (0, 1). - ndim : int, optional - Target number of dimensions when constructing a diagonal array from - an array without axes names/labels. Defaults to 2. - split : bool, optional - Whether or not to try to split the axis name and labels - - Returns - ------- - LArray - The extracted diagonal or constructed diagonal array. - - Examples - -------- - >>> nat = Axis('nat', ['BE', 'FO']) - >>> sex = Axis('sex', ['M', 'F']) - >>> a = ndrange([nat, sex], start=1) - >>> a - nat\\sex | M | F - BE | 1 | 2 - FO | 3 | 4 - >>> d = diag(a) - >>> d - nat,sex | BE,M | FO,F - | 1 | 4 - >>> diag(d) - nat\\sex | M | F - BE | 1 | 0 - FO | 0 | 4 - >>> a = ndrange(sex, start=1) - >>> a - sex | M | F - | 1 | 2 - >>> diag(a) - sex\\sex | M | F - M | 1 | 0 - F | 0 | 2 - """ - if a.ndim == 1: - axis = a.axes[0] - axis_name = axis.name - if k != 0: - raise NotImplementedError("k != 0 not supported for 1D arrays") - if split and isinstance(axis_name, str) and ',' in axis_name: - axes_names = axis_name.split(',') - axes_labels = list(zip(*np.char.split(axis.labels, ','))) - axes = [Axis(name, labels) - for name, labels in zip(axes_names, axes_labels)] - else: - axes = [axis] + [axis.copy() for _ in range(ndim - 1)] - res = zeros(axes, dtype=a.dtype) - diag_indices = kth_diag_indices(res.shape, k) - res.ipoints[diag_indices] = a - return res - else: - if k != 0 and len(axes) > 2: - raise NotImplementedError("k != 0 and len(axes) > 2") - if axes is None: - axes = a.axes - else: - axes = a.axes[axes] - axes_indices = kth_diag_indices(axes.shape, k) - indexer = tuple(axis.i[indices] - for axis, indices in zip(axes, axes_indices)) - return a.points[indexer] - - -def labels_array(axes): - """Returns an array with specified axes and the combination of - corresponding labels as value. - - Parameters - ---------- - axes : Axis or collection of Axis - - Returns - ------- - LArray - - Example - ------- - >>> nat = Axis('nat', ['BE', 'FO']) - >>> sex = Axis('sex', ['M', 'F']) - >>> labels_array(sex) - sex | M | F - | M | F - >>> labels_array((nat, sex)) - nat | sex\\axis | nat | sex - BE | M | BE | M - BE | F | BE | F - FO | M | FO | M - FO | F | FO | F - """ - # >>> labels_array((nat, sex)) - # nat\\sex | M | F - # BE | BE,M | BE,F - # FO | FO,M | FO,F - axes = AxisCollection(axes) - if len(axes) > 1: - res_axes = axes + Axis('axis', axes.names) - res_data = np.empty(res_axes.shape, dtype=object) - res_data.flat[:] = list(product(*axes.labels)) - # XXX: I wonder if it wouldn't be better to return LGroups or a - # similar object which would display as "a,b" but where each label is - # stored separately. - # flat_data = np.array([p for p in product(*axes.labels)]) - # res_data = flat_data.reshape(axes.shape) - else: - res_axes = axes - res_data = axes[0].labels - return LArray(res_data, res_axes) - - -def identity(axis): - raise NotImplementedError("identity(axis) is deprecated. In most cases, " - "you can now use the axis directly. For example, " - "'identity(age) < 10' can be replaced by " - "'age < 10'. In other cases, you should use " - "labels_array(axis) instead.") - - -def eye(rows, columns=None, k=0, dtype=None): - """Return a 2-D array with ones on the diagonal and zeros elsewhere. - - Parameters - ---------- - rows : int or Axis - Rows of the output. - columns : int or Axis, optional - Columns in the output. If None, defaults to rows. - k : int, optional - Index of the diagonal: 0 (the default) refers to the main diagonal, a - positive value refers to an upper diagonal, and a negative value to a - lower diagonal. - dtype : data-type, optional - Data-type of the returned array. Defaults to float. - - Returns - ------- - LArray of shape (rows, columns) - An array where all elements are equal to zero, except for the k-th - diagonal, whose values are equal to one. - - Example - ------- - >>> eye(2, dtype=int) - {0}*\\{1}* | 0 | 1 - 0 | 1 | 0 - 1 | 0 | 1 - >>> sex = Axis('sex', ['M', 'F']) - >>> eye(sex) - sex\\sex | M | F - M | 1.0 | 0.0 - F | 0.0 | 1.0 - >>> eye(3, k=1) - {0}*\\{1}* | 0 | 1 | 2 - 0 | 0.0 | 1.0 | 0.0 - 1 | 0.0 | 0.0 | 1.0 - 2 | 0.0 | 0.0 | 0.0 - """ - if columns is None: - columns = rows.copy() if isinstance(rows, Axis) else rows - axes = AxisCollection([rows, columns]) - shape = axes.shape - data = np.eye(shape[0], shape[1], k, dtype) - return LArray(data, axes) - - -def stack(arrays, axis): - """ - stack([numbirths * HMASC, - numbirths * (1 - HMASC)], Axis('sex', 'H,F')) - potential alternate syntaxes - stack(['H', numbirths * HMASC, - 'F', numbirths * (1 - HMASC)], 'sex') - stack(('H', numbirths * HMASC), - ('F', numbirths * (1 - HMASC)), name='sex') - """ - # append an extra length 1 dimension - data_arrays = [a.data.reshape(a.shape + (1,)) for a in arrays] - axes = arrays[0].axes - for a in arrays[1:]: - a.axes.check_compatible(axes) - return LArray(np.concatenate(data_arrays, axis=-1), axes + axis) - - -class AxisReference(Axis): - def __init__(self, name): - self.name = name - self._labels = None - self._iswildcard = False - - def translate(self, key): - raise NotImplementedError("an AxisReference (x.) cannot translate " - "labels") - - def __repr__(self): - return 'AxisReference(%r)' % self.name - - -class AxisReferenceFactory(object): - def __getattr__(self, key): - return AxisReference(key) - - def __getitem__(self, key): - return AxisReference(key) - -x = AxisReferenceFactory() - - -def get_axes(value): - return value.axes if isinstance(value, LArray) else AxisCollection([]) - - -# assigning a temporary name to anonymous axes before broadcasting and -# removing it afterwards is not a good idea after all because it copies the -# axes/change the object, and thus "flatten" wouldn't work with position axes: -# a[ones(a.axes[axes], dtype=bool)] -# but if we had assigned axes names from the start (without dropping them) -# this wouldn't be a problem. -def make_numpy_broadcastable(values): - """ - return values where LArrays are (numpy) broadcastable between them. - For that to be possible, all common axes must be compatible. - Extra axes (in any array) can have any length. - - * the resulting arrays will have the combination of all axes found in the - input arrays, the earlier arrays defining the order of axes. Axes with - labels take priority over wildcard axes. - * length 1 wildcard axes will be added for axes not present in input - """ - all_axes = AxisCollection.union(*[get_axes(v) for v in values]) - - # 1) reorder axes - def transpose(v): - # XXX: v.transpose(all_axes & v.axes) SHOULD work - return v.transpose(v.axes[all_axes & v.axes]) - values = [transpose(v) if isinstance(v, LArray) else v - for v in values] - - # 2) add length one axes - def reshape(v): - return v.reshape(v.axes.get_all(all_axes)) - return [reshape(v) if isinstance(v, LArray) else v - for v in values], all_axes - - -# excel IO tools in Python -# - openpyxl, the slowest but most-complete package but still lags behind -# PHPExcel from which it was ported. despite the drawbacks the API is very -# complete. -# biggest drawbacks: -# * you can get either the "cached" value of cells OR their formulas but NOT -# BOTH and this is a file-wide setting (data_only=True). -# if you have an excel file and want to add a sheet to it, you either loose -# all cached values (which is problematic in many cases since you do not -# necessarily have linked files) or loose all formulas. -# * it loose "charts" on read. => cannot append/update a sheet to a file with -# charts, which is precisely what many users asked. => users need to -# create their charts using code. -# - xlsxwriter: faster and slightly more feature-complete than openpyxl -# regarding writing but does not read anything => cannot update an existing -# file. API seems extremely complete. -# - pyexcelerate: yet faster but also write only. Didn't check whether API -# is more featured than xlsxwriter or not. -# - xlwings: wraps win32com & equivalent on mac, so can potentially do -# everything (I guess) but this is SLOW and needs a running excel instance, -# etc. diff --git a/larray/core/__init__.py b/larray/core/__init__.py new file mode 100644 index 000000000..27abcf3ac --- /dev/null +++ b/larray/core/__init__.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import, division, print_function + +from larray.core.group import * +from larray.core.axis import * +from larray.core.array import * +from larray.core.session import * +from larray.core.ufuncs import * diff --git a/larray/core/abstractbases.py b/larray/core/abstractbases.py new file mode 100644 index 000000000..0546bb6a6 --- /dev/null +++ b/larray/core/abstractbases.py @@ -0,0 +1,17 @@ +from __future__ import absolute_import + +from abc import ABCMeta + + +# define abstract base classes to enable isinstance type checking on our objects +# idea taken from https://github.com/pandas-dev/pandas/blob/master/pandas/core/dtypes/generic.py +class ABCAxis(object): + __metaclass__ = ABCMeta + + +class ABCAxisReference(ABCAxis): + __metaclass__ = ABCMeta + + +class ABCLArray(object): + __metaclass__ = ABCMeta diff --git a/larray/core/array.py b/larray/core/array.py new file mode 100644 index 000000000..b79263a55 --- /dev/null +++ b/larray/core/array.py @@ -0,0 +1,8167 @@ +# -*- coding: utf8 -*- +from __future__ import absolute_import, division, print_function + +__all__ = [ + 'LArray', 'zeros', 'zeros_like', 'ones', 'ones_like', 'empty', 'empty_like', 'full', 'full_like', 'sequence', + 'create_sequential', 'ndrange', 'labels_array', 'ndtest', 'aslarray', 'identity', 'diag', 'eye', + 'larray_equal', 'larray_nan_equal', 'all', 'any', 'sum', 'prod', 'cumsum', 'cumprod', 'min', 'max', 'mean', 'ptp', + 'var', 'std', 'median', 'percentile', 'stack', 'nan', 'nan_equal', 'element_equal' +] + +""" +Matrix class +""" + +# ? implement multi group in one axis getitem: lipro['P01,P02;P05'] <=> (lipro['P01,P02'], lipro['P05']) + +# * we need an API to get to the "next" label. Sometimes, we want to use label+1, but that is problematic when labels +# are not numeric, or have not a step of 1. X.agegroup[X.agegroup.after(25):] +# X.agegroup[X.agegroup[25].next():] + +# * implement keepaxes=True for _group_aggregate instead of/in addition to group tuples + +# ? implement newaxis + +# * Axis.sequence? geo.seq('A31', 'A38') (equivalent to geo['A31..A38']) + +# * re-implement row_totals/col_totals? or what do we do with them? + +# * time specific API so that we know if we go for a subclass or not + +# * data alignment in arithmetic methods + +# * test structured arrays + +# ? move "utils" to its own project (so that it is not duplicated between larray and liam2) +# OR +# include utils only in larray project and make larray a dependency of liam2 +# (and potentially rename it to reflect the broader scope) + +from collections import Iterable, Sequence +from itertools import product, chain, groupby, islice +import os +import sys +import functools + +try: + import builtins +except ImportError: + import __builtin__ as builtins + +import numpy as np +import pandas as pd + +try: + import xlwings as xw +except ImportError: + xw = None + +try: + from numpy import nanprod as np_nanprod +except ImportError: + np_nanprod = None + +from larray.core.abstractbases import ABCLArray +from larray.core.expr import ExprNode +from larray.core.group import (Group, IGroup, LGroup, remove_nested_groups, _to_key, _to_keys, + _range_to_slice, _translate_sheet_name, _translate_key_hdf) +from larray.core.axis import Axis, AxisReference, AxisCollection, X, _make_axis +from larray.util.misc import (table2str, size2str, basestring, izip, rproduct, ReprString, duplicates, + float_error_handler_factory, _isnoneslice, light_product, unique_list, common_type, + renamed_to, deprecate_kwarg) + + +nan = np.nan + + +def all(values, axis=None): + """ + Test whether all array elements along a given axis evaluate to True. + + See Also + -------- + LArray.all + """ + if isinstance(values, LArray): + return values.all(axis) + else: + return builtins.all(values) + + +def any(values, axis=None): + """ + Test whether any array elements along a given axis evaluate to True. + + See Also + -------- + LArray.any + """ + if isinstance(values, LArray): + return values.any(axis) + else: + return builtins.any(values) + + +# commutative modulo float precision errors +def sum(array, *args, **kwargs): + """ + Sum of array elements. + + See Also + -------- + LArray.sum + """ + # XXX: we might want to be more aggressive here (more types to convert), however, generators should still be + # computed via the builtin. + if isinstance(array, (np.ndarray, list)): + array = LArray(array) + if isinstance(array, LArray): + return array.sum(*args, **kwargs) + else: + return builtins.sum(array, *args, **kwargs) + + +def prod(array, *args, **kwargs): + """ + Product of array elements. + + See Also + -------- + LArray.prod + """ + return array.prod(*args, **kwargs) + + +def cumsum(array, *args, **kwargs): + """ + Returns the cumulative sum of array elements. + + See Also + -------- + LArray.cumsum + """ + return array.cumsum(*args, **kwargs) + + +def cumprod(array, *args, **kwargs): + """ + Returns the cumulative product of array elements. + + See Also + -------- + LArray.cumprod + """ + return array.cumprod(*args, **kwargs) + + +def min(array, *args, **kwargs): + """ + Minimum of array elements. + + See Also + -------- + LArray.min + """ + if isinstance(array, LArray): + return array.min(*args, **kwargs) + else: + return builtins.min(array, *args, **kwargs) + + +def max(array, *args, **kwargs): + """ + Maximum of array elements. + + See Also + -------- + LArray.max + """ + if isinstance(array, LArray): + return array.max(*args, **kwargs) + else: + return builtins.max(array, *args, **kwargs) + + +def mean(array, *args, **kwargs): + """ + Computes the arithmetic mean. + + See Also + -------- + LArray.mean + """ + return array.mean(*args, **kwargs) + + +def median(array, *args, **kwargs): + """ + Computes the median. + + See Also + -------- + LArray.median + """ + return array.median(*args, **kwargs) + + +def percentile(array, *args, **kwargs): + """ + Computes the qth percentile of the data along the specified axis. + + See Also + -------- + LArray.percentile + """ + return array.percentile(*args, **kwargs) + + +# not commutative +def ptp(array, *args, **kwargs): + """ + Returns the range of values (maximum - minimum). + + See Also + -------- + LArray.ptp + """ + return array.ptp(*args, **kwargs) + + +def var(array, *args, **kwargs): + """ + Computes the variance. + + See Also + -------- + LArray.var + """ + return array.var(*args, **kwargs) + + +def std(array, *args, **kwargs): + """ + Computes the standard deviation. + + See Also + -------- + LArray.std + """ + return array.std(*args, **kwargs) + + +def concat(arrays, axis=0, dtype=None): + """Concatenate arrays along axis + + Parameters + ---------- + arrays : tuple of LArray + Arrays to concatenate. + axis : axis reference (int, str or Axis), optional + Axis along which to concatenate. Defaults to the first axis. + dtype : dtype, optional + Result data type. Defaults to the "closest" type which can hold all arrays types without loss of information. + + Returns + ------- + LArray + + Examples + -------- + >>> arr1 = ndtest((2, 3)) + >>> arr1 + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> arr2 = ndtest('a=a0,a1;b=b3') + >>> arr2 + a\\b b3 + a0 0 + a1 1 + >>> arr3 = ndtest('b=b4,b5') + >>> arr3 + b b4 b5 + 0 1 + >>> concat((arr1, arr2, arr3), 'b') + a\\b b0 b1 b2 b3 b4 b5 + a0 0 1 2 0 0 1 + a1 3 4 5 1 0 1 + """ + # Get axis by name, so that we do *NOT* check they are "compatible", because it makes sense to append axes of + # different length + name = arrays[0].axes[axis].name + arrays_labels = [array.axes[axis].labels for array in arrays] + + # switch to object dtype if labels are of incompatible types, so that we do not implicitly convert numeric types to + # strings (numpy should not do this in the first place but that is another story). This can happen for example when + # we want to add a "total" tick to a numeric axis (eg age). + labels_type = common_type(arrays_labels) + if labels_type is object: + # astype always copies, while asarray only copies if necessary + arrays_labels = [np.asarray(labels, dtype=object) for labels in arrays_labels] + + combined_axis = Axis(np.concatenate(arrays_labels), name) + + # combine all axes (using labels from any side if any) + result_axes = arrays[0].axes.replace(axis, combined_axis).union(*[array.axes - axis for array in arrays[1:]]) + + if dtype is None: + dtype = common_type(arrays) + + result = empty(result_axes, dtype=dtype) + start = 0 + for labels, array in zip(arrays_labels, arrays): + stop = start + len(labels) + result[combined_axis.i[start:stop]] = array + start = stop + return result + + +class LArrayIterator(object): + def __init__(self, array): + self.array = array + self.index = 0 + + def __iter__(self): + return self + + def __next__(self): + array = self.array + if self.index == len(self.array): + raise StopIteration + # result = array.i[array.axes[0].i[self.index]] + result = array.i[self.index] + self.index += 1 + return result + # Python 2 + next = __next__ + + +class LArrayPositionalIndexer(object): + def __init__(self, array): + self.array = array + + def _translate_key(self, key): + """ + Translates key into tuple of IGroup, i.e. + tuple of collections of labels. + """ + if not isinstance(key, tuple): + key = (key,) + if len(key) > self.array.ndim: + raise IndexError("key has too many indices (%d) for array with %d dimensions" % (len(key), self.array.ndim)) + # no need to create a full nd key as that will be done later anyway + return tuple(axis.i[axis_key] + for axis_key, axis in zip(key, self.array.axes)) + + def __getitem__(self, key): + return self.array[self._translate_key(key)] + + def __setitem__(self, key, value): + self.array[self._translate_key(key)] = value + + def __len__(self): + return len(self.array) + + +class LArrayPointsIndexer(object): + def __init__(self, array): + self.array = array + + def __getitem__(self, key): + # TODO: this should generate an "intersection"/points NDGroup and simply do return self.array[nd_group] + data = np.asarray(self.array) + translated_key = self.array._translated_key(key, bool_stuff=True) + + axes = self.array._bool_key_new_axes(translated_key) + data = data[translated_key] + # drop length 1 dimensions created by scalar keys + # data = data.reshape(tuple(len(axis) for axis in axes)) + if not axes: + # scalars do not need to be wrapped in LArray + return data + else: + return LArray(data, axes) + + def __setitem__(self, key, value): + data = np.asarray(self.array) + translated_key = self.array._translated_key(key, bool_stuff=True) + if isinstance(value, LArray): + axes = self.array._bool_key_new_axes(translated_key, wildcard_allowed=True) + value = value.broadcast_with(axes) + data[translated_key] = value + + +class LArrayPositionalPointsIndexer(object): + def __init__(self, array): + self.array = array + + def __getitem__(self, key): + data = np.asarray(self.array) + + axes = self.array._bool_key_new_axes(key, wildcard_allowed=False) + data = data[key] + # drop length 1 dimensions created by scalar keys + # data = data.reshape(tuple(len(axis) for axis in axes)) + if not axes: + # scalars do not need to be wrapped in LArray + return data + else: + return LArray(data, axes) + + def __setitem__(self, key, value): + data = np.asarray(self.array) + data[key] = value + + +def get_axis(obj, i): + """ + Returns an axis according to its position. + + Parameters + ---------- + obj : LArray or other array + Input LArray or any array object which has a shape attribute (NumPy or Pandas array). + i : int + index of the axis. + + Returns + ------- + Axis + Axis corresponding to the given index if input `obj` is a LArray. A new anonymous Axis with the length of + the ith dimension of the input `obj` otherwise. + + Examples + -------- + >>> arr = ndtest((2, 2, 2)) + >>> arr + a b\c c0 c1 + a0 b0 0 1 + a0 b1 2 3 + a1 b0 4 5 + a1 b1 6 7 + >>> get_axis(arr, 1) + Axis(['b0', 'b1'], 'b') + >>> np_arr = np.zeros((2, 2, 2)) + >>> get_axis(np_arr, 1) + Axis(2, None) + """ + return obj.axes[i] if isinstance(obj, LArray) else Axis(obj.shape[i]) + + +_arg_agg = { + 'q': """ + q : int in range of [0,100] (or sequence of floats) + Percentile to compute, which must be between 0 and 100 inclusive.""" +} + +_kwarg_agg = { + 'dtype': {'value': None, 'doc': """ + dtype : dtype, optional + The data type of the returned array. Defaults to None (the dtype of the input array)."""}, + 'out': {'value': None, 'doc': """ + out : LArray, optional + Alternate output array in which to place the result. It must have the same shape as the expected output and + its type is preserved (e.g., if dtype(out) is float, the result will consist of 0.0’s and 1.0’s). + Axes and labels can be different, only the shape matters. Defaults to None (create a new array)."""}, + 'ddof': {'value': 1, 'doc': """ + ddof : int, optional + "Delta Degrees of Freedom": the divisor used in the calculation is ``N - ddof``, where ``N`` represents + the number of elements. Defaults to 1."""}, + 'skipna': {'value': None, 'doc': """ + skipna : bool, optional + Whether or not to skip NaN (null) values. If False, resulting cells will be NaN if any of the aggregated + cells is NaN. Defaults to True."""}, + 'keepaxes': {'value': False, 'doc': """ + keepaxes : bool, optional + Whether or not reduced axes are left in the result as dimensions with size one. Defaults to False.""" + }, + 'interpolation': {'value': 'linear', 'doc': """ + interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'}, optional + Interpolation method to use when the desired quantile lies between two data points ``i < j``: + + * linear: ``i + (j - i) * fraction``, where ``fraction`` is the fractional part of the index surrounded + by ``i`` and ``j``. + * lower: ``i``. + * higher: ``j``. + * nearest: ``i`` or ``j``, whichever is nearest. + * midpoint: ``(i + j) / 2``. + + Defaults to 'linear'.""" + } +} + + +def _doc_agg_method(func, by=False, long_name='', action_verb='perform', extra_args=[], kwargs=[]): + if not long_name: + long_name = func.__name__ + + _args = ','.join(extra_args) + ', ' if len(extra_args) > 0 else '' + _kwargs = ', '.join(["{}={!r}".format(k, _kwarg_agg[k]['value']) for k in kwargs]) + ', ' if len(kwargs) > 0 else '' + signature = '{name}({args}*axes_and_groups, {kwargs}**explicit_axes)'.format(name=func.__name__, + args=_args, kwargs=_kwargs) + + if by: + specific_template = """The {long_name} is {action_verb}ed along all axes except the given one(s). + For groups, {long_name} is {action_verb}ed along groups and non associated axes.""" + else: + specific_template = "Axis(es) or group(s) along which the {long_name} is {action_verb}ed." + doc_specific = specific_template.format(long_name=long_name, action_verb=action_verb) + + doc_args = "".join(_arg_agg[arg] for arg in extra_args) + doc_kwargs = "".join(_kwarg_agg[kw]['doc'] for kw in kwargs) + doc_varargs = """ + \*axes_and_groups : None or int or str or Axis or Group or any combination of those + {specific} + The default (no axis or group) is to {action_verb} the {long_name} over all the dimensions of the input + array. + + An axis can be referred by: + + * its index (integer). Index can be a negative integer, in which case it counts from the last to the + first axis. + * its name (str or AxisReference). You can use either a simple string ('axis_name') or the special + variable x (x.axis_name). + * a variable (Axis). If the axis has been defined previously and assigned to a variable, you can pass it as + argument. + + You may not want to {action_verb} the {long_name} over a whole axis but over a selection of specific + labels. To do so, you have several possibilities: + + * (['a1', 'a3', 'a5'], 'b1, b3, b5') : labels separated by commas in a list or a string + * ('a1:a5:2') : select labels using a slice (general syntax is 'start:end:step' where is 'step' is + optional and 1 by default). + * (a='a1, a2, a3', x.b['b1, b2, b3']) : in case of possible ambiguity, i.e. if labels can belong to more + than one axis, you must precise the axis. + * ('a1:a3; a5:a7', b='b0,b2; b1,b3') : create several groups with semicolons. + Names are simply given by the concatenation of labels (here: 'a1,a2,a3', 'a5,a6,a7', 'b0,b2' and 'b1,b3') + * ('a1:a3 >> a123', 'b[b0,b2] >> b12') : operator ' >> ' allows to rename groups."""\ + .format(specific=doc_specific, action_verb=action_verb, long_name=long_name) + parameters = """Parameters + ----------{args}{varargs}{kwargs}""".format(args=doc_args, varargs=doc_varargs, kwargs=doc_kwargs) + + func.__doc__ = func.__doc__.format(signature=signature, parameters=parameters) + + +_always_return_float = {np.mean, np.nanmean, np.median, np.nanmedian, np.percentile, np.nanpercentile, + np.std, np.nanstd, np.var, np.nanvar} + +obj_isnan = np.vectorize(lambda x: x != x, otypes=[bool]) + + +def element_equal(a1, a2, rtol=0, atol=0, nan_equals=False): + """ + Compares two arrays element-wise and returns array of booleans. + + Parameters + ---------- + a1, a2 : LArray-like + Input arrays. aslarray() is used on non-LArray inputs. + rtol : float or int, optional + The relative tolerance parameter (see Notes). Defaults to 0. + atol : float or int, optional + The absolute tolerance parameter (see Notes). Defaults to 0. + nan_equals: boolean, optional + Whether or not to consider nan values at the same positions in the two arrays as equal. + By default, an array containing nan values is never equal to another array, even if that other array + also contains nan values at the same positions. The reason is that a nan value is different from + *anything*, including itself. Defaults to False. + + Returns + ------- + LArray + Boolean array of where a1 and a2 are equal within a tolerance range if given. + If nan_equals=True, nan’s in a1 will be considered equal to nan’s in a2 in the output array. + + Notes + ----- + For finite values, element_equal uses the following equation to test whether two values are equal: + + absolute(array1 - array2) <= (atol + rtol * absolute(array2)) + + The above equation is not symmetric in array1 and array2, so that element_equal(array1, array2) + might be different from element_equal(array2, array1) in some rare cases. + + Examples + -------- + >>> arr1 = LArray([6., np.nan, 8.], "a=a0..a2") + >>> arr1 + a a0 a1 a2 + 6.0 nan 8.0 + + Default behavior (same as == operator) + + >>> element_equal(arr1, arr1) + a a0 a1 a2 + True False True + + Test equality between two arrays within a given tolerance range. + Return True if absolute(array1 - array2) <= (atol + rtol * absolute(array2)). + + >>> arr2 = LArray([5.999, np.nan, 8.001], "a=a0..a2") + >>> arr2 + a a0 a1 a2 + 5.999 nan 8.001 + >>> element_equal(arr1, arr2, nan_equals=True) + a a0 a1 a2 + False True False + >>> element_equal(arr1, arr2, atol=0.01, nan_equals=True) + a a0 a1 a2 + True True True + >>> element_equal(arr1, arr2, rtol=0.01, nan_equals=True) + a a0 a1 a2 + True True True + """ + a1, a2 = aslarray(a1), aslarray(a2) + + if rtol == 0 and atol == 0: + if not nan_equals: + return a1 == a2 + else: + from larray.core.ufuncs import isnan + + def general_isnan(a): + if np.issubclass_(a.dtype.type, np.inexact): + return isnan(a) + elif a.dtype.type is np.object_: + return LArray(obj_isnan(a), a.axes) + else: + return False + + return (a1 == a2) | (general_isnan(a1) & general_isnan(a2)) + else: + (a1, a2), res_axes = make_numpy_broadcastable([a1, a2]) + return LArray(np.isclose(a1.data, a2.data, rtol=rtol, atol=atol, equal_nan=nan_equals), res_axes) + + +def nan_equal(a1, a2): + import warnings + warnings.warn("nan_equal() is deprecated. Use equal() instead.", FutureWarning, stacklevel=2) + return element_equal(a1, a2, nan_equals=True) + + +class LArray(ABCLArray): + """ + A LArray object represents a multidimensional, homogeneous array of fixed-size items with labeled axes. + + The function :func:`aslarray` can be used to convert a NumPy array or Pandas DataFrame into a LArray. + + Parameters + ---------- + data : scalar, tuple, list or NumPy ndarray + Input data. + axes : collection (tuple, list or AxisCollection) of axes (int, str or Axis), optional + Axes. + title : str, optional + Title of array. + + Attributes + ---------- + data : NumPy ndarray + Data. + axes : AxisCollection + Axes. + title : str + Title. + + See Also + -------- + sequence : Create a LArray by sequentially applying modifications to the array along axis. + ndtest : Create a test LArray with increasing elements. + zeros : Create a LArray, each element of which is zero. + ones : Create a LArray, each element of which is 1. + full : Create a LArray filled with a given value. + empty : Create a LArray, but leave its allocated memory unchanged (i.e., it contains “garbage”). + + Examples + -------- + >>> age = Axis([10, 11, 12], 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009], 'time') + >>> axes = [age, sex, time] + >>> data = np.zeros((len(axes), len(sex), len(time))) + >>> LArray(data, axes) + age sex\\time 2007 2008 2009 + 10 M 0.0 0.0 0.0 + 10 F 0.0 0.0 0.0 + 11 M 0.0 0.0 0.0 + 11 F 0.0 0.0 0.0 + 12 M 0.0 0.0 0.0 + 12 F 0.0 0.0 0.0 + >>> full(axes, 10.0) + age sex\\time 2007 2008 2009 + 10 M 10.0 10.0 10.0 + 10 F 10.0 10.0 10.0 + 11 M 10.0 10.0 10.0 + 11 F 10.0 10.0 10.0 + 12 M 10.0 10.0 10.0 + 12 F 10.0 10.0 10.0 + >>> arr = empty(axes) + >>> arr['F'] = 1.0 + >>> arr['M'] = -1.0 + >>> arr + age sex\\time 2007 2008 2009 + 10 M -1.0 -1.0 -1.0 + 10 F 1.0 1.0 1.0 + 11 M -1.0 -1.0 -1.0 + 11 F 1.0 1.0 1.0 + 12 M -1.0 -1.0 -1.0 + 12 F 1.0 1.0 1.0 + >>> bysex = sequence(sex, initial=-1, inc=2) + >>> bysex + sex M F + -1 1 + >>> sequence(age, initial=10, inc=bysex) + sex\\age 10 11 12 + M 10 9 8 + F 10 11 12 + """ + + def __init__(self, data, axes=None, title=''): + data = np.asarray(data) + ndim = data.ndim + if axes is None: + axes = AxisCollection(data.shape) + else: + if not isinstance(axes, AxisCollection): + axes = AxisCollection(axes) + if axes.ndim != ndim: + raise ValueError("number of axes (%d) does not match " + "number of dimensions of data (%d)" + % (axes.ndim, ndim)) + if axes.shape != data.shape: + raise ValueError("length of axes %s does not match " + "data shape %s" % (axes.shape, data.shape)) + + self.data = data + self.axes = axes + self.title = title + + # XXX: rename to posnonzero and implement a label version of nonzero + def nonzero(self): + """ + Returns the indices of the elements that are non-zero. + + Specifically, it returns a tuple of arrays (one for each dimension) + containing the indices of the non-zero elements in that dimension. + + Returns + ------- + tuple of arrays : tuple + Indices of elements that are non-zero. + + Examples + -------- + >>> arr = ndtest((2, 3)) % 2 + >>> arr + a\\b b0 b1 b2 + a0 0 1 0 + a1 1 0 1 + >>> arr.nonzero() # doctest: +SKIP + [array([0, 1, 1]), array([1, 0, 2])] + """ + # FIXME: return tuple of IGroup instead (or even NDGroup) so that you + # can do a[a.nonzero()] + return self.data.nonzero() + + def set_axes(self, axes_to_replace=None, new_axis=None, inplace=False, **kwargs): + """ + Replace one, several or all axes of the array. + + Parameters + ---------- + axes_to_replace : axis ref or dict {axis ref: axis} or list of tuple (axis ref, axis) \ + or list of Axis or AxisCollection + Axes to replace. If a single axis reference is given, the `new_axis` argument must be provided. + If a list of Axis or an AxisCollection is given, all axes will be replaced by the new ones. + In that case, the number of new axes must match the number of the old ones. + new_axis : Axis, optional + New axis if `axes_to_replace` contains a single axis reference. + inplace : bool, optional + Whether or not to modify the original object or return a new array and leave the original intact. + Defaults to False. + **kwargs : Axis + New axis for each axis to replace given as a keyword argument. + + Returns + ------- + LArray + Array with axes replaced. + + See Also + -------- + rename : rename one of several axes + + Examples + -------- + >>> arr = ndtest((2, 3)) + >>> arr + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> row = Axis(['r0', 'r1'], 'row') + >>> column = Axis(['c0', 'c1', 'c2'], 'column') + + Replace one axis (second argument `new_axis` must be provided) + + >>> arr.set_axes(X.a, row) + row\\b b0 b1 b2 + r0 0 1 2 + r1 3 4 5 + + Replace several axes (keywords, list of tuple or dictionary) + + >>> arr.set_axes(a=row, b=column) # doctest: +SKIP + >>> # or + >>> arr.set_axes([(X.a, row), (X.b, column)]) # doctest: +SKIP + >>> # or + >>> arr.set_axes({X.a: row, X.b: column}) + row\\column c0 c1 c2 + r0 0 1 2 + r1 3 4 5 + + Replace all axes (list of axes or AxisCollection) + + >>> arr.set_axes([row, column]) + row\\column c0 c1 c2 + r0 0 1 2 + r1 3 4 5 + >>> arr2 = ndtest([row, column]) + >>> arr.set_axes(arr2.axes) + row\\column c0 c1 c2 + r0 0 1 2 + r1 3 4 5 + """ + new_axes = self.axes.replace(axes_to_replace, new_axis, **kwargs) + if inplace: + if new_axes.ndim != self.ndim: + raise ValueError("number of axes (%d) does not match number of dimensions of data (%d)" + % (new_axes.ndim, self.ndim)) + if new_axes.shape != self.data.shape: + raise ValueError("length of axes %s does not match data shape %s" % (new_axes.shape, self.data.shape)) + self.axes = new_axes + return self + else: + return LArray(self.data, new_axes, title=self.title) + + with_axes = renamed_to(set_axes, 'with_axes') + + def __getattr__(self, key): + if key in self.axes: + return self.axes[key] + else: + raise AttributeError("'{}' object has no attribute '{}'".format(self.__class__.__name__, key)) + + # needed to make *un*pickling work (because otherwise, __getattr__ is called before .axes exists, which leads to + # an infinite recursion) + def __getstate__(self): + return self.__dict__ + + def __setstate__(self, d): + self.__dict__ = d + + def __dir__(self): + names = set(axis.name for axis in self.axes if axis.name is not None) + return list(set(dir(self.__class__)) | set(self.__dict__.keys()) | names) + + def _ipython_key_completions_(self): + return list(chain(*[list(labels) for labels in self.axes.labels])) + + @property + def i(self): + """ + Allows selection of a subset using indices of labels. + + Examples + -------- + >>> arr = ndtest((2, 3, 4)) + >>> arr + a b\\c c0 c1 c2 c3 + a0 b0 0 1 2 3 + a0 b1 4 5 6 7 + a0 b2 8 9 10 11 + a1 b0 12 13 14 15 + a1 b1 16 17 18 19 + a1 b2 20 21 22 23 + + >>> arr.i[:, 0:2, [0,2]] + a b\\c c0 c2 + a0 b0 0 2 + a0 b1 4 6 + a1 b0 12 14 + a1 b1 16 18 + """ + return LArrayPositionalIndexer(self) + + @property + def points(self): + """ + Allows selection of arbitrary items in the array + based on their N-dimensional label index. + + Examples + -------- + >>> arr = ndtest((2, 3, 4)) + >>> arr + a b\\c c0 c1 c2 c3 + a0 b0 0 1 2 3 + a0 b1 4 5 6 7 + a0 b2 8 9 10 11 + a1 b0 12 13 14 15 + a1 b1 16 17 18 19 + a1 b2 20 21 22 23 + + To select the two points with label coordinates + [a0, b0, c0] and [a1, b2, c2], you must do: + + >>> arr.points['a0,a1', 'b0,b2', 'c0,c2'] + a_b_c a0_b0_c0 a1_b2_c2 + 0 22 + + The number of label(s) on each dimension must be equal: + + >>> arr.points['a0,a1', 'b0,b2', 'c0,c1,c2'] # doctest: +NORMALIZE_WHITESPACE + Traceback (most recent call last): + ... + IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (2,) (3,) + """ + return LArrayPointsIndexer(self) + + @property + def ipoints(self): + """ + Allows selection of arbitrary items in the array based on their N-dimensional index. + + Examples + -------- + >>> arr = ndtest((2, 3, 4)) + >>> arr + a b\\c c0 c1 c2 c3 + a0 b0 0 1 2 3 + a0 b1 4 5 6 7 + a0 b2 8 9 10 11 + a1 b0 12 13 14 15 + a1 b1 16 17 18 19 + a1 b2 20 21 22 23 + + To select the two points with index coordinates + [0, 0, 0] and [1, 2, 2], you must do: + + >>> arr.ipoints[[0,1], [0,2], [0,2]] + a_b_c a0_b0_c0 a1_b2_c2 + 0 22 + + The number of index(es) on each dimension must be equal: + + >>> arr.ipoints[[0,1], [0,2], [0,1,2]] # doctest: +NORMALIZE_WHITESPACE + Traceback (most recent call last): + ... + IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (2,) (3,) + """ + return LArrayPositionalPointsIndexer(self) + + def to_frame(self, fold_last_axis_name=False, dropna=None): + """ + Converts LArray into Pandas DataFrame. + + Parameters + ---------- + fold_last_axis_name : bool, optional + Defaults to False. + dropna : {'any', 'all', None}, optional + * any : if any NA values are present, drop that label + * all : if all values are NA, drop that label + * None by default. + + Returns + ------- + Pandas DataFrame + + Examples + -------- + >>> arr = ndtest((2, 2, 2)) + >>> arr + a b\\c c0 c1 + a0 b0 0 1 + a0 b1 2 3 + a1 b0 4 5 + a1 b1 6 7 + >>> arr.to_frame() # doctest: +NORMALIZE_WHITESPACE + c c0 c1 + a b + a0 b0 0 1 + b1 2 3 + a1 b0 4 5 + b1 6 7 + >>> arr.to_frame(fold_last_axis_name=True) # doctest: +NORMALIZE_WHITESPACE + c0 c1 + a b\\c + a0 b0 0 1 + b1 2 3 + a1 b0 4 5 + b1 6 7 + """ + columns = pd.Index(self.axes[-1].labels) + if not fold_last_axis_name: + columns.name = self.axes[-1].name + if self.ndim > 1: + axes_names = self.axes.names[:-1] + if fold_last_axis_name: + tmp = axes_names[-1] if axes_names[-1] is not None else '' + if self.axes[-1].name: + axes_names[-1] = "{}\\{}".format(tmp, self.axes[-1].name) + if self.ndim == 2: + index = pd.Index(data=self.axes[0].labels, name=axes_names[0]) + else: + index = pd.MultiIndex.from_product(self.axes.labels[:-1], names=axes_names) + else: + index = pd.Index(['']) + if fold_last_axis_name: + index.name = self.axes.names[-1] + data = np.asarray(self).reshape(len(index), len(columns)) + df = pd.DataFrame(data, index, columns) + if dropna is not None: + dropna = dropna if dropna is not True else 'all' + df.dropna(inplace=True, how=dropna) + return df + df = property(to_frame) + + def to_series(self, name=None, dropna=False): + """ + Converts LArray into Pandas Series. + + Parameters + ---------- + name : str, optional + Name of the series. Defaults to None. + dropna : bool, optional. + False by default. + + Returns + ------- + Pandas Series + + Examples + -------- + >>> arr = ndtest((2, 3), dtype=float) + >>> arr + a\\b b0 b1 b2 + a0 0.0 1.0 2.0 + a1 3.0 4.0 5.0 + >>> arr.to_series() # doctest: +NORMALIZE_WHITESPACE + a b + a0 b0 0.0 + b1 1.0 + b2 2.0 + a1 b0 3.0 + b1 4.0 + b2 5.0 + dtype: float64 + + Set a name + + >>> arr.to_series('my_name') # doctest: +NORMALIZE_WHITESPACE + a b + a0 b0 0.0 + b1 1.0 + b2 2.0 + a1 b0 3.0 + b1 4.0 + b2 5.0 + Name: my_name, dtype: float64 + + Drop nan values + + >>> arr['b1'] = np.nan + >>> arr + a\\b b0 b1 b2 + a0 0.0 nan 2.0 + a1 3.0 nan 5.0 + >>> arr.to_series(dropna=True) # doctest: +NORMALIZE_WHITESPACE + a b + a0 b0 0.0 + b2 2.0 + a1 b0 3.0 + b2 5.0 + dtype: float64 + """ + index = pd.MultiIndex.from_product([axis.labels for axis in self.axes], names=self.axes.names) + series = pd.Series(np.asarray(self).reshape(self.size), index, name=name) + if dropna: + series.dropna(inplace=True) + return series + series = property(to_series) + + def describe(self, *args, **kwargs): + """ + Descriptive summary statistics, excluding NaN values. + + By default, it includes the number of non-NaN values, the mean, standard deviation, minimum, maximum and + the 25, 50 and 75 percentiles. + + Parameters + ---------- + *args : int or str or Axis or Group or any combination of those, optional + Axes or groups along which to compute the aggregates. Defaults to aggregate over the whole array. + percentiles : array-like, optional. + List of integer percentiles to include. Defaults to [25, 50, 75]. + + Returns + ------- + LArray + + See Also + -------- + LArray.describe_by + + Examples + -------- + >>> arr = LArray([0, 6, 2, 5, 4, 3, 1, 3], 'year=2013..2020') + >>> arr + year 2013 2014 2015 2016 2017 2018 2019 2020 + 0 6 2 5 4 3 1 3 + >>> arr.describe() + statistic count mean std min 25% 50% 75% max + 8.0 3.0 2.0 0.0 1.75 3.0 4.25 6.0 + >>> arr.describe(percentiles=[50, 90]) + statistic count mean std min 50% 90% max + 8.0 3.0 2.0 0.0 3.0 5.3 6.0 + """ + # retrieve kw-only arguments + percentiles = kwargs.pop('percentiles', None) + if kwargs: + raise TypeError("describe() got an unexpected keyword argument '{}'".format(list(kwargs.keys())[0])) + if percentiles is None: + percentiles = [25, 50, 75] + plabels = ['{}%'.format(p) for p in percentiles] + labels = ['count', 'mean', 'std', 'min'] + plabels + ['max'] + percentiles = [0] + list(percentiles) + [100] + # TODO: we should use the commented code using *self.percentile(percentiles, *args) but this does not work + # when *args is not empty (see https://github.com/larray-project/larray/issues/192) + # return stack([(~np.isnan(self)).sum(*args), self.mean(*args), self.std(*args), + # *self.percentile(percentiles, *args)], Axis(labels, 'stats')) + return stack([(~np.isnan(self)).sum(*args), self.mean(*args), self.std(*args)] + + [self.percentile(p, *args) for p in percentiles], Axis(labels, 'statistic')) + + def describe_by(self, *args, **kwargs): + """ + Descriptive summary statistics, excluding NaN values, along axes or for groups. + + By default, it includes the number of non-NaN values, the mean, standard deviation, minimum, maximum and + the 25, 50 and 75 percentiles. + + Parameters + ---------- + *args : int or str or Axis or Group or any combination of those, optional + Axes or groups to include in the result after aggregating. Defaults to aggregate over the whole array. + percentiles : array-like, optional. + list of integer percentiles to include. Defaults to [25, 50, 75]. + + Returns + ------- + LArray + + See Also + -------- + LArray.describe + + Examples + -------- + >>> data = [[0, 6, 3, 5, 4, 2, 1, 3], [7, 5, 3, 2, 8, 5, 6, 4]] + >>> arr = LArray(data, 'gender=Male,Female;year=2013..2020').astype(float) + >>> arr + gender\year 2013 2014 2015 2016 2017 2018 2019 2020 + Male 0.0 6.0 3.0 5.0 4.0 2.0 1.0 3.0 + Female 7.0 5.0 3.0 2.0 8.0 5.0 6.0 4.0 + >>> arr.describe_by('gender') + gender\statistic count mean std min 25% 50% 75% max + Male 8.0 3.0 2.0 0.0 1.75 3.0 4.25 6.0 + Female 8.0 5.0 2.0 2.0 3.75 5.0 6.25 8.0 + >>> arr.describe_by('gender', (X.year[:2015], X.year[2018:])) + gender year\statistic count mean std min 25% 50% 75% max + Male :2015 3.0 3.0 3.0 0.0 1.5 3.0 4.5 6.0 + Male 2018: 3.0 2.0 1.0 1.0 1.5 2.0 2.5 3.0 + Female :2015 3.0 5.0 2.0 3.0 4.0 5.0 6.0 7.0 + Female 2018: 3.0 5.0 1.0 4.0 4.5 5.0 5.5 6.0 + >>> arr.describe_by('gender', percentiles=[50, 90]) + gender\statistic count mean std min 50% 90% max + Male 8.0 3.0 2.0 0.0 3.0 5.3 6.0 + Female 8.0 5.0 2.0 2.0 5.0 7.3 8.0 + """ + # retrieve kw-only arguments + percentiles = kwargs.pop('percentiles', None) + if kwargs: + raise TypeError("describe() got an unexpected keyword argument '{}'".format(list(kwargs.keys())[0])) + args = self._prepare_aggregate(None, args) + args = self._by_args_to_normal_agg_args(args) + return self.describe(*args, percentiles=percentiles) + + # noinspection PyAttributeOutsideInit + # def __array_finalize__(self, obj): + # """ + # used when arrays are allocated from subclasses of ndarrays + # """ + # return np.ndarray.__array_finalize__(self.data, obj) + + # def __array_prepare__(self, arr, context=None): + # """ + # called before ufuncs (must return an ndarray) + # """ + # return np.ndarray.__array_prepare__(self.data, arr, context) + + def __array_wrap__(self, out_arr, context=None): + """ + Called after numpy ufuncs. This is never called during our wrapped + ufuncs, but if somebody uses raw numpy function, this works in some + cases. + """ + data = np.ndarray.__array_wrap__(self.data, out_arr, context) + return LArray(data, self.axes) + + def __bool__(self): + return bool(self.data) + # Python 2 + __nonzero__= __bool__ + + def rename(self, renames=None, to=None, inplace=False, **kwargs): + """Renames axes of the array. + + Parameters + ---------- + renames : axis ref or dict {axis ref: str} or list of tuple (axis ref, str) + Renames to apply. If a single axis reference is given, the `to` argument must be used. + to : str or Axis + New name if `renames` contains a single axis reference. + **kwargs : str or Axis + New name for each axis given as a keyword argument. + + Returns + ------- + LArray + Array with axes renamed. + + See Also + -------- + set_axes : replace one or several axes + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> arr = ndtest([nat, sex]) + >>> arr + nat\\sex M F + BE 0 1 + FO 2 3 + >>> arr.rename(X.nat, 'nat2') + nat2\\sex M F + BE 0 1 + FO 2 3 + >>> arr.rename(nat='nat2', sex='sex2') + nat2\\sex2 M F + BE 0 1 + FO 2 3 + >>> arr.rename([('nat', 'nat2'), ('sex', 'sex2')]) + nat2\\sex2 M F + BE 0 1 + FO 2 3 + >>> arr.rename({'nat': 'nat2', 'sex': 'sex2'}) + nat2\\sex2 M F + BE 0 1 + FO 2 3 + """ + if isinstance(renames, dict): + items = list(renames.items()) + elif isinstance(renames, list): + items = renames[:] + elif isinstance(renames, (str, Axis, int)): + items = [(renames, to)] + else: + items = [] + items += kwargs.items() + renames = {self.axes[k]: v for k, v in items} + axes = [a.rename(renames[a]) if a in renames else a + for a in self.axes] + if inplace: + self.axes = AxisCollection(axes) + return self + else: + return LArray(self.data, axes) + + def reindex(self, axes_to_reindex=None, new_axis=None, fill_value=np.nan, inplace=False, **kwargs): + """Reorder and/or add new labels in axes. + + Place NaN or given `fill_value` in locations having no value previously. + + Parameters + ---------- + axes_to_reindex : axis ref or dict {axis ref: axis} or list of tuple (axis ref, axis) \ + or list of Axis or AxisCollection + Axes to reindex. If a single axis reference is given, the `new_axis` argument must be provided. + If a list of Axis or an AxisCollection is given, existing axes are reindexed while missing ones are added. + new_axis : int, str, list/tuple/array of str, Group or Axis, optional + List of new labels or new axis if `axes_to_replace` contains a single axis reference. + fill_value : scalar or LArray, optional + Value used to fill cells corresponding to label combinations which were not present before reindexing. + Defaults to NaN. + inplace : bool, optional + Whether or not to modify the original object or return a new array and leave the original intact. + Defaults to False. + **kwargs : Axis + New axis for each axis to reindex given as a keyword argument. + + Returns + ------- + LArray + Array with reindexed axes. + + Notes + ----- + When introducing NAs into an array containing integers via reindex, + all data will be promoted to float in order to store the NAs. + + Examples + -------- + >>> arr = ndtest((2, 2)) + >>> arr + a\\b b0 b1 + a0 0 1 + a1 2 3 + >>> arr2 = ndtest('a=a1,a2;c=c0;b=b2..b0') + >>> arr2 + a c\\b b2 b1 b0 + a1 c0 0 1 2 + a2 c0 3 4 5 + + Reindex an axis by passing labels (list or string) + + >>> arr.reindex('b', ['b1', 'b2', 'b0']) + a\\b b1 b2 b0 + a0 1.0 nan 0.0 + a1 3.0 nan 2.0 + >>> arr.reindex('b', 'b0..b2', fill_value=-1) + a\\b b0 b1 b2 + a0 0 1 -1 + a1 2 3 -1 + + Reindex using an axis from another array + + >>> arr.reindex('b', arr2.b, fill_value=-1) + a\\b b2 b1 b0 + a0 -1 1 0 + a1 -1 3 2 + + Reindex using a subset of an axis + + >>> arr.reindex('b', arr2.b['b1':], fill_value=-1) + a\\b b1 b0 + a0 1 0 + a1 3 2 + + Reindex several axes + + >>> arr.reindex({'a': arr2.a, 'b': arr2.b}, fill_value=-1) + a\\b b2 b1 b0 + a1 -1 3 2 + a2 -1 -1 -1 + >>> arr.reindex({'a': arr2.a, 'b': arr2.b['b1':]}, fill_value=-1) + a\\b b1 b0 + a1 3 2 + a2 -1 -1 + + Reindex by passing a collection of axes + + >>> arr.reindex(arr2.axes, fill_value=-1) + a b\\c c0 + a1 b2 -1 + a1 b1 3 + a1 b0 2 + a2 b2 -1 + a2 b1 -1 + a2 b0 -1 + >>> arr2.reindex(arr.axes, fill_value=-1) + a c\\b b0 b1 + a0 c0 -1 -1 + a1 c0 2 1 + """ + # XXX: can't we move this to AxisCollection.replace? + if new_axis is not None and not isinstance(new_axis, Axis): + new_axis = Axis(new_axis, self.axes[axes_to_reindex].name) + elif isinstance(new_axis, Axis): + new_axis = new_axis.rename(self.axes[axes_to_reindex].name) + if isinstance(axes_to_reindex, (list, tuple)) and all([isinstance(axis, Axis) for axis in axes_to_reindex]): + axes_to_reindex = AxisCollection(axes_to_reindex) + if isinstance(axes_to_reindex, AxisCollection): + assert new_axis is None + # add extra axes if needed + res_axes = AxisCollection([axes_to_reindex.get(axis, axis) for axis in self.axes]) | axes_to_reindex + else: + res_axes = self.axes.replace(axes_to_reindex, new_axis, **kwargs) + res = full(res_axes, fill_value, dtype=common_type((self.data, fill_value))) + def get_labels(self_axis): + res_axis = res_axes[self_axis] + if res_axis.equals(self_axis): + return self_axis[:] + else: + return self_axis[self_axis.intersection(res_axis).labels] + self_labels = tuple(get_labels(axis) for axis in self.axes) + res_labels = tuple(res_axes[group.axis][group] for group in self_labels) + res[res_labels] = self[self_labels] + if inplace: + self.axes = res.axes + self.data = res.data + return self + else: + return res + + def align(self, other, join='outer', fill_value=nan, axes=None): + """Align two arrays on their axes with the specified join method. + + In other words, it ensure all common axes are compatible. Those arrays can then be used in binary operations. + + Parameters + ---------- + other : LArray-like + join : {'outer', 'inner', 'left', 'right'}, optional + Join method. For each axis common to both arrays: + - outer: will use a label if it is in either arrays axis (ordered like the first array). + This is the default as it results in no information loss. + - inner: will use a label if it is in both arrays axis (ordered like the first array) + - left: will use the first array axis labels + - right: will use the other array axis labels. + fill_value : scalar or LArray, optional + Value used to fill cells corresponding to label combinations which are not common to both arrays. + Defaults to NaN. + axes : AxisReference or sequence of them, optional + Axes to align. Need to be valid in both arrays. Defaults to None (all common axes). This must be specified + when mixing anonymous and non-anonymous axes. + + Returns + ------- + (left, right) : (LArray, LArray) + Aligned objects + + Notes + ----- + Arrays with anonymous axes are currently not supported. + + Examples + -------- + >>> arr1 = ndtest((2, 3)) + >>> arr1 + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> arr2 = -ndtest((3, 2)) + >>> # reorder array to make the test more interesting + >>> arr2 = arr2[['b1', 'b0']] + >>> arr2 + a\\b b1 b0 + a0 -1 0 + a1 -3 -2 + a2 -5 -4 + + Align arr1 and arr2 + + >>> aligned1, aligned2 = arr1.align(arr2) + >>> aligned1 + a\\b b0 b1 b2 + a0 0.0 1.0 2.0 + a1 3.0 4.0 5.0 + a2 nan nan nan + >>> aligned2 + a\\b b0 b1 b2 + a0 0.0 -1.0 nan + a1 -2.0 -3.0 nan + a2 -4.0 -5.0 nan + + After aligning all common axes, one can then do operations between the two arrays + + >>> aligned1 + aligned2 + a\\b b0 b1 b2 + a0 0.0 0.0 nan + a1 1.0 1.0 nan + a2 nan nan nan + + Other kinds of joins are supported + + >>> aligned1, aligned2 = arr1.align(arr2, join='inner') + >>> aligned1 + a\\b b0 b1 + a0 0.0 1.0 + a1 3.0 4.0 + >>> aligned2 + a\\b b0 b1 + a0 0.0 -1.0 + a1 -2.0 -3.0 + >>> aligned1, aligned2 = arr1.align(arr2, join='left') + >>> aligned1 + a\\b b0 b1 b2 + a0 0.0 1.0 2.0 + a1 3.0 4.0 5.0 + >>> aligned2 + a\\b b0 b1 b2 + a0 0.0 -1.0 nan + a1 -2.0 -3.0 nan + >>> aligned1, aligned2 = arr1.align(arr2, join='right') + >>> aligned1 + a\\b b1 b0 + a0 1.0 0.0 + a1 4.0 3.0 + a2 nan nan + >>> aligned2 + a\\b b1 b0 + a0 -1.0 0.0 + a1 -3.0 -2.0 + a2 -5.0 -4.0 + + The fill value for missing labels defaults to nan but can be changed to any compatible value. + + >>> aligned1, aligned2 = arr1.align(arr2, fill_value=0) + >>> aligned1 + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + a2 0 0 0 + >>> aligned2 + a\\b b0 b1 b2 + a0 0 -1 0 + a1 -2 -3 0 + a2 -4 -5 0 + >>> aligned1 + aligned2 + a\\b b0 b1 b2 + a0 0 0 2 + a1 1 1 5 + a2 -4 -5 0 + + It also works when either arrays (or both) have extra axes + + >>> arr3 = ndtest((3, 2, 2)) + >>> arr1 + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> arr3 + a b\\c c0 c1 + a0 b0 0 1 + a0 b1 2 3 + a1 b0 4 5 + a1 b1 6 7 + a2 b0 8 9 + a2 b1 10 11 + >>> aligned1, aligned2 = arr1.align(arr3, join='inner') + >>> aligned1 + a\\b b0 b1 + a0 0.0 1.0 + a1 3.0 4.0 + >>> aligned2 + a b\c c0 c1 + a0 b0 0.0 1.0 + a0 b1 2.0 3.0 + a1 b0 4.0 5.0 + a1 b1 6.0 7.0 + >>> aligned1 + aligned2 + a b\\c c0 c1 + a0 b0 0.0 1.0 + a0 b1 3.0 4.0 + a1 b0 7.0 8.0 + a1 b1 10.0 11.0 + + One can also align only some specific axes (but in that case arrays might not be compatible) + + >>> aligned1, aligned2 = arr1.align(arr2, axes='b') + >>> aligned1 + a\\b b0 b1 b2 + a0 0.0 1.0 2.0 + a1 3.0 4.0 5.0 + >>> aligned2 + a\\b b0 b1 b2 + a0 0.0 -1.0 nan + a1 -2.0 -3.0 nan + a2 -4.0 -5.0 nan + """ + other = aslarray(other) + # reindex does not currently support anonymous axes + if any(name is None for name in self.axes.names) or any(name is None for name in other.axes.names): + raise ValueError("arrays with anonymous axes are currently not supported by LArray.align") + left_axes, right_axes = self.axes.align(other.axes, join=join, axes=axes) + return self.reindex(left_axes, fill_value=fill_value), other.reindex(right_axes, fill_value=fill_value) + + @deprecate_kwarg('reverse', 'ascending', {True: False, False: True}) + def sort_values(self, key=None, axis=None, ascending=True): + """Sorts values of the array. + + Parameters + ---------- + key : scalar or tuple or Group + Key along which to sort. Must have exactly one dimension less than ndim. + Cannot be used in combination with `axis` argument. + If both `key` and `axis` are None, sort array with all axes combined. + Defaults to None. + axis : int or str or Axis + Axis along which to sort. Cannot be used in combination with `key` argument. + Defaults to None. + ascending : bool, optional + Sort values in ascending order. Defaults to True. + + Returns + ------- + LArray + Array with sorted values. + + Examples + -------- + sort the whole array (no key or axis given) + + >>> arr_1D = LArray([10, 2, 4], 'a=a0..a2') + >>> arr_1D + a a0 a1 a2 + 10 2 4 + >>> arr_1D.sort_values() + a a1 a2 a0 + 2 4 10 + >>> arr_2D = LArray([[10, 2, 4], [3, 7, 1]], 'a=a0,a1; b=b0..b2') + >>> arr_2D + a\\b b0 b1 b2 + a0 10 2 4 + a1 3 7 1 + >>> # if the array has more than one dimension, sort array with all axes combined + >>> arr_2D.sort_values() + a_b a1_b2 a0_b1 a1_b0 a0_b2 a1_b1 a0_b0 + 1 2 3 4 7 10 + + Sort along a given key + + >>> # sort columns according to the values of the row associated with the label 'a1' + >>> arr_2D.sort_values('a1') + a\\b b2 b0 b1 + a0 4 10 2 + a1 1 3 7 + >>> arr_2D.sort_values('a1', ascending=False) + a\\b b1 b0 b2 + a0 2 10 4 + a1 7 3 1 + >>> arr_3D = LArray([[[10, 2, 4], [3, 7, 1]], [[5, 1, 6], [2, 8, 9]]], + ... 'a=a0,a1; b=b0,b1; c=c0..c2') + >>> arr_3D + a b\\c c0 c1 c2 + a0 b0 10 2 4 + a0 b1 3 7 1 + a1 b0 5 1 6 + a1 b1 2 8 9 + >>> # sort columns according to the values of the row associated with the labels 'a0' and 'b1' + >>> arr_3D.sort_values(('a0', 'b1')) + a b\\c c2 c0 c1 + a0 b0 4 10 2 + a0 b1 1 3 7 + a1 b0 6 5 1 + a1 b1 9 2 8 + + Sort along an axis + + >>> arr_2D + a\\b b0 b1 b2 + a0 10 2 4 + a1 3 7 1 + >>> # sort values along axis 'a' + >>> # equivalent to sorting the values of each column of the array + >>> arr_2D.sort_values(axis='a') + a*\\b b0 b1 b2 + 0 3 2 1 + 1 10 7 4 + >>> # sort values along axis 'b' + >>> # equivalent to sorting the values of each row of the array + >>> arr_2D.sort_values(axis='b') + a\\b* 0 1 2 + a0 2 4 10 + a1 1 3 7 + """ + if key is not None and axis is not None: + raise ValueError("Arguments key and axis are exclusive and cannot be used in combination") + if axis is not None: + axis = self.axes[axis] + axis_idx = self.axes.index(axis) + data = np.sort(self.data, axis_idx) + new_axes = self.axes.replace(axis_idx, Axis(len(axis), axis.name)) + res = LArray(data, new_axes) + elif key is not None: + subset = self[key] + if subset.ndim > 1: + raise NotImplementedError("sort_values key must have one dimension less than array.ndim") + assert subset.ndim == 1 + axis = subset.axes[0] + indicesofsorted = subset.indicesofsorted() + + # FIXME: .data shouldn't be necessary, but currently, if we do not do it, we get + # IGroup(nat EU FO BE + # 1 2 0, axis='nat') + # which sorts the *data* correctly, but the labels on the nat axis are not sorted (because the __getitem__ in + # that case reuse the key axis as-is -- like it should). + # Both use cases have value, but I think reordering the ticks should be the default. Now, I am unsure where to + # change this. Probably in IGroupMaker.__getitem__, but then how do I get the "not reordering labels" behavior + # that I have now? + # FWIW, using .data, I get IGroup([1, 2, 0], axis='nat'), which works. + sorter = axis.i[indicesofsorted.data] + res = self[sorter] + else: + res = self.combine_axes() + indicesofsorted = np.argsort(res.data) + res = res.i[indicesofsorted] + axis = res.axes[0] + return res[axis[::-1]] if not ascending else res + + @deprecate_kwarg('reverse', 'ascending', {True: False, False: True}) + def sort_axes(self, axes=None, ascending=True): + """Sorts axes of the array. + + Parameters + ---------- + axes : axis reference (Axis, str, int) or list of them, optional + Axes to sort. Defaults to all axes. + ascending : bool, optional + Sort axes in ascending order. Defaults to True. + + Returns + ------- + LArray + Array with sorted axes. + + Examples + -------- + >>> a = ndtest("nat=EU,FO,BE; sex=M,F") + >>> a + nat\\sex M F + EU 0 1 + FO 2 3 + BE 4 5 + >>> a.sort_axes('sex') + nat\\sex F M + EU 1 0 + FO 3 2 + BE 5 4 + >>> a.sort_axes() + nat\\sex F M + BE 5 4 + EU 1 0 + FO 3 2 + >>> a.sort_axes(('sex', 'nat')) + nat\\sex F M + BE 5 4 + EU 1 0 + FO 3 2 + >>> a.sort_axes(ascending=False) + nat\\sex M F + FO 2 3 + EU 0 1 + BE 4 5 + """ + if axes is None: + axes = self.axes + elif not isinstance(axes, (tuple, list, AxisCollection)): + axes = [axes] + + if not isinstance(axes, AxisCollection): + axes = self.axes[axes] + + def sort_key(axis): + key = np.argsort(axis.labels) + if not ascending: + key = key[::-1] + return axis.i[key] + + return self[tuple(sort_key(axis) for axis in axes)] + + sort_axis = renamed_to(sort_axes, 'sort_axis') + + def _translate_axis_key_chunk(self, axis_key, bool_passthrough=True): + """ + Translates axis(es) key into axis(es) position(s). + + Parameters + ---------- + axis_key : any kind of key + Key to select axis(es). + bool_passthrough : bool, optional + True by default. + + Returns + ------- + IGroup + Positional group with valid axes (from self.axes) + """ + axis_key = remove_nested_groups(axis_key) + + if isinstance(axis_key, Group) and axis_key.axis is not None: + # retarget to real axis, if needed + # only retarget IGroup and not LGroup to give the opportunity for axis.translate to try the "ticks" + # version of the group ONLY if key.axis is not real_axis (for performance reasons) + if isinstance(axis_key, IGroup): + if axis_key.axis in self.axes: + axis_key = axis_key.retarget_to(self.axes[axis_key.axis]) + else: + # axis associated with axis_key may not belong to self. + # In that case, we translate IGroup to labels and search for a compatible axis + # (see end of this method) + axis_key = axis_key.to_label() + + # already positional + if isinstance(axis_key, IGroup): + if axis_key.axis is None: + raise ValueError("positional groups without axis are not supported") + return axis_key + + # labels but known axis + if isinstance(axis_key, LGroup) and axis_key.axis is not None: + try: + real_axis = self.axes[axis_key.axis] + try: + axis_pos_key = real_axis.index(axis_key, bool_passthrough) + except KeyError: + raise ValueError("%r is not a valid label for any axis" % axis_key) + return real_axis.i[axis_pos_key] + except KeyError: + # axis associated with axis_key may not belong to self. + # In that case, we translate LGroup to labels and search for a compatible axis + # (see end of this method) + axis_key = axis_key.to_label() + + # otherwise we need to guess the axis + # TODO: instead of checking all axes, we should have a big mapping + # (in AxisCollection or LArray): + # label -> (axis, index) + # but for Pandas, this wouldn't work, we'd need label -> axis + valid_axes = [] + # TODO: use axis_key dtype to only check compatible axes + for axis in self.axes: + try: + axis_pos_key = axis.index(axis_key, bool_passthrough) + valid_axes.append(axis) + except KeyError: + continue + if not valid_axes: + raise ValueError("%s is not a valid label for any axis" % axis_key) + elif len(valid_axes) > 1: + # TODO: make an AxisCollection.display_name(axis) method out of this + # valid_axes = ', '.join(self.axes.display_name(axis) for a in valid_axes) + valid_axes = ', '.join(a.name if a.name is not None else '{{{}}}'.format(self.axes.index(a)) + for a in valid_axes) + raise ValueError('%s is ambiguous (valid in %s)' % (axis_key, valid_axes)) + return valid_axes[0].i[axis_pos_key] + + def _translate_axis_key(self, axis_key, bool_passthrough=True): + """Same as chunk. + + Returns + ------- + IGroup + Positional group with valid axes (from self.axes) + """ + if isinstance(axis_key, ExprNode): + axis_key = axis_key.evaluate(self.axes) + + if isinstance(axis_key, LArray) and np.issubdtype(axis_key.dtype, np.bool_) and bool_passthrough: + if len(axis_key.axes) > 1: + raise ValueError("mixing ND boolean filters with other filters in getitem is not currently supported") + else: + return IGroup(axis_key.nonzero()[0], axis=axis_key.axes[0]) + + # translate Axis keys to LGroup keys + # FIXME: this should be simply: + # if isinstance(axis_key, Axis): + # axis_key = axis_key[:] + # but it does not work for some reason (the retarget does not seem to happen) + if isinstance(axis_key, Axis): + real_axis = self.axes[axis_key] + if isinstance(axis_key, AxisReference) or axis_key.equals(real_axis): + axis_key = real_axis[:] + else: + axis_key = axis_key.labels + + # TODO: do it for Group without axis too + if isinstance(axis_key, (tuple, list, np.ndarray, LArray)): + axis = None + # TODO: I should actually do some benchmarks to see if this is useful, and estimate which numbers to use + for size in (1, 10, 100, 1000): + # TODO: do not recheck already checked elements + key_chunk = axis_key.i[:size] if isinstance(axis_key, LArray) else axis_key[:size] + try: + tkey = self._translate_axis_key_chunk(key_chunk, bool_passthrough) + axis = tkey.axis + break + except ValueError: + continue + # the (start of the) key match a single axis + if axis is not None: + # make sure we have an Axis object + # TODO: we should make sure the tkey returned from _translate_axis_key_chunk always contains a + # real Axis (and thus kill this line) + axis = self.axes[axis] + # wrap key in LGroup + axis_key = axis[axis_key] + # XXX: reuse tkey chunks and only translate the rest? + return self._translate_axis_key_chunk(axis_key, bool_passthrough) + else: + return self._translate_axis_key_chunk(axis_key, bool_passthrough) + + def _guess_axis(self, axis_key): + if isinstance(axis_key, Group): + group_axis = axis_key.axis + if group_axis is not None: + # we have axis information but not necessarily an Axis object from self.axes + real_axis = self.axes[group_axis] + if group_axis is not real_axis: + axis_key = axis_key.with_axis(real_axis) + return axis_key + + # TODO: instead of checking all axes, we should have a big mapping + # (in AxisCollection or LArray): + # label -> (axis, index) + # or possibly (for ambiguous labels) + # label -> {axis: index} + # but for Pandas, this wouldn't work, we'd need label -> axis + valid_axes = [] + for axis in self.axes: + try: + axis.index(axis_key) + valid_axes.append(axis) + except KeyError: + continue + if not valid_axes: + raise ValueError("%s is not a valid label for any axis" % axis_key) + elif len(valid_axes) > 1: + valid_axes = ', '.join(a.name if a.name is not None else '{{{}}}'.format(self.axes.index(a)) + for a in valid_axes) + raise ValueError('%s is ambiguous (valid in %s)' % (axis_key, valid_axes)) + return valid_axes[0][axis_key] + + # TODO: move this to AxisCollection + def _translated_key(self, key, bool_stuff=False): + """Completes and translates key + + Parameters + ---------- + key : single axis key or tuple of keys or dict {axis_name: axis_key} + Each axis key can be either a scalar, a list of scalars or an LGroup. + + Returns + ------- + Returns a full N dimensional positional key. + """ + + if isinstance(key, np.ndarray) and np.issubdtype(key.dtype, np.bool_) and not bool_stuff: + return key.nonzero() + if isinstance(key, LArray) and np.issubdtype(key.dtype, np.bool_) and not bool_stuff: + # if only the axes order is wrong, transpose + # FIXME: if the key has both missing and extra axes, it could be the correct size (or even shape, see below) + if key.size == self.size and key.shape != self.shape: + return np.asarray(key.transpose(self.axes)).nonzero() + # otherwise we need to transform the key to integer + elif key.size != self.size: + extra_key_axes = key.axes - self.axes + if extra_key_axes: + raise ValueError("subset key %s contains more axes than array %s" % (key.axes, self.axes)) + + # do I want to allow key_axis.name to match against axis.num? does not seem like a good idea. + # but this should work + # >>> a = ndtest((3, 4)) + # >>> x1, x2 = a.axes + # >>> a[x2 > 2] + + # the current solution with hash = (labels, name) works but is slow for large axes and broken if axis + # labels are modified in-place, which I am unsure I want to support anyway + self.axes.check_compatible(key.axes) + local_axes = [self.axes[axis] for axis in key.axes] + map_key = dict(zip(local_axes, np.asarray(key).nonzero())) + return tuple(map_key.get(axis, slice(None)) for axis in self.axes) + else: + # correct shape + # FIXME: if the key has both missing and extra axes (at the index of the missing axes), the shape + # could be the same while the result should not + return np.asarray(key).nonzero() + + # convert scalar keys to 1D keys + if not isinstance(key, (tuple, dict)): + key = (key,) + + if isinstance(key, tuple): + # drop slice(None) and Ellipsis since they are meaningless because of guess_axis. + # XXX: we might want to raise an exception when we find Ellipses or (most) slice(None) because except for + # a single slice(None) a[:], I don't think there is any point. + key = [axis_key for axis_key in key + if not _isnoneslice(axis_key) and axis_key is not Ellipsis] + + # translate all keys to IGroup + key = [self._translate_axis_key(axis_key, bool_passthrough=not bool_stuff) + for axis_key in key] + + assert all(isinstance(axis_key, IGroup) for axis_key in key) + + # extract axis from Group keys + key_items = [(k.axis, k) for k in key] + else: + # key axes could be strings or axis references and we want real axes + key_items = [(self.axes[k], v) for k, v in key.items()] + # TODO: use _translate_axis_key (to translate to IGroup here too) + # key_items = [axis.translate(axis_key, bool_passthrough=not bool_stuff) + # for axis, axis_key in key_items] + + # even keys given as dict can contain duplicates (if the same axis was + # given under different forms, e.g. name and AxisReference). + dupe_axes = list(duplicates(axis for axis, axis_key in key_items)) + if dupe_axes: + dupe_axes = ', '.join(str(axis) for axis in dupe_axes) + raise ValueError("key has several values for axis: %s" % dupe_axes) + + key = dict(key_items) + + # dict -> tuple (complete and order key) + assert all(isinstance(k, Axis) for k in key) + key = [key[axis] if axis in key else slice(None) + for axis in self.axes] + + # IGroup -> raw positional + return tuple(axis.index(axis_key, bool_passthrough=not bool_stuff) + for axis, axis_key in zip(self.axes, key)) + + # TODO: we only need axes length => move this to AxisCollection + # (but this backend/numpy-specific so we'll probably need to create a subclass of it) + def _cross_key(self, key): + """ + Returns a key indexing the cross product. + + Parameters + ---------- + key : complete (contains all dimensions) index-based key. + + Returns + ------- + key + A key for indexing the cross product. + """ + + # handle advanced indexing with more than one indexing array: basic indexing (only integer and slices) and + # advanced indexing with only one indexing array are handled fine by numpy + if self._needs_advanced_indexing(key): + # np.ix_ wants only lists so: + + # 1) transform scalar-key to lists of 1 element. In that case, ndarray.__getitem__ leaves length 1 + # dimensions instead of dropping them like we would like, so we will need to drop them later ourselves + # (via reshape) + noscalar_key = [[axis_key] if np.isscalar(axis_key) else axis_key + for axis_key in key] + + # 2) expand slices to lists (ranges) + # XXX: cache the range in the axis? + # TODO: fork np.ix_ to allow for slices directly + # it will be tricky to get right though because in that case the result of a[key] can have its dimensions in + # the wrong order (if the ix_arrays are not next to each other, the corresponding dimensions are moved to + # the front). It is probably worth the trouble though because it is much faster than the current solution + # (~5x in my simple test) but this case (num_ix_arrays > 1) is rare in the first place (at least in demo) + # so it is not a priority. + listkey = tuple(np.arange(*axis_key.indices(len(axis))) if isinstance(axis_key, slice) else axis_key + for axis_key, axis in zip(noscalar_key, self.axes)) + # np.ix_ computes the cross product of all lists + return np.ix_(*listkey) + else: + return tuple(key) + + def _needs_advanced_indexing(self, key): + sequence = (tuple, list, np.ndarray) + # count number of indexing arrays (ie non scalar/slices) in tuple + num_ix_arrays = sum(isinstance(axis_key, sequence) for axis_key in key) + num_scalars = sum(np.isscalar(axis_key) for axis_key in key) + num_slices = sum(isinstance(axis_key, slice) for axis_key in key) + assert len(key) == num_ix_arrays + num_scalars + num_slices + return num_ix_arrays > 1 or (num_ix_arrays > 0 and num_scalars) + + def _collapse_slices(self, key): + # isinstance(ndarray, collections.Sequence) is False but it + # behaves like one + sequence = (tuple, list, np.ndarray) + return [_range_to_slice(axis_key, len(axis)) if isinstance(axis_key, sequence) else axis_key + for axis_key, axis in zip(key, self.axes)] + + def _get_axes_from_translated_key(self, translated_key, include_scalar_axis_key=False): + if include_scalar_axis_key: + return [axis.subaxis(axis_key) if not np.isscalar(axis_key) else Axis(1, axis.name) + for axis, axis_key in zip(self.axes, translated_key)] + else: + return [axis.subaxis(axis_key) + for axis, axis_key in zip(self.axes, translated_key) + if not np.isscalar(axis_key)] + + def __getitem__(self, key, collapse_slices=False): + + if isinstance(key, ExprNode): + key = key.evaluate(self.axes) + + data = np.asarray(self.data) + # XXX: I think I should split this into complete_key and translate_key because for LArray keys I need a + # complete key with axes for subaxis + translated_key = self._translated_key(key) + + # FIXME: I have a huge problem with boolean labels + non points + if isinstance(key, (LArray, np.ndarray)) and np.issubdtype(key.dtype, np.bool_): + return LArray(data[translated_key], self._bool_key_new_axes(translated_key)) + + if any(isinstance(axis_key, LArray) for axis_key in translated_key): + k2 = [k.data if isinstance(k, LArray) else k + for k in translated_key] + res_data = data[k2] + axes = self._get_axes_from_translated_key(translated_key) + first_col = AxisCollection(axes[0]) + res_axes = first_col.union(*axes[1:]) + return LArray(res_data, res_axes) + + # TODO: if the original key was a list of labels, subaxis(translated_key).labels == orig_key, so we should use + # orig_axis_key.copy() + axes = self._get_axes_from_translated_key(translated_key) + + if collapse_slices: + translated_key = self._collapse_slices(translated_key) + cross_key = self._cross_key(translated_key) + data = data[cross_key] + if not axes: + # scalars do not need to be wrapped in LArray + return data + else: + # drop length 1 dimensions created by scalar keys + res_data = data.reshape(tuple(len(axis) for axis in axes)) + assert _equal_modulo_len1(data.shape, res_data.shape) + return LArray(res_data, axes) + + def __setitem__(self, key, value, collapse_slices=True): + # TODO: if key or value has more axes than self, we should use + # total_axes = self.axes + key.axes + value.axes + # expanded = self.expand(total_axes) + # data = np.asarray(expanded.data) + + # concerning keys this can make sense in several cases: + # single bool LArray key with extra axes. + # tuple of bool LArray keys (eg one for each axis). each could have extra axes. Common axes between keys are + # not a problem, we can simply "and" them. Though we should avoid explicitly "and"ing them if there is no + # common axis because that is less efficient than the implicit "and" that is done by numpy __getitem__ (and + # the fact we need to combine dimensions when any key has more than 1 dim). + + # the bool value represents whether the axis label is taken or not if any bool key (part) has more than one + # axis, we get combined dimensions out of it. + + # int LArray keys + # the int value represent an index along ONE particular axis, even if the key has more than one axis. + if isinstance(key, ExprNode): + key = key.evaluate(self.axes) + + data = np.asarray(self.data) + translated_key = self._translated_key(key) + + if isinstance(key, (LArray, np.ndarray)) and np.issubdtype(key.dtype, np.bool_): + if isinstance(value, LArray): + new_axes = self._bool_key_new_axes(translated_key, wildcard_allowed=True) + value = value.broadcast_with(new_axes) + data[translated_key] = value + return + + if collapse_slices: + translated_key = self._collapse_slices(translated_key) + cross_key = self._cross_key(translated_key) + + if isinstance(value, LArray): + # XXX: we might want to create fakes (or wildcard?) axes in this case, as we only use axes names and axes + # length, not the ticks, and those could theoretically take a significant time to compute + if self._needs_advanced_indexing(translated_key): + # when adv indexing is needed, cross_key converts scalars to lists of 1 element, which does not remove + # the dimension like scalars normally do + axes = self._get_axes_from_translated_key(translated_key, True) + else: + axes = self._get_axes_from_translated_key(translated_key) + value = value.broadcast_with(axes) + value.axes.check_compatible(axes) + + # replace incomprehensible error message "could not broadcast input array from shape XX into shape YY" + # for users by "incompatible axes" + extra_axes = [axis for axis in value.axes - axes if len(axis) > 1] + if extra_axes: + extra_axes = AxisCollection(extra_axes) + axes = AxisCollection(axes) + text = 'axes are' if len(extra_axes) > 1 else 'axis is' + raise ValueError("Value {!s} {} not present in target subset {!s}. A value can only have the same axes " + "or fewer axes than the subset being targeted".format(extra_axes, text, axes)) + else: + # if value is a "raw" ndarray we rely on numpy broadcasting + pass + + data[cross_key] = value + + def _bool_key_new_axes(self, key, wildcard_allowed=False, sep='_'): + """ + Returns an AxisCollection containing combined axes. + Axes corresponding to scalar key are dropped. + + This method is used in case of boolean key. + + Parameters + ---------- + key : tuple + Position-based key + wildcard_allowed : bool + + Returns + ------- + AxisCollection + + Notes + ----- + See examples of properties `points` and `ipoints`. + """ + # TODO: use AxisCollection.combine_axes. The problem is that it uses product(*axes_labels) + # while here we need zip(*axes_labels) + combined_axes = [axis for axis_key, axis in zip(key, self.axes) + if not _isnoneslice(axis_key) and + not np.isscalar(axis_key)] + # scalar axes are not taken, since we want to kill them + other_axes = [axis for axis_key, axis in zip(key, self.axes) + if _isnoneslice(axis_key)] + assert len(key) > 0 + axes_indices = [self.axes.index(axis) for axis in combined_axes] + diff = np.diff(axes_indices) + # this can happen if key has only None slices and scalars + if not len(combined_axes): + combined_axis_pos = None + elif np.any(diff > 1): + # combined axes in front + combined_axis_pos = 0 + else: + combined_axis_pos = axes_indices[0] + # all anonymous axes => anonymous combined axis + if all(axis.name is None for axis in combined_axes): + combined_name = None + else: + combined_name = sep.join(str(self.axes.axis_id(axis)) for axis in combined_axes) + new_axes = other_axes + if combined_axis_pos is not None: + if wildcard_allowed: + lengths = [len(axis_key) for axis_key in key + if not _isnoneslice(axis_key) and not np.isscalar(axis_key)] + combined_axis_len = lengths[0] + assert all(l == combined_axis_len for l in lengths) + combined_axis = Axis(combined_axis_len, combined_name) + else: + # TODO: the combined keys should be objects which display as: + # (axis1_label, axis2_label, ...) but which should also store + # the axis (names?) + # Q: Should it be the same object as the NDLGroup?/NDKey? + # A: yes, probably. On the Pandas backend, we could/should have + # separate axes. On the numpy backend we cannot. + axes_labels = [axis.labels[axis_key] + for axis_key, axis in zip(key, self.axes) + if not _isnoneslice(axis_key) and not np.isscalar(axis_key)] + if len(combined_axes) == 1: + # Q: if axis is a wildcard axis, should the result be a + # wildcard axis (and axes_labels discarded?) + combined_labels = axes_labels[0] + else: + combined_labels = [sep.join(str(l) for l in comb) + for comb in zip(*axes_labels)] + + # CRAP, this can lead to duplicate labels (especially using .points) + combined_axis = Axis(combined_labels, combined_name) + new_axes.insert(combined_axis_pos, combined_axis) + return AxisCollection(new_axes) + + def set(self, value, **kwargs): + """ + Sets a subset of array to value. + + * all common axes must be either of length 1 or the same length + * extra axes in value must be of length 1 + * extra axes in current array can have any length + + Parameters + ---------- + value : scalar or LArray + + Examples + -------- + >>> arr = ndtest((3, 3)) + >>> arr + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + a2 6 7 8 + >>> arr['a1:', 'b1:'].set(10) + >>> arr + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 10 10 + a2 6 10 10 + >>> arr['a1:', 'b1:'].set(ndtest("a=a1,a2;b=b1,b2")) + >>> arr + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 0 1 + a2 6 2 3 + """ + self.__setitem__(kwargs, value) + + def reshape(self, target_axes): + """ + Given a list of new axes, changes the shape of the array. + The size of the array (= number of elements) must be equal + to the product of length of target axes. + + Parameters + ---------- + target_axes : iterable of Axis + New axes. The size of the array (= number of stored data) + must be equal to the product of length of target axes. + + Returns + ------- + LArray + New array with new axes but same data. + + Examples + -------- + >>> arr = ndtest((2, 2, 2)) + >>> arr + a b\\c c0 c1 + a0 b0 0 1 + a0 b1 2 3 + a1 b0 4 5 + a1 b1 6 7 + >>> new_arr = arr.reshape([Axis('a=a0,a1'), + ... Axis(['b0c0', 'b0c1', 'b1c0', 'b1c1'], 'bc')]) + >>> new_arr + a\\bc b0c0 b0c1 b1c0 b1c1 + a0 0 1 2 3 + a1 4 5 6 7 + """ + # this is a dangerous operation, because except for adding length 1 axes (which is safe), it potentially + # modifies data + # TODO: add a check/flag? for "unsafe" reshapes (but allow merging + # several axes & "splitting" axes) etc. + # eg 4, 3, 2 -> 2, 3, 4 is wrong (even if size is respected) + # 4, 3, 2 -> 12, 2 is potentially ok (merging adjacent dimensions) + # -> 4, 6 is potentially ok (merging adjacent dimensions) + # -> 24 is potentially ok (merging adjacent dimensions) + # -> 3, 8 WRONG (non adjacent dimensions) + # -> 8, 3 WRONG + # 4, 3, 2 -> 2, 2, 3, 2 is potentially ok (splitting dim) + data = np.asarray(self).reshape([len(axis) for axis in target_axes]) + return LArray(data, target_axes) + + def reshape_like(self, target): + """ + Same as reshape but with an array as input. + Total size (= number of stored data) of the two arrays must be equal. + + See Also + -------- + reshape : returns a LArray with a new shape given a list of axes. + + Examples + -------- + >>> arr = zeros((2, 2, 2), dtype=int) + >>> arr + {0}* {1}*\\{2}* 0 1 + 0 0 0 0 + 0 1 0 0 + 1 0 0 0 + 1 1 0 0 + >>> new_arr = arr.reshape_like(ndtest((2, 4))) + >>> new_arr + a\\b b0 b1 b2 b3 + a0 0 0 0 0 + a1 0 0 0 0 + """ + return self.reshape(target.axes) + + def broadcast_with(self, target): + """ + Returns an array that is (NumPy) broadcastable with target. + + * all common axes must be either of length 1 or the same length + * extra axes in source can have any length and will be moved to the + front + * extra axes in target can have any length and the result will have axes + of length 1 for those axes + + This is different from reshape which ensures the result has exactly the + shape of the target. + + Parameters + ---------- + target : LArray or collection of Axis + + Returns + ------- + LArray + """ + if isinstance(target, LArray): + target_axes = target.axes + else: + target_axes = target + if not isinstance(target, AxisCollection): + target_axes = AxisCollection(target_axes) + if self.axes == target_axes: + return self + + target_axes = (self.axes - target_axes) | target_axes + + # XXX: this breaks la['1,5,9'] = la['2,7,3'] + # but that use case should use drop_labels + # self.axes.check_compatible(target_axes) + + # 1) reorder axes to target order + array = self.transpose(target_axes & self.axes) + + # 2) add length one axes + return array.reshape(array.axes.get_all(target_axes)) + + # XXX: I wonder if effectively dropping the labels is necessary or not + # we could perfectly only mark the axis as being a wildcard axis and keep + # the labels intact. These wildcard axes with labels + # could be useful in a few situations. For example, Excel sheets could + # have such behavior: you can slice columns using letters, but that + # wouldn't prevent doing computation between arrays using different + # columns. On the other hand, it makes wild axes less obvious and I + # wonder if there would be a risk of wildcard axes inadvertently leaking. + # plus it might be confusing if incompatible labels "work". + def drop_labels(self, axes=None): + """Drops the labels from axes (replace those axes by "wildcard" axes). + + Useful when you want to apply operations between two arrays + or subarrays with same shape but incompatible axes + (different labels). + + Parameters + ---------- + axes : Axis or list/tuple/AxisCollection of Axis, optional + Axis(es) on which you want to drop the labels. + + Returns + ------- + LArray + + Notes + ----- + Use it at your own risk. + + Examples + -------- + >>> a = Axis('a=a1,a2') + >>> b = Axis('b=b1,b2') + >>> b2 = Axis('b=b2,b3') + >>> arr1 = ndtest([a, b]) + >>> arr1 + a\\b b1 b2 + a1 0 1 + a2 2 3 + >>> arr1.drop_labels(b) + a\\b* 0 1 + a1 0 1 + a2 2 3 + >>> arr1.drop_labels([a, b]) + a*\\b* 0 1 + 0 0 1 + 1 2 3 + >>> arr2 = ndtest([a, b2]) + >>> arr2 + a\\b b2 b3 + a1 0 1 + a2 2 3 + >>> arr1 * arr2 + Traceback (most recent call last): + ... + ValueError: incompatible axes: + Axis(['b2', 'b3'], 'b') + vs + Axis(['b1', 'b2'], 'b') + >>> arr1 * arr2.drop_labels() + a\\b b1 b2 + a1 0 1 + a2 4 9 + >>> arr1.drop_labels() * arr2 + a\\b b2 b3 + a1 0 1 + a2 4 9 + >>> arr1.drop_labels(X.a) * arr2.drop_labels(X.b) + a\\b b1 b2 + a1 0 1 + a2 4 9 + """ + if axes is None: + axes = self.axes + if not isinstance(axes, (tuple, list, AxisCollection)): + axes = [axes] + old_axes = self.axes[axes] + new_axes = [Axis(len(axis), axis.name) for axis in old_axes] + res_axes = self.axes[:] + res_axes[axes] = new_axes + return LArray(self.data, res_axes) + + def __str__(self): + if not self.ndim: + return str(np.asscalar(self)) + elif not len(self): + return 'LArray([])' + else: + table = list(self.as_table(maxlines=200, edgeitems=5)) + return table2str(table, 'nan', fullinfo=True, maxwidth=200, keepcols=self.ndim - 1) + __repr__ = __str__ + + def __iter__(self): + return LArrayIterator(self) + + def __contains__(self, key): + return any(key in axis for axis in self.axes) + + def as_table(self, maxlines=None, edgeitems=5, light=False): + """ + Generator. Returns next line of the table representing an array. + + Parameters + ---------- + maxlines : int, optional + Maximum number of lines to show. + edgeitems : int, optional + If number of lines to display is greater than `maxlines`, + only the first and last `edgeitems` lines are displayed. + Only active if `maxlines` is not None. + Equals to 5 by default. + + Returns + ------- + list + Next line of the table as a list. + + Examples + -------- + >>> arr = ndtest((2, 2, 3)) + >>> list(arr.as_table()) # doctest: +NORMALIZE_WHITESPACE + [['a', 'b\\\\c', 'c0', 'c1', 'c2'], + ['a0', 'b0', 0, 1, 2], + ['a0', 'b1', 3, 4, 5], + ['a1', 'b0', 6, 7, 8], + ['a1', 'b1', 9, 10, 11]] + >>> list(arr.as_table(light=True)) # doctest: +NORMALIZE_WHITESPACE + [['a', 'b\\\\c', 'c0', 'c1', 'c2'], + ['a0', 'b0', 0, 1, 2], + ['', 'b1', 3, 4, 5], + ['a1', 'b0', 6, 7, 8], + ['', 'b1', 9, 10, 11]] + """ + if not self.ndim: + return + + # ert unit geo\time 2012 2011 2010 + # NEER27 I05 AT 101.41 101.63 101.63 + # NEER27 I05 AU 134.86 125.29 117.08 + width = self.shape[-1] + height = int(np.prod(self.shape[:-1])) + data = np.asarray(self).reshape(height, width) + + # get list of names of axes + axes_names = self.axes.display_names[:] + # transforms ['a', 'b', 'c', 'd'] into ['a', 'b', 'c\\d'] + if len(axes_names) > 1: + axes_names[-2] = '\\'.join(axes_names[-2:]) + axes_names.pop() + # get list of labels for each axis except the last one. + labels = [axis.labels.tolist() for axis in self.axes[:-1]] + # creates vertical lines (ticks is a list of list) + if self.ndim == 1: + # There is no vertical axis, so the axis name should not have + # any "tick" below it and we add an empty "tick". + ticks = [['']] + elif light: + ticks = light_product(*labels) + else: + ticks = product(*labels) + # returns the first line (axes names + labels of last axis) + yield axes_names + self.axes[-1].labels.tolist() + # summary if needed + if maxlines is not None and height > maxlines: + # replace middle lines of the table by '...'. + # We show only the first and last edgeitems lines. + startticks = islice(ticks, edgeitems) + midticks = [["..."] * (self.ndim - 1)] + endticks = list(islice(rproduct(*labels), edgeitems))[::-1] + ticks = chain(startticks, midticks, endticks) + data = chain(data[:edgeitems].tolist(), + [["..."] * width], + data[-edgeitems:].tolist()) + for tick, dataline in izip(ticks, data): + # returns next line (labels of N-1 first axes + data) + yield list(tick) + dataline + else: + for tick, dataline in izip(ticks, data): + # returns next line (labels of N-1 first axes + data) + yield list(tick) + dataline.tolist() + + def dump(self, header=True): + """Dump array as a 2D nested list + + Parameters + ---------- + header : bool + Whether or not to output axes names and labels. + + Returns + ------- + 2D nested list + """ + if not header: + # flatten all dimensions except the last one + return self.data.reshape(-1, self.shape[-1]).tolist() + else: + return list(self.as_table()) + + # XXX: should filter(geo=['W']) return a view by default? (collapse=True) + # I think it would be dangerous to make it the default + # behavior, because that would introduce a subtle difference between + # filter(dim=[a, b]) and filter(dim=[a]) even though it would be faster + # and uses less memory. Maybe I should have a "view" argument which + # defaults to 'auto' (ie collapse by default), can be set to False to + # force a copy and to True to raise an exception if a view is not possible. + def filter(self, collapse=False, **kwargs): + """Filters the array along the axes given as keyword arguments. + + The *collapse* argument determines whether consecutive ranges should + be collapsed to slices, which is more efficient and returns a view + (and not a copy) if possible (if all ranges are consecutive). + Only use this argument if you do not intent to modify the resulting + array, or if you know what you are doing. + + It is similar to np.take but works with several axes at once. + """ + return self.__getitem__(kwargs, collapse) + + def _axis_aggregate(self, op, axes=(), keepaxes=False, out=None, **kwargs): + """ + Parameters + ---------- + op : function + An aggregate function with this signature: func(a, axis=None, dtype=None, out=None, keepdims=False) + axes : tuple of axes, optional + Each axis can be an Axis object, str or int. + out : LArray, optional + Alternative output array in which to place the result. It must have the same shape as the expected output. + keepaxes : bool or scalar, optional + If this is set to True, the axes which are reduced are left in the result as dimensions with size one. + + Returns + ------- + LArray or scalar + """ + src_data = np.asarray(self) + axes = self.axes[list(axes)] if axes else self.axes + axes_indices = tuple(self.axes.index(a) for a in axes) if axes != self.axes else None + if op.__name__ == 'ptp': + if axes_indices is not None and len(axes) > 1: + raise ValueError('ptp can only be applied along a single axis or all axes, not multiple arbitrary axes') + elif axes_indices is not None: + axes_indices = axes_indices[0] + else: + kwargs['keepdims'] = bool(keepaxes) + if out is not None: + assert isinstance(out, LArray) + kwargs['out'] = out.data + res_data = op(src_data, axis=axes_indices, **kwargs) + if keepaxes: + label = op.__name__.replace('nan', '') if keepaxes is True else keepaxes + new_axes = [Axis([label], axis.name) for axis in axes] + res_axes = self.axes[:] + res_axes[axes] = new_axes + else: + res_axes = self.axes - axes + if not res_axes: + # scalars don't need to be wrapped in LArray + return res_data + else: + return LArray(res_data, res_axes) + + def _cum_aggregate(self, op, axis): + """ + op is a numpy cumulative aggregate function: func(arr, axis=0). + axis is an Axis object, a str or an int. Contrary to other aggregate functions this only supports one axis at a + time. + """ + # TODO: accept a single group in axis, to filter & aggregate in one shot + return LArray(op(np.asarray(self), axis=self.axes.index(axis)), + self.axes) + + # TODO: now that items is never a (k, v), it should be renamed to + # something else: args? (groups would be misleading because each "item" can contain several groups) + # TODO: experiment implementing this using ufunc.reduceat + # http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.ufunc.reduceat.html + # XXX: rename keepaxes to label=value? For group_aggregates we might want to keep the LGroup label if any + def _group_aggregate(self, op, items, keepaxes=False, out=None, **kwargs): + assert out is None + res = self + # TODO: when working with several "axes" at the same times, we should not produce the intermediary result at + # all. It should be faster and consume a bit less memory. + for item in items: + res_axes = res.axes[:] + res_shape = list(res.shape) + + if isinstance(item, tuple): + assert all(isinstance(g, Group) for g in item) + groups = item + axis = groups[0].axis + # they should all have the same axis (this is already checked + # in _prepare_aggregate though) + assert all(g.axis.equals(axis) for g in groups[1:]) + killaxis = False + else: + # item is in fact a single group + assert isinstance(item, Group), type(item) + groups = (item,) + axis = item.axis + # it is easier to kill the axis after the fact + killaxis = True + + axis, axis_idx = res.axes[axis], res.axes.index(axis) + # potentially translate axis reference to real axes + groups = tuple(g.with_axis(axis) for g in groups) + res_shape[axis_idx] = len(groups) + + # XXX: this code is fragile. I wonder if there isn't a way to ask the function what kind of dtype/shape it + # will return given the input we are going to give it. My first search for this found nothing. One + # way to do this would be to create one big mapping: {(op, input dtype): res dtype} + res_dtype = float if op in _always_return_float else res.dtype + if op in (np.sum, np.nansum) and res.dtype in (np.bool, np.bool_): + res_dtype = int + res_data = np.empty(res_shape, dtype=res_dtype) + + group_idx = [slice(None) for _ in res_shape] + for i, group in enumerate(groups): + group_idx[axis_idx] = i + # this is only useful for ndim == 1 because a[(0,)] (equivalent to a[0] which kills the axis) + # is different from a[[0]] (which does not kill the axis) + idx = tuple(group_idx) + + # we need only lists of ticks, not single ticks, otherwise the dimension is discarded too early + # (in __getitem__ instead of in the aggregate func) + if isinstance(group, IGroup) and np.isscalar(group.key): + group = IGroup([group.key], axis=group.axis) + elif isinstance(group, LGroup): + key = _to_key(group.key) + assert not isinstance(key, Group) + if np.isscalar(key): + key = [key] + # we do not care about the name at this point + group = LGroup(key, axis=group.axis) + + arr = res.__getitem__(group, collapse_slices=True) + if res_data.ndim == 1: + assert len(idx) == 1 and idx[0] == i + + # res_data[idx] but instead of returning a scalar (eg np.int32), it returns a 0d array which is a + # view on res_data, which can thus be used as out + out = res_data[i:i + 1].reshape(()) + else: + out = res_data[idx] + + arr = np.asarray(arr) + op(arr, axis=axis_idx, out=out, **kwargs) + del arr + if killaxis: + assert group_idx[axis_idx] == 0 + res_data = res_data[idx] + del res_axes[axis_idx] + else: + # We do NOT modify the axis name (eg append "_agg" or "*") even though this creates a new axis that is + # independent from the original one because the original name is what users will want to use to access + # that axis (eg in .filter kwargs) + res_axes[axis_idx] = Axis(groups, axis.name) + + if isinstance(res_data, np.ndarray): + res = LArray(res_data, res_axes) + else: + res = res_data + return res + + def _prepare_aggregate(self, op, args, kwargs=None, commutative=False, stack_depth=1): + """converts args to keys & LGroup and kwargs to LGroup""" + + if kwargs is None: + kwargs_items = [] + else: + explicit_axis = kwargs.pop('axis', None) + if explicit_axis is not None: + explicit_axis = self.axes[explicit_axis] + if isinstance(explicit_axis, Axis): + args += (explicit_axis,) + else: + assert isinstance(explicit_axis, AxisCollection) + args += tuple(explicit_axis) + kwargs_items = kwargs.items() + if not commutative and len(kwargs_items) > 1: + # TODO: lift this restriction for python3.6+ + raise ValueError("grouping aggregates on multiple axes at the same time using keyword arguments is not " + "supported for '%s' (because it is not a commutative operation and keyword arguments are " + "*not* ordered in Python)" % op.__name__) + + # Sort kwargs by axis name so that we have consistent results between runs because otherwise rounding errors + # could lead to slightly different results even for commutative operations. + sorted_kwargs = sorted(kwargs_items) + + # convert kwargs to LGroup so that we can only use args afterwards but still keep the axis information + def standardise_kw_arg(axis_name, key, stack_depth=1): + if isinstance(key, str): + key = _to_keys(key, stack_depth + 1) + if isinstance(key, tuple): + # XXX +2? + return tuple(standardise_kw_arg(axis_name, k, stack_depth + 1) for k in key) + if isinstance(key, LGroup): + return key + return self.axes[axis_name][key] + + def to_labelgroup(key, stack_depth=1): + if isinstance(key, str): + key = _to_keys(key, stack_depth + 1) + if isinstance(key, tuple): + # a tuple is supposed to be several groups on the same axis + # TODO: it would be better to use self._translate_axis_key directly (so that we do not need to do the + # label -> position translation twice) but this fails because the groups are also used as ticks on the + # new axis, and igroups are not the same that LGroups in this regard (I wonder if ideally it shouldn't + # be the same???) + # groups = tuple(self._translate_axis_key(k) for k in key) + groups = tuple(self._guess_axis(_to_key(k, stack_depth + 1)) for k in key) + axis = groups[0].axis + if not all(g.axis.equals(axis) for g in groups[1:]): + raise ValueError("group with different axes: %s" % str(key)) + return groups + if isinstance(key, (Group, int, basestring, list, slice)): + return self._guess_axis(key) + else: + raise NotImplementedError("%s has invalid type (%s) for a group aggregate key" + % (key, type(key).__name__)) + + def standardise_arg(arg, stack_depth=1): + if self.axes.isaxis(arg): + return self.axes[arg] + else: + return to_labelgroup(arg, stack_depth + 1) + + operations = [standardise_arg(a, stack_depth=stack_depth + 2) for a in args if a is not None] + \ + [standardise_kw_arg(k, v, stack_depth=stack_depth + 2) for k, v in sorted_kwargs] + if not operations: + # op() without args is equal to op(all_axes) + operations = self.axes + return operations + + def _by_args_to_normal_agg_args(self, operations): + # get axes to aggregate + flat_op = chain.from_iterable([(o,) if isinstance(o, (Group, Axis)) else o + for o in operations]) + axes = [o.axis if isinstance(o, Group) else o for o in flat_op] + to_agg = self.axes - axes + + # add groups to axes to aggregate + def is_or_contains_group(o): + return isinstance(o, Group) or (isinstance(o, tuple) and isinstance(o[0], Group)) + + return list(to_agg) + [o for o in operations if is_or_contains_group(o)] + + def _aggregate(self, op, args, kwargs=None, keepaxes=False, by_agg=False, commutative=False, + out=None, extra_kwargs={}): + operations = self._prepare_aggregate(op, args, kwargs, commutative, stack_depth=3) + if by_agg and operations != self.axes: + operations = self._by_args_to_normal_agg_args(operations) + + res = self + # group *consecutive* same-type (group vs axis aggregates) operations + # we do not change the order of operations since we only group consecutive operations. + for are_axes, axes in groupby(operations, self.axes.isaxis): + func = res._axis_aggregate if are_axes else res._group_aggregate + res = func(op, axes, keepaxes=keepaxes, out=out, **extra_kwargs) + return res + + # op=sum does not parse correctly + def with_total(self, *args, **kwargs): + """with_total(*args, op='sum', label='total', **kwargs) + + Add aggregated values (sum by default) along each axis. + A user defined label can be given to specified the computed values. + + Parameters + ---------- + *args : int or str or Axis or Group or any combination of those, optional + Axes or groups along which to compute the aggregates. Passed groups should be named. + Defaults to aggregate over the whole array. + op : aggregate function, optional + Defaults to `sum`. + label : scalar value, optional + Label to use for the total. Applies only to aggregated axes, not groups. Defaults to "total". + **kwargs : int or str or Group or any combination of those, optional + Axes or groups along which to compute the aggregates. + + Returns + ------- + LArray + + Examples + -------- + >>> arr = ndtest((3, 3)) + >>> arr + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + a2 6 7 8 + >>> arr.with_total() + a\\b b0 b1 b2 total + a0 0 1 2 3 + a1 3 4 5 12 + a2 6 7 8 21 + total 9 12 15 36 + >>> arr.with_total('a', 'b0,b1 >> total_01') + a\\b b0 b1 b2 total_01 + a0 0 1 2 1 + a1 3 4 5 7 + a2 6 7 8 13 + total 9 12 15 21 + >>> arr.with_total(op=prod, label='product') + a\\b b0 b1 b2 product + a0 0 1 2 0 + a1 3 4 5 60 + a2 6 7 8 336 + product 0 28 80 0 + """ + # TODO: default to op.__name__ + label = kwargs.pop('label', 'total') + op = kwargs.pop('op', sum) + npop = { + sum: np.sum, + prod: np.prod, + min: np.min, + max: np.max, + mean: np.mean, + ptp: np.ptp, + var: np.var, + std: np.std, + median: np.median, + percentile: np.percentile, + } + # TODO: commutative should be known for usual ops + operations = self._prepare_aggregate(op, args, kwargs, False, stack_depth=2) + res = self + # TODO: we should allocate the final result directly and fill it progressively, so that the original array is + # only copied once + for axis in operations: + # TODO: append/extend first with an empty array then _aggregate with out= + if self.axes.isaxis(axis): + value = res._axis_aggregate(npop[op], (axis,), keepaxes=label) + else: + # groups + if not isinstance(axis, tuple): + # assume a single group + axis = (axis,) + lgkey = axis + axis = lgkey[0].axis + value = res._aggregate(npop[op], (lgkey,)) + res = res.extend(axis, value) + return res + + # TODO: make sure we can do + # arr[x.sex.i[arr.indexofmin(x.sex)]] <- fails + # and + # arr[arr.labelofmin(x.sex)] <- fails + # should both be equal to arr.min(x.sex) + # the versions where axis is None already work as expected in the simple + # case (no ambiguous labels): + # arr.i[arr.indexofmin()] + # arr[arr.labelofmin()] + # for the case where axis is None, we should return an NDGroup + # so that arr[arr.labelofmin()] works even if the minimum is on ambiguous labels + def labelofmin(self, axis=None): + """Returns labels of the minimum values along a given axis. + + Parameters + ---------- + axis : int or str or Axis, optional + Axis along which to work. If not specified, works on the full array. + + Returns + ------- + LArray + + Notes + ----- + In case of multiple occurrences of the minimum values, the indices corresponding to the first occurrence are + returned. + + Examples + -------- + >>> nat = Axis('nat=BE,FR,IT') + >>> sex = Axis('sex=M,F') + >>> arr = LArray([[0, 1], [3, 2], [2, 5]], [nat, sex]) + >>> arr + nat\\sex M F + BE 0 1 + FR 3 2 + IT 2 5 + >>> arr.labelofmin(X.sex) + nat BE FR IT + M F M + >>> arr.labelofmin() + ('BE', 'M') + """ + if axis is not None: + axis, axis_idx = self.axes[axis], self.axes.index(axis) + data = axis.labels[self.data.argmin(axis_idx)] + return LArray(data, self.axes - axis) + else: + indices = np.unravel_index(self.data.argmin(), self.shape) + return tuple(axis.labels[i] for i, axis in zip(indices, self.axes)) + + argmin = renamed_to(labelofmin, 'argmin') + + def indexofmin(self, axis=None): + """Returns indices of the minimum values along a given axis. + + Parameters + ---------- + axis : int or str or Axis, optional + Axis along which to work. If not specified, works on the full array. + + Returns + ------- + LArray + + Notes + ----- + In case of multiple occurrences of the minimum values, the indices corresponding to the first occurrence are + returned. + + Examples + -------- + >>> nat = Axis('nat=BE,FR,IT') + >>> sex = Axis('sex=M,F') + >>> arr = LArray([[0, 1], [3, 2], [2, 5]], [nat, sex]) + >>> arr + nat\\sex M F + BE 0 1 + FR 3 2 + IT 2 5 + >>> arr.indexofmin(X.sex) + nat BE FR IT + 0 1 0 + >>> arr.indexofmin() + (0, 0) + """ + if axis is not None: + axis, axis_idx = self.axes[axis], self.axes.index(axis) + return LArray(self.data.argmin(axis_idx), self.axes - axis) + else: + return np.unravel_index(self.data.argmin(), self.shape) + + posargmin = renamed_to(indexofmin, 'posargmin') + + def labelofmax(self, axis=None): + """Returns labels of the maximum values along a given axis. + + Parameters + ---------- + axis : int or str or Axis, optional + Axis along which to work. If not specified, works on the full array. + + Returns + ------- + LArray + + Notes + ----- + In case of multiple occurrences of the maximum values, the labels corresponding to the first occurrence are + returned. + + Examples + -------- + >>> nat = Axis('nat=BE,FR,IT') + >>> sex = Axis('sex=M,F') + >>> arr = LArray([[0, 1], [3, 2], [2, 5]], [nat, sex]) + >>> arr + nat\\sex M F + BE 0 1 + FR 3 2 + IT 2 5 + >>> arr.labelofmax(X.sex) + nat BE FR IT + F M F + >>> arr.labelofmax() + ('IT', 'F') + """ + if axis is not None: + axis, axis_idx = self.axes[axis], self.axes.index(axis) + data = axis.labels[self.data.argmax(axis_idx)] + return LArray(data, self.axes - axis) + else: + indices = np.unravel_index(self.data.argmax(), self.shape) + return tuple(axis.labels[i] for i, axis in zip(indices, self.axes)) + + argmax = renamed_to(labelofmax, 'argmax') + + def indexofmax(self, axis=None): + """Returns indices of the maximum values along a given axis. + + Parameters + ---------- + axis : int or str or Axis, optional + Axis along which to work. If not specified, works on the full array. + + Returns + ------- + LArray + + Notes + ----- + In case of multiple occurrences of the maximum values, the labels corresponding to the first occurrence are + returned. + + Examples + -------- + >>> nat = Axis('nat=BE,FR,IT') + >>> sex = Axis('sex=M,F') + >>> arr = LArray([[0, 1], [3, 2], [2, 5]], [nat, sex]) + >>> arr + nat\\sex M F + BE 0 1 + FR 3 2 + IT 2 5 + >>> arr.indexofmax(X.sex) + nat BE FR IT + 1 0 1 + >>> arr.indexofmax() + (2, 1) + """ + if axis is not None: + axis, axis_idx = self.axes[axis], self.axes.index(axis) + return LArray(self.data.argmax(axis_idx), self.axes - axis) + else: + return np.unravel_index(self.data.argmax(), self.shape) + + posargmax = renamed_to(indexofmax, 'posargmax') + + def labelsofsorted(self, axis=None, ascending=True, kind='quicksort'): + """Returns the labels that would sort this array. + + Performs an indirect sort along the given axis using the algorithm specified by the `kind` keyword. It returns + an array of labels of the same shape as `a` that index data along the given axis in sorted order. + + Parameters + ---------- + axis : int or str or Axis, optional + Axis along which to sort. This can be omitted if array has only one axis. + ascending : bool, optional + Sort values in ascending order. Defaults to True. + kind : {'quicksort', 'mergesort', 'heapsort'}, optional + Sorting algorithm. Defaults to 'quicksort'. + + Returns + ------- + LArray + + Examples + -------- + >>> arr = LArray([[0, 1], [3, 2], [2, 5]], "nat=BE,FR,IT; sex=M,F") + >>> arr + nat\\sex M F + BE 0 1 + FR 3 2 + IT 2 5 + >>> arr.labelsofsorted('sex') + nat\\sex 0 1 + BE M F + FR F M + IT M F + >>> arr.labelsofsorted('sex', ascending=False) + nat\\sex 0 1 + BE F M + FR M F + IT F M + """ + if axis is None: + if self.ndim > 1: + raise ValueError("array has ndim > 1 and no axis specified for labelsofsorted") + axis = self.axes[0] + axis = self.axes[axis] + pos = self.indicesofsorted(axis, ascending=ascending, kind=kind) + return LArray(axis.labels[pos.data], pos.axes) + + argsort = renamed_to(labelsofsorted, 'argsort') + + def indicesofsorted(self, axis=None, ascending=True, kind='quicksort'): + """Returns the indices that would sort this array. + + Performs an indirect sort along the given axis using the algorithm specified by the `kind` keyword. It returns + an array of indices with the same axes as `a` that index data along the given axis in sorted order. + + Parameters + ---------- + axis : int or str or Axis, optional + Axis along which to sort. This can be omitted if array has only one axis. + ascending : bool, optional + Sort values in ascending order. Defaults to True. + kind : {'quicksort', 'mergesort', 'heapsort'}, optional + Sorting algorithm. Defaults to 'quicksort'. + + Returns + ------- + LArray + + Examples + -------- + >>> arr = LArray([[1, 5], [3, 2], [0, 4]], "nat=BE,FR,IT; sex=M,F") + >>> arr + nat\\sex M F + BE 1 5 + FR 3 2 + IT 0 4 + >>> arr.indicesofsorted('nat') + nat\\sex M F + 0 2 1 + 1 0 2 + 2 1 0 + >>> arr.indicesofsorted('nat', ascending=False) + nat\\sex M F + 0 1 0 + 1 0 2 + 2 2 1 + """ + if axis is None: + if self.ndim > 1: + raise ValueError("array has ndim > 1 and no axis specified for indicesofsorted") + axis = self.axes[0] + axis, axis_idx = self.axes[axis], self.axes.index(axis) + data = self.data.argsort(axis_idx, kind=kind) + if not ascending: + reverser = tuple(slice(None, None, -1) if i == axis_idx else slice(None) + for i in range(self.ndim)) + data = data[reverser] + new_axis = Axis(np.arange(len(axis)), axis.name) + return LArray(data, self.axes.replace(axis, new_axis)) + + posargsort = renamed_to(indicesofsorted, 'posargsort') + + def copy(self): + """Returns a copy of the array. + """ + return LArray(self.data.copy(), axes=self.axes[:], title=self.title) + + @property + def info(self): + """Describes a LArray (title + shape and labels for each axis). + + Returns + ------- + str + Description of the array (title + shape and labels for each axis). + + Examples + -------- + >>> mat0 = LArray([[2.0, 5.0], [8.0, 6.0]], "nat=BE,FO; sex=F,M") + >>> mat0.info + 2 x 2 + nat [2]: 'BE' 'FO' + sex [2]: 'F' 'M' + dtype: float64 + memory used: 32 bytes + >>> mat1 = LArray([[2.0, 5.0], [8.0, 6.0]], "nat=BE,FO; sex=F,M", 'test matrix') + >>> mat1.info + test matrix + 2 x 2 + nat [2]: 'BE' 'FO' + sex [2]: 'F' 'M' + dtype: float64 + memory used: 32 bytes + """ + str_info = '{}\n'.format(self.title) if self.title else '' + str_info += '{}\ndtype: {}\nmemory used: {}'.format(self.axes.info, self.dtype.name, self.memory_used) + return ReprString(str_info) + + def ratio(self, *axes): + """Returns an array with all values divided by the sum of values along given axes. + + Parameters + ---------- + *axes + + Returns + ------- + LArray + array / array.sum(axes) + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> a = LArray([[4, 6], [2, 8]], [nat, sex]) + >>> a + nat\\sex M F + BE 4 6 + FO 2 8 + >>> a.sum() + 20 + >>> a.ratio() + nat\\sex M F + BE 0.2 0.3 + FO 0.1 0.4 + >>> a.ratio(X.sex) + nat\\sex M F + BE 0.4 0.6 + FO 0.2 0.8 + >>> a.ratio('M') + nat\\sex M F + BE 1.0 1.5 + FO 1.0 4.0 + """ + # # this does not work, but I am unsure it should + # # >>> a.sum(age[[0, 1]], age[2]) / a.sum(age) + # >>> a.sum(([0, 1], 2)) / a.sum(age) + # # >>> a / a.sum(([0, 1], 2)) + # >>> a.sum(x.sex) + # >>> a.sum(x.age) + # >>> a.sum(x.sex) / a.sum(x.age) + # >>> a.ratio('F') + # could mean + # >>> a.sum('F') / a.sum(a.get_axis('F')) + # >>> a.sum('F') / a.sum(x.sex) + # age 0 1 2 + # 1.0 0.6 0.555555555556 + # OR (current meaning) + # >>> a / a.sum('F') + # age\\sex M F + # 0 0.0 1.0 + # 1 0.666666666667 1.0 + # 2 0.8 1.0 + # One solution is to add an argument + # >>> a.ratio(what='F', by=x.sex) + # age 0 1 2 + # 1.0 0.6 0.555555555556 + # >>> a.sum('F') / a.sum(x.sex) + + # >>> a.sum((age[[0, 1]], age[[1, 2]])) / a.sum(age) + # >>> a.ratio((age[[0, 1]], age[[1, 2]]), by=age) + + # >>> a.sum((x.age[[0, 1]], x.age[[1, 2]])) / a.sum(x.age) + # >>> a.ratio((x.age[[0, 1]], x.age[[1, 2]], by=x.age) + + # >>> lalala.sum(([0, 1], [1, 2])) / lalala.sum(x.age) + # >>> lalala.ratio(([0, 1], [1, 2]), by=x.age) + + # >>> b = a.sum((age[[0, 1]], age[[1, 2]])) + # >>> b + # age\sex M F + # [0 1] 2 4 + # [1 2] 6 8 + # >>> b / b.sum(x.age) + # age\\sex M F + # [0 1] 0.25 0.333333333333 + # [1 2] 0.75 0.666666666667 + # >>> b / a.sum(x.age) + # age\\sex M F + # [0 1] 0.333333333333 0.444444444444 + # [1 2] 1.0 0.888888888889 + # # >>> a.ratio([0, 1], [2]) + # # >>> a.ratio(x.age[[0, 1]], x.age[2]) + # >>> a.ratio((x.age[[0, 1]], x.age[2])) + # nat\\sex M F + # BE 0.0 1.0 + # FO 0.6666666666 1.0 + return self / self.sum(*axes) + + def rationot0(self, *axes): + """Returns a LArray with values array / array.sum(axes) where the sum is not 0, 0 otherwise. + + Parameters + ---------- + *axes + + Returns + ------- + LArray + array / array.sum(axes) + + Examples + -------- + >>> a = Axis('a=a0,a1') + >>> b = Axis('b=b0,b1,b2') + >>> arr = LArray([[6, 0, 2], + ... [4, 0, 8]], [a, b]) + >>> arr + a\\b b0 b1 b2 + a0 6 0 2 + a1 4 0 8 + >>> arr.sum() + 20 + >>> arr.rationot0() + a\\b b0 b1 b2 + a0 0.3 0.0 0.1 + a1 0.2 0.0 0.4 + >>> arr.rationot0(X.a) + a\\b b0 b1 b2 + a0 0.6 0.0 0.2 + a1 0.4 0.0 0.8 + + for reference, the normal ratio method would return: + + >>> arr.ratio(X.a) + a\\b b0 b1 b2 + a0 0.6 nan 0.2 + a1 0.4 nan 0.8 + """ + return self.divnot0(self.sum(*axes)) + + def percent(self, *axes): + """Returns an array with values given as percent of the total of all values along given axes. + + Parameters + ---------- + *axes + + Returns + ------- + LArray + array / array.sum(axes) * 100 + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> a = LArray([[4, 6], [2, 8]], [nat, sex]) + >>> a + nat\\sex M F + BE 4 6 + FO 2 8 + >>> a.percent() + nat\\sex M F + BE 20.0 30.0 + FO 10.0 40.0 + >>> a.percent(X.sex) + nat\\sex M F + BE 40.0 60.0 + FO 20.0 80.0 + """ + # dividing by self.sum(*axes) * 0.01 would be faster in many cases but I suspect it loose more precision. + return self * 100 / self.sum(*axes) + + # aggregate method decorator + def _decorate_agg_method(npfunc, nanfunc=None, commutative=False, by_agg=False, extra_kwargs=[], + long_name='', action_verb='perform'): + def decorated(func): + _doc_agg_method(func, by_agg, long_name, action_verb, kwargs=extra_kwargs + ['out', 'skipna', 'keepaxes']) + + @functools.wraps(func) + def wrapper(self, *args, **kwargs): + keepaxes = kwargs.pop('keepaxes', _kwarg_agg['keepaxes']['value']) + skipna = kwargs.pop('skipna', _kwarg_agg['skipna']['value']) + out = kwargs.pop('out', _kwarg_agg['out']['value']) + if skipna is None: + skipna = nanfunc is not None + if skipna and nanfunc is None: + raise ValueError("skipna is not available for {}".format(func.__name__)) + _npfunc = nanfunc if skipna else npfunc + _extra_kwargs = {} + for k in extra_kwargs: + _extra_kwargs[k] = kwargs.pop(k, _kwarg_agg[k]['value']) + return self._aggregate(_npfunc, args, kwargs, by_agg=by_agg, keepaxes=keepaxes, + commutative=commutative, out=out, extra_kwargs=_extra_kwargs) + return wrapper + return decorated + + @_decorate_agg_method(np.all, commutative=True, long_name="AND reduction") + def all(self, *args, **kwargs): + """{signature} + Test whether all selected elements evaluate to True. + + {parameters} + + Returns + ------- + LArray of bool or bool + + See Also + -------- + LArray.all_by, LArray.any, LArray.any_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> barr = arr < 6 + >>> barr + a\\b b0 b1 b2 b3 + a0 True True True True + a1 True True False False + a2 False False False False + a3 False False False False + >>> barr.all() + False + >>> # along axis 'a' + >>> barr.all(X.a) + b b0 b1 b2 b3 + False False False False + >>> # along axis 'b' + >>> barr.all(X.b) + a a0 a1 a2 a3 + True False False False + + Select some rows only + + >>> barr.all(['a0', 'a1']) + b b0 b1 b2 b3 + True True False False + >>> # or equivalently + >>> # barr.all('a0,a1') + + Split an axis in several parts + + >>> barr.all((['a0', 'a1'], ['a2', 'a3'])) + a\\b b0 b1 b2 b3 + a0,a1 True True False False + a2,a3 False False False False + >>> # or equivalently + >>> # barr.all('a0,a1;a2,a3') + + Same with renaming + + >>> barr.all((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a\\b b0 b1 b2 b3 + a01 True True False False + a23 False False False False + >>> # or equivalently + >>> # barr.all('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.all, commutative=True, by_agg=True, long_name="AND reduction") + def all_by(self, *args, **kwargs): + """{signature} + Test whether all selected elements evaluate to True. + + {parameters} + + Returns + ------- + LArray of bool or bool + + See Also + -------- + LArray.all, LArray.any, LArray.any_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> barr = arr < 6 + >>> barr + a\\b b0 b1 b2 b3 + a0 True True True True + a1 True True False False + a2 False False False False + a3 False False False False + >>> barr.all_by() + False + >>> # by axis 'a' + >>> barr.all_by(X.a) + a a0 a1 a2 a3 + True False False False + >>> # by axis 'b' + >>> barr.all_by(X.b) + b b0 b1 b2 b3 + False False False False + + Select some rows only + + >>> barr.all_by(['a0', 'a1']) + False + >>> # or equivalently + >>> # barr.all_by('a0,a1') + + Split an axis in several parts + + >>> barr.all_by((['a0', 'a1'], ['a2', 'a3'])) + a a0,a1 a2,a3 + False False + >>> # or equivalently + >>> # barr.all_by('a0,a1;a2,a3') + + Same with renaming + + >>> barr.all_by((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a a01 a23 + False False + >>> # or equivalently + >>> # barr.all_by('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.any, commutative=True, long_name="OR reduction") + def any(self, *args, **kwargs): + """{signature} + Test whether any selected elements evaluate to True. + + {parameters} + + Returns + ------- + LArray of bool or bool + + See Also + -------- + LArray.any_by, LArray.all, LArray.all_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> barr = arr < 6 + >>> barr + a\\b b0 b1 b2 b3 + a0 True True True True + a1 True True False False + a2 False False False False + a3 False False False False + >>> barr.any() + True + >>> # along axis 'a' + >>> barr.any(X.a) + b b0 b1 b2 b3 + True True True True + >>> # along axis 'b' + >>> barr.any(X.b) + a a0 a1 a2 a3 + True True False False + + Select some rows only + + >>> barr.any(['a0', 'a1']) + b b0 b1 b2 b3 + True True True True + >>> # or equivalently + >>> # barr.any('a0,a1') + + Split an axis in several parts + + >>> barr.any((['a0', 'a1'], ['a2', 'a3'])) + a\\b b0 b1 b2 b3 + a0,a1 True True True True + a2,a3 False False False False + >>> # or equivalently + >>> # barr.any('a0,a1;a2,a3') + + Same with renaming + + >>> barr.any((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a\\b b0 b1 b2 b3 + a01 True True True True + a23 False False False False + >>> # or equivalently + >>> # barr.any('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.any, commutative=True, by_agg=True, long_name="OR reduction") + def any_by(self, *args, **kwargs): + """{signature} + Test whether any selected elements evaluate to True. + + {parameters} + + Returns + ------- + LArray of bool or bool + + See Also + -------- + LArray.any, LArray.all, LArray.all_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> barr = arr < 6 + >>> barr + a\\b b0 b1 b2 b3 + a0 True True True True + a1 True True False False + a2 False False False False + a3 False False False False + >>> barr.any_by() + True + >>> # by axis 'a' + >>> barr.any_by(X.a) + a a0 a1 a2 a3 + True True False False + >>> # by axis 'b' + >>> barr.any_by(X.b) + b b0 b1 b2 b3 + True True True True + + Select some rows only + + >>> barr.any_by(['a0', 'a1']) + True + >>> # or equivalently + >>> # barr.any_by('a0,a1') + + Split an axis in several parts + + >>> barr.any_by((['a0', 'a1'], ['a2', 'a3'])) + a a0,a1 a2,a3 + True False + >>> # or equivalently + >>> # barr.any_by('a0,a1;a2,a3') + + Same with renaming + + >>> barr.any_by((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a a01 a23 + True False + >>> # or equivalently + >>> # barr.any_by('a0,a1>>a01;a2,a3>>a23') + """ + pass + + # commutative modulo float precision errors + + @_decorate_agg_method(np.sum, np.nansum, commutative=True, extra_kwargs=['dtype']) + def sum(self, *args, **kwargs): + """{signature} + Computes the sum of array elements along given axes/groups. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.sum_by, LArray.prod, LArray.prod_by, + LArray.cumsum, LArray.cumprod + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.sum() + 120 + >>> # along axis 'a' + >>> arr.sum(X.a) + b b0 b1 b2 b3 + 24 28 32 36 + >>> # along axis 'b' + >>> arr.sum(X.b) + a a0 a1 a2 a3 + 6 22 38 54 + + Select some rows only + + >>> arr.sum(['a0', 'a1']) + b b0 b1 b2 b3 + 4 6 8 10 + >>> # or equivalently + >>> # arr.sum('a0,a1') + + Split an axis in several parts + + >>> arr.sum((['a0', 'a1'], ['a2', 'a3'])) + a\\b b0 b1 b2 b3 + a0,a1 4 6 8 10 + a2,a3 20 22 24 26 + >>> # or equivalently + >>> # arr.sum('a0,a1;a2,a3') + + Same with renaming + + >>> arr.sum((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a\\b b0 b1 b2 b3 + a01 4 6 8 10 + a23 20 22 24 26 + >>> # or equivalently + >>> # arr.sum('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.sum, np.nansum, commutative=True, by_agg=True, extra_kwargs=['dtype'], long_name="sum") + def sum_by(self, *args, **kwargs): + """{signature} + Computes the sum of array elements for the given axes/groups. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.sum, LArray.prod, LArray.prod_by, + LArray.cumsum, LArray.cumprod + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.sum_by() + 120 + >>> # along axis 'a' + >>> arr.sum_by(X.a) + a a0 a1 a2 a3 + 6 22 38 54 + >>> # along axis 'b' + >>> arr.sum_by(X.b) + b b0 b1 b2 b3 + 24 28 32 36 + + Select some rows only + + >>> arr.sum_by(['a0', 'a1']) + 28 + >>> # or equivalently + >>> # arr.sum_by('a0,a1') + + Split an axis in several parts + + >>> arr.sum_by((['a0', 'a1'], ['a2', 'a3'])) + a a0,a1 a2,a3 + 28 92 + >>> # or equivalently + >>> # arr.sum_by('a0,a1;a2,a3') + + Same with renaming + + >>> arr.sum_by((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a a01 a23 + 28 92 + >>> # or equivalently + >>> # arr.sum_by('a0,a1>>a01;a2,a3>>a23') + """ + pass + + # nanprod needs numpy 1.10 + @_decorate_agg_method(np.prod, np_nanprod, commutative=True, extra_kwargs=['dtype'], long_name="product") + def prod(self, *args, **kwargs): + """{signature} + Computes the product of array elements along given axes/groups. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.prod_by, LArray.sum, LArray.sum_by, + LArray.cumsum, LArray.cumprod + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.prod() + 0 + >>> # along axis 'a' + >>> arr.prod(X.a) + b b0 b1 b2 b3 + 0 585 1680 3465 + >>> # along axis 'b' + >>> arr.prod(X.b) + a a0 a1 a2 a3 + 0 840 7920 32760 + + Select some rows only + + >>> arr.prod(['a0', 'a1']) + b b0 b1 b2 b3 + 0 5 12 21 + >>> # or equivalently + >>> # arr.prod('a0,a1') + + Split an axis in several parts + + >>> arr.prod((['a0', 'a1'], ['a2', 'a3'])) + a\\b b0 b1 b2 b3 + a0,a1 0 5 12 21 + a2,a3 96 117 140 165 + >>> # or equivalently + >>> # arr.prod('a0,a1;a2,a3') + + Same with renaming + + >>> arr.prod((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a\\b b0 b1 b2 b3 + a01 0 5 12 21 + a23 96 117 140 165 + >>> # or equivalently + >>> # arr.prod('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.prod, np_nanprod, commutative=True, by_agg=True, extra_kwargs=['dtype'], + long_name="product") + def prod_by(self, *args, **kwargs): + """{signature} + Computes the product of array elements for the given axes/groups. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.prod, LArray.sum, LArray.sum_by, + LArray.cumsum, LArray.cumprod + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.prod_by() + 0 + >>> # along axis 'a' + >>> arr.prod_by(X.a) + a a0 a1 a2 a3 + 0 840 7920 32760 + >>> # along axis 'b' + >>> arr.prod_by(X.b) + b b0 b1 b2 b3 + 0 585 1680 3465 + + Select some rows only + + >>> arr.prod_by(['a0', 'a1']) + 0 + >>> # or equivalently + >>> # arr.prod_by('a0,a1') + + Split an axis in several parts + + >>> arr.prod_by((['a0', 'a1'], ['a2', 'a3'])) + a a0,a1 a2,a3 + 0 259459200 + >>> # or equivalently + >>> # arr.prod_by('a0,a1;a2,a3') + + Same with renaming + + >>> arr.prod_by((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a a01 a23 + 0 259459200 + >>> # or equivalently + >>> # arr.prod_by('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.min, np.nanmin, commutative=True, long_name="minimum", action_verb="search") + def min(self, *args, **kwargs): + """{signature} + Get minimum of array elements along given axes/groups. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.min_by, LArray.max, LArray.max_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.min() + 0 + >>> # along axis 'a' + >>> arr.min(X.a) + b b0 b1 b2 b3 + 0 1 2 3 + >>> # along axis 'b' + >>> arr.min(X.b) + a a0 a1 a2 a3 + 0 4 8 12 + + Select some rows only + + >>> arr.min(['a0', 'a1']) + b b0 b1 b2 b3 + 0 1 2 3 + >>> # or equivalently + >>> # arr.min('a0,a1') + + Split an axis in several parts + + >>> arr.min((['a0', 'a1'], ['a2', 'a3'])) + a\\b b0 b1 b2 b3 + a0,a1 0 1 2 3 + a2,a3 8 9 10 11 + >>> # or equivalently + >>> # arr.min('a0,a1;a2,a3') + + Same with renaming + + >>> arr.min((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a\\b b0 b1 b2 b3 + a01 0 1 2 3 + a23 8 9 10 11 + >>> # or equivalently + >>> # arr.min('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.min, np.nanmin, commutative=True, by_agg=True, long_name="minimum", action_verb="search") + def min_by(self, *args, **kwargs): + """{signature} + Get minimum of array elements for the given axes/groups. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.min, LArray.max, LArray.max_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.min_by() + 0 + >>> # along axis 'a' + >>> arr.min_by(X.a) + a a0 a1 a2 a3 + 0 4 8 12 + >>> # along axis 'b' + >>> arr.min_by(X.b) + b b0 b1 b2 b3 + 0 1 2 3 + + Select some rows only + + >>> arr.min_by(['a0', 'a1']) + 0 + >>> # or equivalently + >>> # arr.min_by('a0,a1') + + Split an axis in several parts + + >>> arr.min_by((['a0', 'a1'], ['a2', 'a3'])) + a a0,a1 a2,a3 + 0 8 + >>> # or equivalently + >>> # arr.min_by('a0,a1;a2,a3') + + Same with renaming + + >>> arr.min_by((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a a01 a23 + 0 8 + >>> # or equivalently + >>> # arr.min_by('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.max, np.nanmax, commutative=True, long_name="maximum", action_verb="search") + def max(self, *args, **kwargs): + """{signature} + Get maximum of array elements along given axes/groups. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.max_by, LArray.min, LArray.min_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.max() + 15 + >>> # along axis 'a' + >>> arr.max(X.a) + b b0 b1 b2 b3 + 12 13 14 15 + >>> # along axis 'b' + >>> arr.max(X.b) + a a0 a1 a2 a3 + 3 7 11 15 + + Select some rows only + + >>> arr.max(['a0', 'a1']) + b b0 b1 b2 b3 + 4 5 6 7 + >>> # or equivalently + >>> # arr.max('a0,a1') + + Split an axis in several parts + + >>> arr.max((['a0', 'a1'], ['a2', 'a3'])) + a\\b b0 b1 b2 b3 + a0,a1 4 5 6 7 + a2,a3 12 13 14 15 + >>> # or equivalently + >>> # arr.max('a0,a1;a2,a3') + + Same with renaming + + >>> arr.max((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a\\b b0 b1 b2 b3 + a01 4 5 6 7 + a23 12 13 14 15 + >>> # or equivalently + >>> # arr.max('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.max, np.nanmax, commutative=True, by_agg=True, long_name="maximum", action_verb="search") + def max_by(self, *args, **kwargs): + """{signature} + Get maximum of array elements for the given axes/groups. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.max, LArray.min, LArray.min_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.max_by() + 15 + >>> # along axis 'a' + >>> arr.max_by(X.a) + a a0 a1 a2 a3 + 3 7 11 15 + >>> # along axis 'b' + >>> arr.max_by(X.b) + b b0 b1 b2 b3 + 12 13 14 15 + + Select some rows only + + >>> arr.max_by(['a0', 'a1']) + 7 + >>> # or equivalently + >>> # arr.max_by('a0,a1') + + Split an axis in several parts + + >>> arr.max_by((['a0', 'a1'], ['a2', 'a3'])) + a a0,a1 a2,a3 + 7 15 + >>> # or equivalently + >>> # arr.max_by('a0,a1;a2,a3') + + Same with renaming + + >>> arr.max_by((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a a01 a23 + 7 15 + >>> # or equivalently + >>> # arr.max_by('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.mean, np.nanmean, commutative=True, extra_kwargs=['dtype']) + def mean(self, *args, **kwargs): + """{signature} + Computes the arithmetic mean. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.mean_by, LArray.median, LArray.median_by, + LArray.var, LArray.var_by, LArray.std, LArray.std_by, + LArray.percentile, LArray.percentile_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.mean() + 7.5 + >>> # along axis 'a' + >>> arr.mean(X.a) + b b0 b1 b2 b3 + 6.0 7.0 8.0 9.0 + >>> # along axis 'b' + >>> arr.mean(X.b) + a a0 a1 a2 a3 + 1.5 5.5 9.5 13.5 + + Select some rows only + + >>> arr.mean(['a0', 'a1']) + b b0 b1 b2 b3 + 2.0 3.0 4.0 5.0 + >>> # or equivalently + >>> # arr.mean('a0,a1') + + Split an axis in several parts + + >>> arr.mean((['a0', 'a1'], ['a2', 'a3'])) + a\\b b0 b1 b2 b3 + a0,a1 2.0 3.0 4.0 5.0 + a2,a3 10.0 11.0 12.0 13.0 + >>> # or equivalently + >>> # arr.mean('a0,a1;a2,a3') + + Same with renaming + + >>> arr.mean((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a\\b b0 b1 b2 b3 + a01 2.0 3.0 4.0 5.0 + a23 10.0 11.0 12.0 13.0 + >>> # or equivalently + >>> # arr.mean('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.mean, np.nanmean, commutative=True, by_agg=True, extra_kwargs=['dtype'], long_name="mean") + def mean_by(self, *args, **kwargs): + """{signature} + Computes the arithmetic mean. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.mean, LArray.median, LArray.median_by, + LArray.var, LArray.var_by, LArray.std, LArray.std_by, + LArray.percentile, LArray.percentile_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.mean() + 7.5 + >>> # along axis 'a' + >>> arr.mean_by(X.a) + a a0 a1 a2 a3 + 1.5 5.5 9.5 13.5 + >>> # along axis 'b' + >>> arr.mean_by(X.b) + b b0 b1 b2 b3 + 6.0 7.0 8.0 9.0 + + Select some rows only + + >>> arr.mean_by(['a0', 'a1']) + 3.5 + >>> # or equivalently + >>> # arr.mean_by('a0,a1') + + Split an axis in several parts + + >>> arr.mean_by((['a0', 'a1'], ['a2', 'a3'])) + a a0,a1 a2,a3 + 3.5 11.5 + >>> # or equivalently + >>> # arr.mean_by('a0,a1;a2,a3') + + Same with renaming + + >>> arr.mean_by((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a a01 a23 + 3.5 11.5 + >>> # or equivalently + >>> # arr.mean_by('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.median, np.nanmedian, commutative=True) + def median(self, *args, **kwargs): + """{signature} + Computes the arithmetic median. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.median_by, LArray.mean, LArray.mean_by, + LArray.var, LArray.var_by, LArray.std, LArray.std_by, + LArray.percentile, LArray.percentile_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr[:,:] = [[10, 7, 5, 9], \ + [5, 8, 3, 7], \ + [6, 2, 0, 9], \ + [9, 10, 5, 6]] + >>> arr + a\\b b0 b1 b2 b3 + a0 10 7 5 9 + a1 5 8 3 7 + a2 6 2 0 9 + a3 9 10 5 6 + >>> arr.median() + 6.5 + >>> # along axis 'a' + >>> arr.median(X.a) + b b0 b1 b2 b3 + 7.5 7.5 4.0 8.0 + >>> # along axis 'b' + >>> arr.median(X.b) + a a0 a1 a2 a3 + 8.0 6.0 4.0 7.5 + + Select some rows only + + >>> arr.median(['a0', 'a1']) + b b0 b1 b2 b3 + 7.5 7.5 4.0 8.0 + >>> # or equivalently + >>> # arr.median('a0,a1') + + Split an axis in several parts + + >>> arr.median((['a0', 'a1'], ['a2', 'a3'])) + a\\b b0 b1 b2 b3 + a0,a1 7.5 7.5 4.0 8.0 + a2,a3 7.5 6.0 2.5 7.5 + >>> # or equivalently + >>> # arr.median('a0,a1;a2,a3') + + Same with renaming + + >>> arr.median((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a\\b b0 b1 b2 b3 + a01 7.5 7.5 4.0 8.0 + a23 7.5 6.0 2.5 7.5 + >>> # or equivalently + >>> # arr.median('a0,a1>>a01;a2,a3>>a23') + """ + pass + + @_decorate_agg_method(np.median, np.nanmedian, commutative=True, by_agg=True, long_name="mediane") + def median_by(self, *args, **kwargs): + """{signature} + Computes the arithmetic median. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.median, LArray.mean, LArray.mean_by, + LArray.var, LArray.var_by, LArray.std, LArray.std_by, + LArray.percentile, LArray.percentile_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr[:,:] = [[10, 7, 5, 9], \ + [5, 8, 3, 7], \ + [6, 2, 0, 9], \ + [9, 10, 5, 6]] + >>> arr + a\\b b0 b1 b2 b3 + a0 10 7 5 9 + a1 5 8 3 7 + a2 6 2 0 9 + a3 9 10 5 6 + >>> arr.median_by() + 6.5 + >>> # along axis 'a' + >>> arr.median_by(X.a) + a a0 a1 a2 a3 + 8.0 6.0 4.0 7.5 + >>> # along axis 'b' + >>> arr.median_by(X.b) + b b0 b1 b2 b3 + 7.5 7.5 4.0 8.0 + + Select some rows only + + >>> arr.median_by(['a0', 'a1']) + 7.0 + >>> # or equivalently + >>> # arr.median_by('a0,a1') + + Split an axis in several parts + + >>> arr.median_by((['a0', 'a1'], ['a2', 'a3'])) + a a0,a1 a2,a3 + 7.0 5.75 + >>> # or equivalently + >>> # arr.median_by('a0,a1;a2,a3') + + Same with renaming + + >>> arr.median_by((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a a01 a23 + 7.0 5.75 + >>> # or equivalently + >>> # arr.median_by('a0,a1>>a01;a2,a3>>a23') + """ + pass + + # XXX: for performance reasons, we should use the fact that the underlying numpy function handles multiple + # percentiles in one call. This is easy to implement in _axis_aggregate() but not in _group_aggregate() + # since in this case np.percentile() may be called several times. + # percentile needs an explicit method because it has not the same + # signature as other aggregate functions (extra argument) + def percentile(self, q, *args, **kwargs): + """{signature} + Computes the qth percentile of the data along the specified axis. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.percentile_by, LArray.mean, LArray.mean_by, + LArray.median, LArray.median_by, LArray.var, LArray.var_by, + LArray.std, LArray.std_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.percentile(25) + 3.75 + >>> # along axis 'a' + >>> arr.percentile(25, X.a) + b b0 b1 b2 b3 + 3.0 4.0 5.0 6.0 + >>> # along axis 'b' + >>> arr.percentile(25, X.b) + a a0 a1 a2 a3 + 0.75 4.75 8.75 12.75 + >>> # several percentile values + >>> arr.percentile([25, 50, 75], X.b) + percentile\\a a0 a1 a2 a3 + 25 0.75 4.75 8.75 12.75 + 50 1.5 5.5 9.5 13.5 + 75 2.25 6.25 10.25 14.25 + + Select some rows only + + >>> arr.percentile(25, ['a0', 'a1']) + b b0 b1 b2 b3 + 1.0 2.0 3.0 4.0 + >>> # or equivalently + >>> # arr.percentile(25, 'a0,a1') + + Split an axis in several parts + + >>> arr.percentile(25, (['a0', 'a1'], ['a2', 'a3'])) + a\\b b0 b1 b2 b3 + a0,a1 1.0 2.0 3.0 4.0 + a2,a3 9.0 10.0 11.0 12.0 + >>> # or equivalently + >>> # arr.percentile(25, 'a0,a1;a2,a3') + + Same with renaming + + >>> arr.percentile(25, (X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a\\b b0 b1 b2 b3 + a01 1.0 2.0 3.0 4.0 + a23 9.0 10.0 11.0 12.0 + >>> # or equivalently + >>> # arr.percentile(25, 'a0,a1>>a01;a2,a3>>a23') + """ + keepaxes = kwargs.pop('keepaxes', _kwarg_agg['keepaxes']['value']) + skipna = kwargs.pop('skipna', _kwarg_agg['skipna']['value']) + out = kwargs.pop('out', _kwarg_agg['out']['value']) + if skipna is None: + skipna = True + _npfunc = np.nanpercentile if skipna else np.percentile + interpolation = kwargs.pop('interpolation', _kwarg_agg['interpolation']['value']) + if isinstance(q, (list, tuple)): + res = stack([(v, self._aggregate(_npfunc, args, kwargs, keepaxes=keepaxes, commutative=True, + extra_kwargs={'q': v, 'interpolation': interpolation})) for v in q], 'percentile') + return res.transpose() + else : + _extra_kwargs = {'q': q, 'interpolation': interpolation} + return self._aggregate(_npfunc, args, kwargs, by_agg=False, keepaxes=keepaxes, commutative=True, + out=out, extra_kwargs=_extra_kwargs) + + _doc_agg_method(percentile, False, "qth percentile", extra_args=['q'], + kwargs=['out', 'interpolation', 'skipna', 'keepaxes']) + + def percentile_by(self, q, *args, **kwargs): + """{signature} + Computes the qth percentile of the data for the specified axis. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.percentile, LArray.mean, LArray.mean_by, + LArray.median, LArray.median_by, LArray.var, LArray.var_by, + LArray.std, LArray.std_by + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.percentile_by(25) + 3.75 + >>> # along axis 'a' + >>> arr.percentile_by(25, X.a) + a a0 a1 a2 a3 + 0.75 4.75 8.75 12.75 + >>> # along axis 'b' + >>> arr.percentile_by(25, X.b) + b b0 b1 b2 b3 + 3.0 4.0 5.0 6.0 + >>> # several percentile values + >>> arr.percentile_by([25, 50, 75], X.b) + percentile\\b b0 b1 b2 b3 + 25 3.0 4.0 5.0 6.0 + 50 6.0 7.0 8.0 9.0 + 75 9.0 10.0 11.0 12.0 + + Select some rows only + + >>> arr.percentile_by(25, ['a0', 'a1']) + 1.75 + >>> # or equivalently + >>> # arr.percentile_by('a0,a1') + + Split an axis in several parts + + >>> arr.percentile_by(25, (['a0', 'a1'], ['a2', 'a3'])) + a a0,a1 a2,a3 + 1.75 9.75 + >>> # or equivalently + >>> # arr.percentile_by('a0,a1;a2,a3') + + Same with renaming + + >>> arr.percentile_by(25, (X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a a01 a23 + 1.75 9.75 + >>> # or equivalently + >>> # arr.percentile_by('a0,a1>>a01;a2,a3>>a23') + """ + keepaxes = kwargs.pop('keepaxes', _kwarg_agg['keepaxes']['value']) + skipna = kwargs.pop('skipna', _kwarg_agg['skipna']['value']) + out = kwargs.pop('out', _kwarg_agg['out']['value']) + if skipna is None: + skipna = True + _npfunc = np.nanpercentile if skipna else np.percentile + interpolation = kwargs.pop('interpolation', _kwarg_agg['interpolation']['value']) + if isinstance(q, (list, tuple)): + res = stack([(v, self._aggregate(_npfunc, args, kwargs, by_agg=True, keepaxes=keepaxes, commutative=True, + extra_kwargs={'q': v, 'interpolation': interpolation})) for v in q], 'percentile') + return res.transpose() + else: + return self._aggregate(_npfunc, args, kwargs, by_agg=True, keepaxes=keepaxes, commutative=True, out=out, + extra_kwargs={'q': q, 'interpolation': interpolation}) + + _doc_agg_method(percentile_by, True, "qth percentile", extra_args=['q'], + kwargs=['out', 'interpolation', 'skipna', 'keepaxes']) + + # not commutative + + def ptp(self, *args, **kwargs): + """{signature} + Returns the range of values (maximum - minimum). + + The name of the function comes from the acronym for ‘peak to peak’. + + {parameters} + + Returns + ------- + LArray or scalar + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.ptp() + 15 + >>> # along axis 'a' + >>> arr.ptp(X.a) + b b0 b1 b2 b3 + 12 12 12 12 + >>> # along axis 'b' + >>> arr.ptp(X.b) + a a0 a1 a2 a3 + 3 3 3 3 + + Select some rows only + + >>> arr.ptp(['a0', 'a1']) + b b0 b1 b2 b3 + 4 4 4 4 + >>> # or equivalently + >>> # arr.ptp('a0,a1') + + Split an axis in several parts + + >>> arr.ptp((['a0', 'a1'], ['a2', 'a3'])) + a\\b b0 b1 b2 b3 + a0,a1 4 4 4 4 + a2,a3 4 4 4 4 + >>> # or equivalently + >>> # arr.ptp('a0,a1;a2,a3') + + Same with renaming + + >>> arr.ptp((X.a['a0', 'a1'] >> 'a01', X.a['a2', 'a3'] >> 'a23')) + a\\b b0 b1 b2 b3 + a01 4 4 4 4 + a23 4 4 4 4 + >>> # or equivalently + >>> # arr.ptp('a0,a1>>a01;a2,a3>>a23') + """ + out = kwargs.pop('out', _kwarg_agg['out']['value']) + return self._aggregate(np.ptp, args, kwargs, out=out) + + _doc_agg_method(ptp, False, kwargs=['out']) + + @_decorate_agg_method(np.var, np.nanvar, extra_kwargs=['dtype', 'ddof'], long_name="variance") + def var(self, *args, **kwargs): + """{signature} + Computes the unbiased variance. + + Normalized by N-1 by default. This can be changed using the ddof argument. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.var_by, LArray.std, LArray.std_by, + LArray.mean, LArray.mean_by, LArray.median, LArray.median_by, + LArray.percentile, LArray.percentile_by + + Examples + -------- + >>> arr = ndtest((2, 8), dtype=float) + >>> arr[:,:] = [[0, 3, 5, 6, 4, 2, 1, 3], \ + [7, 3, 2, 5, 8, 5, 6, 4]] + >>> arr + a\\b b0 b1 b2 b3 b4 b5 b6 b7 + a0 0.0 3.0 5.0 6.0 4.0 2.0 1.0 3.0 + a1 7.0 3.0 2.0 5.0 8.0 5.0 6.0 4.0 + >>> arr.var() + 4.7999999999999998 + >>> # along axis 'b' + >>> arr.var(X.b) + a a0 a1 + 4.0 4.0 + + Select some columns only + + >>> arr.var(['b0', 'b1', 'b3']) + a a0 a1 + 9.0 4.0 + >>> # or equivalently + >>> # arr.var('b0,b1,b3') + + Split an axis in several parts + + >>> arr.var((['b0', 'b1', 'b3'], 'b5:')) + a\\b b0,b1,b3 b5: + a0 9.0 1.0 + a1 4.0 1.0 + >>> # or equivalently + >>> # arr.var('b0,b1,b3;b5:') + + Same with renaming + + >>> arr.var((X.b['b0', 'b1', 'b3'] >> 'b013', X.b['b5:'] >> 'b567')) + a\\b b013 b567 + a0 9.0 1.0 + a1 4.0 1.0 + >>> # or equivalently + >>> # arr.var('b0,b1,b3>>b013;b5:>>b567') + """ + pass + + @_decorate_agg_method(np.var, np.nanvar, by_agg=True, extra_kwargs=['dtype', 'ddof'], long_name="variance") + def var_by(self, *args, **kwargs): + """{signature} + Computes the unbiased variance. + + Normalized by N-1 by default. This can be changed using the ddof argument. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.var, LArray.std, LArray.std_by, + LArray.mean, LArray.mean_by, LArray.median, LArray.median_by, + LArray.percentile, LArray.percentile_by + + Examples + -------- + >>> arr = ndtest((2, 8), dtype=float) + >>> arr[:,:] = [[0, 3, 5, 6, 4, 2, 1, 3], \ + [7, 3, 2, 5, 8, 5, 6, 4]] + >>> arr + a\\b b0 b1 b2 b3 b4 b5 b6 b7 + a0 0.0 3.0 5.0 6.0 4.0 2.0 1.0 3.0 + a1 7.0 3.0 2.0 5.0 8.0 5.0 6.0 4.0 + >>> arr.var_by() + 4.7999999999999998 + >>> # along axis 'a' + >>> arr.var_by(X.a) + a a0 a1 + 4.0 4.0 + + Select some columns only + + >>> arr.var_by(X.a, ['b0','b1','b3']) + a a0 a1 + 9.0 4.0 + >>> # or equivalently + >>> # arr.var_by('a','b0,b1,b3') + + Split an axis in several parts + + >>> arr.var_by(X.a, (['b0', 'b1', 'b3'], 'b5:')) + a\\b b0,b1,b3 b5: + a0 9.0 1.0 + a1 4.0 1.0 + >>> # or equivalently + >>> # arr.var_by('a','b0,b1,b3;b5:') + + Same with renaming + + >>> arr.var_by(X.a, (X.b['b0', 'b1', 'b3'] >> 'b013', X.b['b5:'] >> 'b567')) + a\\b b013 b567 + a0 9.0 1.0 + a1 4.0 1.0 + >>> # or equivalently + >>> # arr.var_by('a','b0,b1,b3>>b013;b5:>>b567') + """ + pass + + @_decorate_agg_method(np.std, np.nanstd, extra_kwargs=['dtype', 'ddof'], long_name="standard deviation") + def std(self, *args, **kwargs): + """{signature} + Computes the sample standard deviation. + + Normalized by N-1 by default. This can be changed using the ddof argument. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.std_by, LArray.var, LArray.var_by, + LArray.mean, LArray.mean_by, LArray.median, LArray.median_by, + LArray.percentile, LArray.percentile_by + + Examples + -------- + >>> arr = ndtest((2, 8), dtype=float) + >>> arr[:,:] = [[0, 3, 5, 6, 4, 2, 1, 3], + ... [7, 3, 2, 5, 8, 5, 6, 4]] + >>> arr + a\\b b0 b1 b2 b3 b4 b5 b6 b7 + a0 0.0 3.0 5.0 6.0 4.0 2.0 1.0 3.0 + a1 7.0 3.0 2.0 5.0 8.0 5.0 6.0 4.0 + >>> arr.std() + 2.1908902300206643 + >>> # along axis 'b' + >>> arr.std(X.b) + a a0 a1 + 2.0 2.0 + + Select some columns only + + >>> arr.std(['b0', 'b1', 'b3']) + a a0 a1 + 3.0 2.0 + >>> # or equivalently + >>> # arr.std('b0,b1,b3') + + Split an axis in several parts + + >>> arr.std((['b0', 'b1', 'b3'], 'b5:')) + a\\b b0,b1,b3 b5: + a0 3.0 1.0 + a1 2.0 1.0 + >>> # or equivalently + >>> # arr.std('b0,b1,b3;b5:') + + Same with renaming + + >>> arr.std((X.b['b0', 'b1', 'b3'] >> 'b013', X.b['b5:'] >> 'b567')) + a\\b b013 b567 + a0 3.0 1.0 + a1 2.0 1.0 + >>> # or equivalently + >>> # arr.std('b0,b1,b3>>b013;b5:>>b567') + """ + pass + + @_decorate_agg_method(np.std, np.nanstd, by_agg=True, extra_kwargs=['dtype', 'ddof'], + long_name="standard deviation") + def std_by(self, *args, **kwargs): + """{signature} + Computes the sample standard deviation. + + Normalized by N-1 by default. This can be changed using the ddof argument. + + {parameters} + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.std_by, LArray.var, LArray.var_by, + LArray.mean, LArray.mean_by, LArray.median, LArray.median_by, + LArray.percentile, LArray.percentile_by + + Examples + -------- + >>> arr = ndtest((2, 8), dtype=float) + >>> arr[:,:] = [[0, 3, 5, 6, 4, 2, 1, 3], + ... [7, 3, 2, 5, 8, 5, 6, 4]] + >>> arr + a\\b b0 b1 b2 b3 b4 b5 b6 b7 + a0 0.0 3.0 5.0 6.0 4.0 2.0 1.0 3.0 + a1 7.0 3.0 2.0 5.0 8.0 5.0 6.0 4.0 + >>> arr.std_by() + 2.1908902300206643 + >>> # along axis 'a' + >>> arr.std_by(X.a) + a a0 a1 + 2.0 2.0 + + Select some columns only + + >>> arr.std_by(X.a, ['b0','b1','b3']) + a a0 a1 + 3.0 2.0 + >>> # or equivalently + >>> # arr.std_by('a','b0,b1,b3') + + Split an axis in several parts + + >>> arr.std_by(X.a, (['b0', 'b1', 'b3'], 'b5:')) + a\\b b0,b1,b3 b5: + a0 3.0 1.0 + a1 2.0 1.0 + >>> # or equivalently + >>> # arr.std_by('a','b0,b1,b3;b5:') + + Same with renaming + + >>> arr.std_by(X.a, (X.b['b0', 'b1', 'b3'] >> 'b013', X.b['b5:'] >> 'b567')) + a\\b b013 b567 + a0 3.0 1.0 + a1 2.0 1.0 + >>> # or equivalently + >>> # arr.std_by('a','b0,b1,b3>>b013;b5:>>b567') + """ + pass + + # cumulative aggregates + def cumsum(self, axis=-1): + """ + Returns the cumulative sum of array elements along an axis. + + Parameters + ---------- + axis : int or str or Axis, optional + Axis along which to perform the cumulative sum. + If given as position, it can be a negative integer, in which case it counts from the last to the first axis. + By default, the cumulative sum is performed along the last axis. + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.cumprod, LArray.sum, LArray.sum_by, + LArray.prod, LArray.prod_by + + Notes + ----- + Cumulative aggregation functions accept only one axis + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.cumsum() + a\\b b0 b1 b2 b3 + a0 0 1 3 6 + a1 4 9 15 22 + a2 8 17 27 38 + a3 12 25 39 54 + >>> arr.cumsum(X.a) + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 6 8 10 + a2 12 15 18 21 + a3 24 28 32 36 + """ + return self._cum_aggregate(np.cumsum, axis) + + def cumprod(self, axis=-1): + """ + Returns the cumulative product of array elements. + + Parameters + ---------- + axis : int or str or Axis, optional + Axis along which to perform the cumulative product. + If given as position, it can be a negative integer, in which case it counts from the last to the first axis. + By default, the cumulative product is performed along the last axis. + + Returns + ------- + LArray or scalar + + See Also + -------- + LArray.cumsum, LArray.sum, LArray.sum_by, + LArray.prod, LArray.prod_by + + Notes + ----- + Cumulative aggregation functions accept only one axis. + + Examples + -------- + >>> arr = ndtest((4, 4)) + >>> arr + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 4 5 6 7 + a2 8 9 10 11 + a3 12 13 14 15 + >>> arr.cumprod() + a\\b b0 b1 b2 b3 + a0 0 0 0 0 + a1 4 20 120 840 + a2 8 72 720 7920 + a3 12 156 2184 32760 + >>> arr.cumprod(X.a) + a\\b b0 b1 b2 b3 + a0 0 1 2 3 + a1 0 5 12 21 + a2 0 45 120 231 + a3 0 585 1680 3465 + """ + return self._cum_aggregate(np.cumprod, axis) + + # element-wise method factory + def _binop(opname): + fullname = '__%s__' % opname + super_method = getattr(np.ndarray, fullname) + + def opmethod(self, other): + res_axes = self.axes + + if isinstance(other, ExprNode): + other = other.evaluate(self.axes) + + # we could pass scalars through aslarray too but it is too costly performance-wise for only suppressing one + # isscalar test and an if statement. + # TODO: ndarray should probably be converted to larrays because that would harmonize broadcasting rules, but + # it makes some tests fail for some reason. + if not isinstance(other, (LArray, np.ndarray)) and not np.isscalar(other): + other = aslarray(other) + + if isinstance(other, LArray): + # TODO: first test if it is not already broadcastable + (self, other), res_axes = make_numpy_broadcastable([self, other]) + other = other.data + return LArray(super_method(self.data, other), res_axes) + opmethod.__name__ = fullname + return opmethod + + __lt__ = _binop('lt') + __le__ = _binop('le') + __eq__ = _binop('eq') + __ne__ = _binop('ne') + __gt__ = _binop('gt') + __ge__ = _binop('ge') + __add__ = _binop('add') + __radd__ = _binop('radd') + __sub__ = _binop('sub') + __rsub__ = _binop('rsub') + __mul__ = _binop('mul') + __rmul__ = _binop('rmul') + if sys.version < '3': + __div__ = _binop('div') + __rdiv__ = _binop('rdiv') + __truediv__ = _binop('truediv') + __rtruediv__ = _binop('rtruediv') + __floordiv__ = _binop('floordiv') + __rfloordiv__ = _binop('rfloordiv') + __mod__ = _binop('mod') + __rmod__ = _binop('rmod') + __divmod__ = _binop('divmod') + __rdivmod__ = _binop('rdivmod') + __pow__ = _binop('pow') + __rpow__ = _binop('rpow') + __lshift__ = _binop('lshift') + __rlshift__ = _binop('rlshift') + __rshift__ = _binop('rshift') + __rrshift__ = _binop('rrshift') + __and__ = _binop('and') + __rand__ = _binop('rand') + __xor__ = _binop('xor') + __rxor__ = _binop('rxor') + __or__ = _binop('or') + __ror__ = _binop('ror') + + def __matmul__(self, other): + """ + Overrides operator @ for matrix multiplication. + + Notes + ----- + Only available with Python >= 3.5 + + Examples + -------- + >>> arr1d = ndtest(3) + >>> arr1d + a a0 a1 a2 + 0 1 2 + >>> arr2d = ndtest((3, 3)) + >>> arr2d + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + a2 6 7 8 + >>> arr1d @ arr1d # doctest: +SKIP + 5 + >>> arr1d @ arr2d # doctest: +SKIP + b b0 b1 b2 + 15 18 21 + >>> arr2d @ arr1d # doctest: +SKIP + a a0 a1 a2 + 5 14 23 + >>> arr3d = ndtest('c=c0..c2;d=d0..d2;e=e0..e2') + >>> arr1d @ arr3d # doctest: +SKIP + c\\e e0 e1 e2 + c0 15 18 21 + c1 42 45 48 + c2 69 72 75 + >>> arr3d @ arr1d # doctest: +SKIP + c\\d d0 d1 d2 + c0 5 14 23 + c1 32 41 50 + c2 59 68 77 + >>> arr3d @ arr3d # doctest: +SKIP + c d\\e e0 e1 e2 + c0 d0 15 18 21 + c0 d1 42 54 66 + c0 d2 69 90 111 + c1 d0 366 396 426 + c1 d1 474 513 552 + c1 d2 582 630 678 + c2 d0 1203 1260 1317 + c2 d1 1392 1458 1524 + c2 d2 1581 1656 1731 + """ + current = self[:] + axes = self.axes + if not isinstance(other, (LArray, np.ndarray)): + raise NotImplementedError("matrix multiplication not implemented for %s" % type(other)) + if isinstance(other, np.ndarray): + other = LArray(other) + other_axes = other.axes + + combined_axes = axes[:-2] + other_axes[:-2] + if self.ndim > 2 and other.ndim > 2: + current = current.expand(combined_axes).transpose(combined_axes) + other = other.expand(combined_axes).transpose(combined_axes) + + # XXX : What doc of Numpy matmul says: + # The behavior depends on the arguments in the following way: + # * If both arguments are 2-D they are multiplied like conventional matrices. + # * If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes + # and broadcast accordingly. + # * If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix + # multiplication the prepended 1 is removed. + # * If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix + # multiplication the appended 1 is removed. + res_data = current.data.__matmul__(other.data) + + res_axes = list(combined_axes) + if self.ndim > 1: + res_axes += [axes[-2]] + if other.ndim > 1: + res_axes += [other_axes[-1].copy()] + return LArray(res_data, res_axes) + + def __rmatmul__(self, other): + if isinstance(other, np.ndarray): + other = LArray(other) + if not isinstance(other, LArray): + raise NotImplementedError("matrix multiplication not implemented for %s" % type(other)) + return other.__matmul__(self) + + # element-wise method factory + def _unaryop(opname): + fullname = '__%s__' % opname + super_method = getattr(np.ndarray, fullname) + + def opmethod(self): + return LArray(super_method(self.data), self.axes) + opmethod.__name__ = fullname + return opmethod + + # unary ops do not need broadcasting so do not need to be overridden + __neg__ = _unaryop('neg') + __pos__ = _unaryop('pos') + __abs__ = _unaryop('abs') + __invert__ = _unaryop('invert') + + def __round__(self, n=0): + # XXX: use the ufuncs.round instead? + return np.round(self, decimals=n) + + def __index__(self): + return self.data.__index__() + + def __int__(self): + return self.data.__int__() + + def __float__(self): + return self.data.__float__() + + def equals(self, other, rtol=0, atol=0, nan_equals=False): + """ + Compares self with another array and returns True if they have the same axes and elements, False otherwise. + + Parameters + ---------- + other: LArray-like + Input array. aslarray() is used on a non-LArray input. + rtol : float or int, optional + The relative tolerance parameter (see Notes). Defaults to 0. + atol : float or int, optional + The absolute tolerance parameter (see Notes). Defaults to 0. + nan_equals: boolean, optional + Whether or not to consider nan values at the same positions in the two arrays as equal. + By default, an array containing nan values is never equal to another array, even if that other array + also contains nan values at the same positions. The reason is that a nan value is different from + *anything*, including itself. Defaults to False. + + Returns + ------- + bool + Returns True if self is equal to other. + + Notes + ----- + For finite values, equals uses the following equation to test whether two values are equal: + + absolute(array1 - array2) <= (atol + rtol * absolute(array2)) + + The above equation is not symmetric in array1 and array2, so that equals(array1, array2) might be different + from equals(array2, array1) in some rare cases. + + Examples + -------- + >>> arr1 = ndtest((2, 3)) + >>> arr1 + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> arr2 = arr1.copy() + >>> arr1.equals(arr2) + True + >>> arr2['b1'] += 1 + >>> arr1.equals(arr2) + False + >>> arr3 = arr1.set_labels('a', ['x0', 'x1']) + >>> arr1.equals(arr3) + False + + Test equality between two arrays within a given tolerance range. + Return True if absolute(array1 - array2) <= (atol + rtol * absolute(array2)). + + >>> arr1 = LArray([6., 8.], "a=a0,a1") + >>> arr1 + a a0 a1 + 6.0 8.0 + >>> arr2 = LArray([5.999, 8.001], "a=a0,a1") + >>> arr2 + a a0 a1 + 5.999 8.001 + >>> arr1.equals(arr2) + False + >>> arr1.equals(arr2, atol=0.01) + True + >>> arr1.equals(arr2, rtol=0.01) + True + + Arrays with nan values + + >>> arr1 = ndtest((2, 3), dtype=float) + >>> arr1['a1', 'b1'] = nan + >>> arr1 + a\\b b0 b1 b2 + a0 0.0 1.0 2.0 + a1 3.0 nan 5.0 + >>> arr2 = arr1.copy() + >>> # By default, an array containing nan values is never equal to another array, + >>> # even if that other array also contains nan values at the same positions. + >>> # The reason is that a nan value is different from *anything*, including itself. + >>> arr1.equals(arr2) + False + >>> # set flag nan_equals to True to overwrite this behavior + >>> arr1.equals(arr2, nan_equals=True) + True + """ + try: + other = aslarray(other) + except Exception: + return False + return self.axes == other.axes and all(element_equal(self, other, rtol=rtol, atol=atol, nan_equals=nan_equals)) + + def divnot0(self, other): + """Divides array by other, but returns 0.0 where other is 0. + + Parameters + ---------- + other : scalar or LArray + What to divide by. + + Returns + ------- + LArray + Array divided by other, 0.0 where other is 0 + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> a = ndtest((nat, sex)) + >>> a + nat\\sex M F + BE 0 1 + FO 2 3 + >>> b = ndtest(sex) + >>> b + sex M F + 0 1 + >>> a / b + nat\\sex M F + BE nan 1.0 + FO inf 3.0 + >>> a.divnot0(b) + nat\\sex M F + BE 0.0 1.0 + FO 0.0 3.0 + """ + if np.isscalar(other): + if other == 0: + return zeros_like(self, dtype=float) + else: + return self / other + else: + with np.errstate(divide='ignore', invalid='ignore'): + res = self / other + res[other == 0] = 0 + return res + + # XXX: rename/change to "add_axes" ? + # TODO: add a flag copy=True to force a new array. + def expand(self, target_axes=None, out=None, readonly=False): + """Expands array to target_axes. + + Target axes will be added to array if not present. + In most cases this function is not needed because LArray can do operations with arrays having different + (compatible) axes. + + Parameters + ---------- + target_axes : list of Axis or AxisCollection, optional + Self can contain axes not present in `target_axes`. + The result axes will be: [self.axes not in target_axes] + target_axes + out : LArray, optional + Output array, must have the correct shape + readonly : bool, optional + Whether returning a readonly view is acceptable or not (this is much faster) + + Returns + ------- + LArray + Original array if possible (and out is None). + + Examples + -------- + >>> a = Axis('a=a1,a2') + >>> b = Axis('b=b1,b2') + >>> arr = ndtest([a, b]) + >>> arr + a\\b b1 b2 + a1 0 1 + a2 2 3 + >>> c = Axis('c=c1,c2') + >>> arr.expand([a, c, b]) + a c\\b b1 b2 + a1 c1 0 1 + a1 c2 0 1 + a2 c1 2 3 + a2 c2 2 3 + >>> arr.expand([b, c]) + a b\\c c1 c2 + a1 b1 0 0 + a1 b2 1 1 + a2 b1 2 2 + a2 b2 3 3 + """ + if target_axes is None and out is None or target_axes is not None and out is not None: + raise ValueError("either target_axes or out must be defined (not both)") + if out is not None: + target_axes = out.axes + else: + if not isinstance(target_axes, AxisCollection): + target_axes = AxisCollection(target_axes) + target_axes = (self.axes - target_axes) | target_axes + + if out is None: + # this is not strictly necessary but avoids doing this test twice if it is True + if self.axes == target_axes: + return self + + broadcasted = self.broadcast_with(target_axes) + # this can only happen if only the order of axes differed and/or all extra axes have length 1 + if broadcasted.axes == target_axes: + return broadcasted + + if readonly: + # requires numpy 1.10 + return LArray(np.broadcast_to(broadcasted, target_axes.shape), target_axes) + else: + out = empty(target_axes, dtype=self.dtype) + out[:] = broadcasted + return out + + def append(self, axis, value, label=None): + """Adds an array to self along an axis. + + The two arrays must have compatible axes. + + Parameters + ---------- + axis : axis reference + Axis along which to append input array (`value`). + value : scalar or LArray + Array with compatible axes. + label : str, optional + Label for the new item in axis + + Returns + ------- + LArray + Array expanded with `value` along `axis`. + + Examples + -------- + >>> a = ones('nat=BE,FO;sex=M,F') + >>> a + nat\\sex M F + BE 1.0 1.0 + FO 1.0 1.0 + >>> a.append(X.sex, a.sum(X.sex), 'M+F') + nat\\sex M F M+F + BE 1.0 1.0 2.0 + FO 1.0 1.0 2.0 + >>> a.append(X.nat, 2, 'Other') + nat\\sex M F + BE 1.0 1.0 + FO 1.0 1.0 + Other 2.0 2.0 + >>> b = zeros('type=type1,type2') + >>> b + type type1 type2 + 0.0 0.0 + >>> a.append(X.nat, b, 'Other') + nat sex\\type type1 type2 + BE M 1.0 1.0 + BE F 1.0 1.0 + FO M 1.0 1.0 + FO F 1.0 1.0 + Other M 0.0 0.0 + Other F 0.0 0.0 + """ + axis = self.axes[axis] + return self.insert(value, pos=len(axis), axis=axis, label=label) + + def prepend(self, axis, value, label=None): + """Adds an array before self along an axis. + + The two arrays must have compatible axes. + + Parameters + ---------- + axis : axis reference + Axis along which to prepend input array (`value`) + value : LArray + Array with compatible axes. + label : str, optional + Label for the new item in axis + + Returns + ------- + LArray + Array expanded with 'value' at the start of 'axis'. + + Examples + -------- + >>> a = ones('nat=BE,FO;sex=M,F') + >>> a + nat\sex M F + BE 1.0 1.0 + FO 1.0 1.0 + >>> a.prepend(X.sex, a.sum(X.sex), 'M+F') + nat\\sex M+F M F + BE 2.0 1.0 1.0 + FO 2.0 1.0 1.0 + >>> a.prepend(X.nat, 2, 'Other') + nat\\sex M F + Other 2.0 2.0 + BE 1.0 1.0 + FO 1.0 1.0 + >>> b = zeros('type=type1,type2') + >>> b + type type1 type2 + 0.0 0.0 + >>> a.prepend(X.sex, b, 'Other') + nat sex\\type type1 type2 + BE Other 0.0 0.0 + BE M 1.0 1.0 + BE F 1.0 1.0 + FO Other 0.0 0.0 + FO M 1.0 1.0 + FO F 1.0 1.0 + """ + return self.insert(value, pos=0, axis=axis, label=label) + + def extend(self, axis, other): + """Adds an array to self along an axis. + + The two arrays must have compatible axes. + + Parameters + ---------- + axis : axis + Axis along which to extend with input array (`other`) + other : LArray + Array with compatible axes + + Returns + ------- + LArray + Array expanded with 'other' along 'axis'. + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> sex2 = Axis('sex=U') + >>> xtype = Axis('type=type1,type2') + >>> arr1 = ones([sex, xtype]) + >>> arr1 + sex\\type type1 type2 + M 1.0 1.0 + F 1.0 1.0 + >>> arr2 = zeros([sex2, xtype]) + >>> arr2 + sex\\type type1 type2 + U 0.0 0.0 + >>> arr1.extend(X.sex, arr2) + sex\\type type1 type2 + M 1.0 1.0 + F 1.0 1.0 + U 0.0 0.0 + >>> arr3 = zeros([sex2, nat]) + >>> arr3 + sex\\nat BE FO + U 0.0 0.0 + >>> arr1.extend(X.sex, arr3) + sex type\\nat BE FO + M type1 1.0 1.0 + M type2 1.0 1.0 + F type1 1.0 1.0 + F type2 1.0 1.0 + U type1 0.0 0.0 + U type2 0.0 0.0 + """ + return concat((self, other), axis) + + def insert(self, value, before=None, after=None, pos=None, axis=None, label=None): + """Inserts value in array along an axis. + + Parameters + ---------- + value : scalar or LArray + Value to insert. If an LArray, it must have compatible axes. If value already has the axis along which it + is inserted, `label` should not be used. + before : scalar or Group + Label or group before which to insert `value`. + after : scalar or Group + Label or group after which to insert `value`. + pos : int + Index before which to insert `value`. + axis : axis reference (int, str or Axis), optional + Axis in which to insert `value`. This is only required when using `pos` or when before or after are + ambiguous labels. + label : str, optional + Label for the new item in axis. + + Returns + ------- + LArray + Array with `value` inserted along `axis`. The dtype of the returned array will be the "closest" type + which can hold both the array values and the inserted values without loss of information. For example, + when mixing numeric and string types, the dtype will be object. + + Examples + -------- + >>> arr1 = ndtest((2, 3)) + >>> arr1 + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> arr1.insert(42, before='b1', label='b0.5') + a\\b b0 b0.5 b1 b2 + a0 0 42 1 2 + a1 3 42 4 5 + >>> arr2 = ndtest(2) + >>> arr2 + a a0 a1 + 0 1 + >>> arr1.insert(arr2, after='b0', label='b0.5') + a\\b b0 b0.5 b1 b2 + a0 0 0 1 2 + a1 3 1 4 5 + >>> arr1.insert(42, axis='b', pos=1, label='b0.5') + a\\b b0 b0.5 b1 b2 + a0 0 42 1 2 + a1 3 42 4 5 + >>> arr1.insert(42, before=X.b.i[1], label='b0.5') + a\\b b0 b0.5 b1 b2 + a0 0 42 1 2 + a1 3 42 4 5 + + insert an array which already has the axis + + >>> arr3 = ndtest('a=a0,a1;b=b0.1,b0.2') + 42 + >>> arr3 + a\\b b0.1 b0.2 + a0 42 43 + a1 44 45 + >>> arr1.insert(arr3, before='b1') + a\\b b0 b0.1 b0.2 b1 b2 + a0 0 42 43 1 2 + a1 3 44 45 4 5 + """ + + # XXX: unsure we should have arr1.insert(arr3, before='b1,b2') result in (see unit tests): + + # a\\b b0 b0.1 b1 b0.2 b2 + # a0 0 42 1 43 2 + # a1 3 44 4 45 5 + + # we might to implement the following instead: + + # a\\b b0 b0.1 b0.2 b1 b0.1 b0.2 b2 + # a0 0 42 43 1 42 43 2 + # a1 3 44 45 4 44 45 5 + + # The later looks less useful and could be emulated easily via: + # arr1.insert([arr3, arr3], before='b1,b2') + # while the above is a bit harder to achieve manually: + # arr1.insert([arr3[[b]] for b in arr3.b], before=['b1', 'b2']) + # but the later is *probably* more intuitive (and wouldn't suffer from the inefficiency we currently have). + + # XXX: when we have several lists, we implicitly match them by position, which we should avoid for the usual + # reason, but I am unsure what the best syntax for that would be. + + # the goal is to get this result + + # a\b b0 b0.5 b1 b1.5 b2 + # a0 0 8 1 9 2 + # a1 3 8 4 9 5 + + # When the inserted arrays already contain a label, this seems reasonably readable: + + # >>> arr1 = ndtest((2, 3)) + # >>> arr1 + # a\\b b0 b1 b2 + # a0 0 1 2 + # a1 3 4 5 + # >>> arr2 = full('b=b0.5', 8) + # >>> arr2 + # b b0.5 + # 8 + # >>> arr3 = full('b=b1.5', 9) + # >>> arr3 + # b b1.5 + # 9 + # >>> arr1.insert(before={'b1': arr2, 'b2': arr3}) + # a\\b b0 b0.5 b1 b1.5 b2 + # a0 0 8 1 9 2 + # a1 3 8 4 9 5 + + # When the inserted arrays/values have no label, this does not really convince me and it prevents using after + # or pos. + + # >>> arr1.insert(value={'b0.5': ('b1', 8), 'b1.5': ('b2', 9)}) + # a\b b0 b0.5 b1 b1.5 b2 + # a0 0 8 1 9 2 + # a1 3 8 4 9 5 + + # This works with both after and pos and we could support it along with the above syntax when no label is + # needed. Problem: label, value is arbitrary and as such potentially hard to remember. + + # >>> arr1.insert(before={'b1': ('b0.5', 8), 'b2': ('b1.5', 9)}) + # a\b b0 b0.5 b1 b1.5 b2 + # a0 0 8 1 9 2 + # a1 3 8 4 9 5 + + # This is shorter but not readable enough/even more arbitrary than the previous option. + + # >>> arr1.insert([(8, 'b1', 'b0.5'), (9, 'b2', 'b1.5')]) + # a\b b0 b0.5 b1 b1.5 b2 + # a0 0 8 1 9 2 + # a1 3 8 4 9 5 + + # This is readable but odd and not much gained (except efficiency) compared with multiple insert calls + + # >>> arr1.insert([(8, 'before', 'b1', 'label', 'b0.5'), + # (9, 'before', 'b2', 'label', 'b1.5')]) + # >>> arr1.insert(8, before='b1', label='b0.5') \ + # .insert(9, before='b2', label='b1.5') + if sum([before is not None, after is not None, pos is not None]) != 1: + raise ValueError("must specify exactly one of before, after or pos") + + axis = self.axes[axis] if axis is not None else None + if before is not None: + before = self._translate_axis_key(before) if axis is None else axis[before] + axis = before.axis + before_pos = axis.index(before) + elif after is not None: + after = self._translate_axis_key(after) if axis is None else axis[after] + axis = after.axis + before_pos = axis.index(after) + 1 + else: + assert pos is not None + if axis is None: + raise ValueError("axis argument must be provided when using insert(pos=)") + before_pos = pos + + def length(v): + if isinstance(v, LArray) and axis in v.axes: + return len(v.axes[axis]) + else: + return len(v) if isinstance(v, (tuple, list, np.ndarray)) else 1 + + def expand(v, length): + return v if isinstance(v, (tuple, list, np.ndarray)) else [v] * length + + num_inserts = max(length(before_pos), length(label), length(value)) + stops = expand(before_pos, num_inserts) + + if isinstance(value, LArray) and axis in value.axes: + # FIXME: when length(before_pos) == 1 and length(label) == 1, this is inefficient + values = [value[[k]] for k in value.axes[axis]] + else: + values = expand(value, num_inserts) + values = [aslarray(v) if not isinstance(v, LArray) else v + for v in values] + + if label is not None: + labels = expand(label, num_inserts) + values = [v.expand(Axis([l], axis.name), readonly=True) for v, l in zip(values, labels)] + + start = 0 + chunks = [] + for stop, value in zip(stops, values): + chunks.append(self[axis.i[start:stop]]) + chunks.append(value) + start = stop + chunks.append(self[axis.i[start:]]) + return concat(chunks, axis) + + def transpose(self, *args): + """Reorder axes. + + Parameters + ---------- + *args + Accepts either a tuple of axes specs or axes specs as `*args`. Omitted axes keep their order. + Use ... to avoid specifying intermediate axes. + + Returns + ------- + LArray + LArray with reordered axes. + + Examples + -------- + >>> arr = ndtest((2, 2, 2)) + >>> arr + a b\\c c0 c1 + a0 b0 0 1 + a0 b1 2 3 + a1 b0 4 5 + a1 b1 6 7 + >>> arr.transpose('b', 'c', 'a') + b c\\a a0 a1 + b0 c0 0 4 + b0 c1 1 5 + b1 c0 2 6 + b1 c1 3 7 + >>> arr.transpose('b') + b a\\c c0 c1 + b0 a0 0 1 + b0 a1 4 5 + b1 a0 2 3 + b1 a1 6 7 + >>> arr.transpose(..., 'a') # doctest: +SKIP + b c\\a a0 a1 + b0 c0 0 4 + b0 c1 1 5 + b1 c0 2 6 + b1 c1 3 7 + >>> arr.transpose('c', ..., 'a') # doctest: +SKIP + c b\\a a0 a1 + c0 b0 0 4 + c0 b1 2 6 + c1 b0 1 5 + c1 b1 3 7 + """ + if len(args) == 1 and isinstance(args[0], (tuple, list, AxisCollection)): + axes = args[0] + elif len(args) == 0: + axes = self.axes[::-1] + else: + axes = args + + axes = self.axes[axes] + axes_indices = [self.axes.index(axis) for axis in axes] + # this whole mumbo jumbo is required (for now) for anonymous axes + indices_present = set(axes_indices) + missing_indices = [i for i in range(len(self.axes)) if i not in indices_present] + axes_indices = axes_indices + missing_indices + return LArray(self.data.transpose(axes_indices), self.axes[axes_indices]) + T = property(transpose) + + def clip(self, a_min, a_max, out=None): + """Clip (limit) the values in an array. + + Given an interval, values outside the interval are clipped to the interval edges. + For example, if an interval of [0, 1] is specified, values smaller than 0 become 0, + and values larger than 1 become 1. + + Parameters + ---------- + a_min : scalar or array-like + Minimum value. + a_max : scalar or array-like + Maximum value. + out : LArray, optional + The results will be placed in this array. + + Returns + ------- + LArray + An array with the elements of the current array, + but where values < `a_min` are replaced with `a_min`, and those > `a_max` with `a_max`. + + Notes + ----- + If `a_min` and/or `a_max` are array_like, broadcast will occur between self, `a_min` and `a_max`. + """ + from larray.core.ufuncs import clip + return clip(self, a_min, a_max, out) + + @deprecate_kwarg('transpose', 'wide') + def to_csv(self, filepath, sep=',', na_rep='', wide=True, value_name='value', dropna=None, dialect='default', **kwargs): + """ + Writes array to a csv file. + + Parameters + ---------- + filepath : str + path where the csv file has to be written. + sep : str, optional + separator for the csv file. Defaults to `,`. + na_rep : str, optional + replace NA values with na_rep. Defaults to ''. + wide : boolean, optional + Whether or not writing arrays in "wide" format. If True, arrays are exported with the last axis + represented horizontally. If False, arrays are exported in "narrow" format: one column per axis plus one + value column. Defaults to True. + value_name : str, optional + Name of the column containing the values (last column) in the csv file when `wide=False` (see above). + Defaults to 'value'. + dialect : 'default' | 'classic', optional + Whether or not to write the last axis name (using '\' ). Defaults to 'default'. + dropna : None, 'all', 'any' or True, optional + Drop lines if 'all' its values are NA, if 'any' value is NA or do not drop any line (default). + True is equivalent to 'all'. + + Examples + -------- + >>> tmpdir = getfixture('tmpdir') + >>> fname = os.path.join(tmpdir.strpath, 'test.csv') + >>> a = ndtest('nat=BE,FO;sex=M,F') + >>> a + nat\\sex M F + BE 0 1 + FO 2 3 + >>> a.to_csv(fname) + >>> with open(fname) as f: + ... print(f.read().strip()) + nat\\sex,M,F + BE,0,1 + FO,2,3 + >>> a.to_csv(fname, sep=';', wide=False) + >>> with open(fname) as f: + ... print(f.read().strip()) + nat;sex;value + BE;M;0 + BE;F;1 + FO;M;2 + FO;F;3 + >>> a.to_csv(fname, sep=';', wide=False, value_name='population') + >>> with open(fname) as f: + ... print(f.read().strip()) + nat;sex;population + BE;M;0 + BE;F;1 + FO;M;2 + FO;F;3 + >>> a.to_csv(fname, dialect='classic') + >>> with open(fname) as f: + ... print(f.read().strip()) + nat,M,F + BE,0,1 + FO,2,3 + """ + fold = dialect == 'default' + if wide: + frame = self.to_frame(fold, dropna) + frame.to_csv(filepath, sep=sep, na_rep=na_rep, **kwargs) + else: + series = self.to_series(value_name, dropna is not None) + series.to_csv(filepath, sep=sep, na_rep=na_rep, header=True, **kwargs) + + def to_hdf(self, filepath, key, *args, **kwargs): + """ + Writes array to a HDF file. + + A HDF file can contain multiple arrays. + The 'key' parameter is a unique identifier for the array. + + Parameters + ---------- + filepath : str + Path where the hdf file has to be written. + key : str or Group + Name of the array within the HDF file. + *args + **kargs + + Examples + -------- + >>> a = ndtest((2, 3)) + >>> a.to_hdf('test.h5', 'a') # doctest: +SKIP + """ + key = _translate_key_hdf(key) + self.to_frame().to_hdf(filepath, key, *args, **kwargs) + + @deprecate_kwarg('sheet_name', 'sheet') + def to_excel(self, filepath=None, sheet=None, position='A1', overwrite_file=False, clear_sheet=False, + header=True, transpose=False, wide=True, value_name='value', engine=None, *args, **kwargs): + """ + Writes array in the specified sheet of specified excel workbook. + + Parameters + ---------- + filepath : str or int or None, optional + Path where the excel file has to be written. If None (default), creates a new Excel Workbook in a live Excel + instance (Windows only). Use -1 to use the currently active Excel Workbook. Use a name without extension + (.xlsx) to use any unsaved* workbook. + sheet : str or Group or int or None, optional + Sheet where the data has to be written. Defaults to None, Excel standard name if adding a sheet to an + existing file, "Sheet1" otherwise. sheet can also refer to the position of the sheet + (e.g. 0 for the first sheet, -1 for the last one). + position : str or tuple of integers, optional + Integer position (row, column) must be 1-based. Defaults to 'A1'. + overwrite_file : bool, optional + Whether or not to overwrite the existing file (or just modify the specified sheet). Defaults to False. + clear_sheet : bool, optional + Whether or not to clear the existing sheet (if any) before writing. Defaults to False. + header : bool, optional + Whether or not to write a header (axes names and labels). Defaults to True. + transpose : bool, optional + Whether or not to transpose the array over last axis. + This is equivalent to paste with option transpose in Excel. Defaults to False. + wide : boolean, optional + Whether or not writing arrays in "wide" format. If True, arrays are exported with the last axis + represented horizontally. If False, arrays are exported in "narrow" format: one column per axis plus one + value column. Defaults to True. + value_name : str, optional + Name of the column containing the values (last column) in the Excel sheet when `wide=False` (see above). + Defaults to 'value'. + engine : 'xlwings' | 'openpyxl' | 'xlsxwriter' | 'xlwt' | None, optional + Engine to use to make the output. If None (default), it will use 'xlwings' by default if the module is + installed and relies on Pandas default writer otherwise. + *args + **kwargs + + Examples + -------- + >>> a = ndtest('nat=BE,FO;sex=M,F') + >>> # write to a new (unnamed) sheet + >>> a.to_excel('test.xlsx') # doctest: +SKIP + >>> # write to top-left corner of an existing sheet + >>> a.to_excel('test.xlsx', 'Sheet1') # doctest: +SKIP + >>> # add to existing sheet starting at position A15 + >>> a.to_excel('test.xlsx', 'Sheet1', 'A15') # doctest: +SKIP + """ + sheet = _translate_sheet_name(sheet) + + if wide: + pd_obj = self.to_frame(fold_last_axis_name=True) + if transpose and self.ndim >= 2: + names = pd_obj.index.names + pd_obj.index.names = names[:-2] + ['\\'.join(reversed(names[-1].split('\\')))] + else: + pd_obj = self.to_series(value_name) + + if engine is None: + engine = 'xlwings' if xw is not None else None + + if engine == 'xlwings': + from larray.inout.excel import open_excel + + close = False + new_workbook = False + if filepath is None: + new_workbook = True + elif isinstance(filepath, str): + basename, ext = os.path.splitext(filepath) + if ext: + if not os.path.isfile(filepath): + new_workbook = True + close = True + if new_workbook or overwrite_file: + new_workbook = overwrite_file = True + + wb = open_excel(filepath, overwrite_file=overwrite_file) + + if new_workbook: + sheetobj = wb.sheets[0] + if sheet is not None: + sheetobj.name = sheet + elif sheet is not None and sheet in wb: + sheetobj = wb.sheets[sheet] + if clear_sheet: + sheetobj.clear() + else: + sheetobj = wb.sheets.add(sheet, after=wb.sheets[-1]) + + options = dict(header=header, index=header, transpose=transpose) + sheetobj[position].options(**options).value = pd_obj + # TODO: implement wide via/in dump + # sheet[position] = self.dump(header=header, wide=wide) + if close: + wb.save() + wb.close() + else: + if sheet is None: + sheet = 'Sheet1' + # TODO: implement position in this case + # startrow, startcol + pd_obj.to_excel(filepath, sheet, *args, engine=engine, **kwargs) + + def to_clipboard(self, *args, **kwargs): + """Sends the content of the array to clipboard. + + Using to_clipboard() makes it possible to paste the content of the array into a file (Excel, ascii file,...). + + Examples + -------- + >>> a = ndtest('nat=BE,FO;sex=M,F') + >>> a.to_clipboard() # doctest: +SKIP + """ + self.to_frame().to_clipboard(*args, **kwargs) + + # XXX: sep argument does not seem very useful + # def to_excel(self, filename, sep=None): + # # Why xlsxwriter? Because it is faster than openpyxl and xlwt + # # currently does not .xlsx (only .xls). + # # PyExcelerate seem like a decent alternative too + # import xlsxwriter as xl + # + # if sep is None: + # sep = '_' + # #sep = self.sep + # workbook = xl.Workbook(filename) + # if self.ndim > 2: + # for key in product(*[axis.labels for axis in self.axes[:-2]]): + # sheetname = sep.join(str(k) for k in key) + # # sheet names must not: + # # * contain any of the following characters: : \ / ? * [ ] + # # XXX: this will NOT work for unicode strings ! + # table = string.maketrans('[:]', '(-)') + # todelete = r'\/?*' + # sheetname = sheetname.translate(table, todelete) + # # * exceed 31 characters + # # sheetname = sheetname[:31] + # # * be blank + # assert sheetname, "sheet name cannot be blank" + # worksheet = workbook.add_worksheet(sheetname) + # worksheet.write_row(0, 1, self.axes[-1].labels) + # worksheet.write_column(1, 0, self.axes[-2].labels) + # for row, data in enumerate(np.asarray(self[key])): + # worksheet.write_row(1+row, 1, data) + # + # else: + # worksheet = workbook.add_worksheet('Sheet1') + # worksheet.write_row(0, 1, self.axes[-1].labels) + # if self.ndim == 2: + # worksheet.write_column(1, 0, self.axes[-2].labels) + # for row, data in enumerate(np.asarray(self)): + # worksheet.write_row(1+row, 1, data) + + @property + def plot(self): + """Plots the data of the array into a graph (window pop-up). + + The graph can be tweaked to achieve the desired formatting and can be saved to a .png file. + + Parameters + ---------- + kind : str + - 'line' : line plot (default) + - 'bar' : vertical bar plot + - 'barh' : horizontal bar plot + - 'hist' : histogram + - 'box' : boxplot + - 'kde' : Kernel Density Estimation plot + - 'density' : same as 'kde' + - 'area' : area plot + - 'pie' : pie plot + - 'scatter' : scatter plot (if array's dimensions >= 2) + - 'hexbin' : hexbin plot (if array's dimensions >= 2) + ax : matplotlib axes object, default None + subplots : boolean, default False + Make separate subplots for each column + sharex : boolean, default True if ax is None else False + In case subplots=True, share x axis and set some x axis labels to invisible; + defaults to True if ax is None otherwise False if an ax is passed in; + Be aware, that passing in both an ax and sharex=True will alter all x axis labels for all axis in a figure! + sharey : boolean, default False + In case subplots=True, share y axis and set some y axis labels to invisible + layout : tuple (optional) + (rows, columns) for the layout of subplots + figsize : a tuple (width, height) in inches + use_index : boolean, default True + Use index as ticks for x axis + title : string + Title to use for the plot + grid : boolean, default None (matlab style default) + Axis grid lines + legend : False/True/'reverse' + Place legend on axis subplots + style : list or dict + matplotlib line style per column + logx : boolean, default False + Use log scaling on x axis + logy : boolean, default False + Use log scaling on y axis + loglog : boolean, default False + Use log scaling on both x and y axes + xticks : sequence + Values to use for the xticks + yticks : sequence + Values to use for the yticks + xlim : 2-tuple/list + ylim : 2-tuple/list + rot : int, default None + Rotation for ticks (xticks for vertical, yticks for horizontal plots) + fontsize : int, default None + Font size for xticks and yticks + colormap : str or matplotlib colormap object, default None + Colormap to select colors from. If string, load colormap with that name from matplotlib. + colorbar : boolean, optional + If True, plot colorbar (only relevant for 'scatter' and 'hexbin' plots) + position : float + Specify relative alignments for bar plot layout. From 0 (left/bottom-end) to 1 (right/top-end). + Default is 0.5 (center) + layout : tuple (optional) + (rows, columns) for the layout of the plot + yerr : array-like + Error bars on y axis + xerr : array-like + Error bars on x axis + stacked : boolean, default False in line and bar plots, and True in area plot. + If True, create stacked plot. + \**kwargs : keywords + Options to pass to matplotlib plotting method + + Returns + ------- + axes : matplotlib.AxesSubplot or np.array of them + + Notes + ----- + See Pandas documentation of `plot` function for more details on this subject + + Examples + -------- + >>> import matplotlib.pyplot as plt # doctest: +SKIP + >>> a = ndtest('sex=M,F;age=0..20') + + Simple line plot + + >>> a.plot() # doctest: +SKIP + >>> # shows figure (reset the current figure after showing it! Do not call it before savefig) + >>> plt.show() # doctest: +SKIP + + Line plot with grid, title and both axes in logscale + + >>> a.plot(grid=True, loglog=True, title='line plot') # doctest: +SKIP + >>> # saves figure in a file (see matplotlib.pyplot.savefig documentation for more details) + >>> plt.savefig('my_file.png') # doctest: +SKIP + + 2 bar plots sharing the same x axis (one for males and one for females) + + >>> a.plot.bar(subplots=True, sharex=True) # doctest: +SKIP + >>> plt.show() # doctest: +SKIP + + Create a figure containing 2 x 2 graphs + + >>> # see matplotlib.pyplot.subplots documentation for more details + >>> fig, ax = plt.subplots(2, 2, figsize=(15, 15)) # doctest: +SKIP + >>> # 2 curves : Males and Females + >>> a.plot(ax=ax[0, 0], title='line plot') # doctest: +SKIP + >>> # bar plot with stacked values + >>> a.plot.bar(ax=ax[0, 1], stacked=True, title='stacked bar plot') # doctest: +SKIP + >>> # same as previously but with colored areas instead of bars + >>> a.plot.area(ax=ax[1, 0], title='area plot') # doctest: +SKIP + >>> # scatter plot + >>> a.plot.scatter(ax=ax[1, 1], x='M', y='F', title='scatter plot') # doctest: +SKIP + >>> plt.show() # doctest: +SKIP + """ + combined = self.combine_axes(self.axes[:-1], sep=' ') if self.ndim > 2 else self + if combined.ndim == 1: + return combined.to_series().plot + else: + return combined.transpose().to_frame().plot + + @property + def shape(self): + """Returns the shape of the array as a tuple. + + Returns + ------- + tuple + Tuple representing the current shape. + + Examples + -------- + >>> a = ndtest('nat=BE,FO;sex=M,F;type=type1,type2,type3') + >>> a.shape # doctest: +SKIP + (2, 2, 3) + """ + return self.data.shape + + @property + def ndim(self): + """Returns the number of dimensions of the array. + + Returns + ------- + int + Number of dimensions of a LArray. + + Examples + -------- + >>> a = ndtest('nat=BE,FO;sex=M,F') + >>> a.ndim + 2 + """ + return self.data.ndim + + @property + def size(self): + """Returns the number of elements in array. + + Returns + ------- + int + Number of elements in array. + + Examples + -------- + >>> a = ndtest('sex=M,F;type=type1,type2,type3') + >>> a.size + 6 + """ + return self.data.size + + @property + def nbytes(self): + """Returns the number of bytes used to store the array in memory. + + Returns + ------- + int + Number of bytes in array. + + Examples + -------- + >>> a = ndtest('sex=M,F;type=type1,type2,type3', dtype=float) + >>> a.nbytes + 48 + """ + return self.data.nbytes + + @property + def memory_used(self): + """Returns the memory consumed by the array in human readable form. + + Returns + ------- + str + Memory used by the array. + + Examples + -------- + >>> a = ndtest('sex=M,F;type=type1,type2,type3', dtype=float) + >>> a.memory_used + '48 bytes' + """ + return size2str(self.data.nbytes) + + @property + def dtype(self): + """Returns the type of the data of the array. + + Returns + ------- + dtype + Type of the data of the array. + + Examples + -------- + >>> a = zeros('sex=M,F;type=type1,type2,type3') + >>> a.dtype + dtype('float64') + """ + return self.data.dtype + + @property + def item(self): + return self.data.item + + def __len__(self): + return len(self.data) + + def __array__(self, dtype=None): + return np.asarray(self.data, dtype=dtype) + + __array_priority__ = 100 + + # XXX: implement guess axis? + """ + # guessing each axis + >>> a.set_labels({'M': 'Men', 'BE': 'Belgian'}) + nat\\sex Men Women + BE 0 1 + FO 2 3 + + # we have to choose which one to support because it is probably not a good idea to simultaneously support the + # following syntax (even though we *could* support both if we split values on , before we determine if the key is + # an axis or a label by looking if the value is a list or a single string. + >>> a.set_labels({'sex': 'Men,Women', 'BE': 'Belgian'}) + nat\\sex Men Women + BE 0 1 + FO 2 3 + # this is shorter but I do not like it because string are both quoted and not quoted and you cannot have int + # labels + >>> a.set_labels(M='Men', BE='Belgian') + nat\\sex Men Women + BE 0 1 + FO 2 3 + """ + def set_labels(self, axis=None, labels=None, inplace=False, **kwargs): + """Replaces the labels of an axis of array. + + Parameters + ---------- + axis : string or Axis or dict + Axis for which we want to replace labels, or mapping {axis: changes} where changes can either be the + complete list of labels or a mapping {old_label: new_label}. + labels : int, str, iterable or mapping, optional + Integer or list of values usable as the collection of labels for an Axis. If this is mapping, it must be + {old_label: new_label}. This argument must not be used if axis is a mapping. + inplace : bool, optional + Whether or not to modify the original object or return a new array and leave the original intact. + Defaults to False. + **kwargs : + `axis`=`labels` for each axis you want to set labels. + + Returns + ------- + LArray + Array with modified labels. + + Examples + -------- + >>> a = ndtest('nat=BE,FO;sex=M,F') + >>> a + nat\\sex M F + BE 0 1 + FO 2 3 + >>> a.set_labels(X.sex, ['Men', 'Women']) + nat\\sex Men Women + BE 0 1 + FO 2 3 + + when passing a single string as labels, it will be interpreted to create the list of labels, so that one can + use the same syntax than during axis creation. + + >>> a.set_labels(X.sex, 'Men,Women') + nat\\sex Men Women + BE 0 1 + FO 2 3 + + to replace only some labels, one must give a mapping giving the new label for each label to replace + + >>> a.set_labels(X.sex, {'M': 'Men'}) + nat\\sex Men F + BE 0 1 + FO 2 3 + + to replace labels for several axes at the same time, one should give a mapping giving the new labels for each + changed axis + + >>> a.set_labels({'sex': 'Men,Women', 'nat': 'Belgian,Foreigner'}) + nat\\sex Men Women + Belgian 0 1 + Foreigner 2 3 + + or use keyword arguments + + >>> a.set_labels(sex='Men,Women', nat='Belgian,Foreigner') + nat\\sex Men Women + Belgian 0 1 + Foreigner 2 3 + + one can also replace some labels in several axes by giving a mapping of mappings + + >>> a.set_labels({'sex': {'M': 'Men'}, 'nat': {'BE': 'Belgian'}}) + nat\\sex Men F + Belgian 0 1 + FO 2 3 + """ + if axis is None: + changes = {} + elif isinstance(axis, dict): + changes = axis + elif isinstance(axis, (basestring, Axis, int)): + changes = {axis: labels} + else: + raise ValueError("Expected None or a string/int/Axis/dict instance for axis argument") + changes.update(kwargs) + # TODO: we should implement the non-dict behavior in Axis.replace, so that we can simplify this code to: + # new_axes = [self.axes[old_axis].replace(axis_changes) for old_axis, axis_changes in changes.items()] + new_axes = [] + for old_axis, axis_changes in changes.items(): + real_axis = self.axes[old_axis] + if isinstance(axis_changes, dict): + new_axis = real_axis.replace(axis_changes) + else: + new_axis = Axis(axis_changes, real_axis.name) + new_axes.append((old_axis, new_axis)) + axes = self.axes.replace(new_axes) + + if inplace: + self.axes = axes + return self + else: + return LArray(self.data, axes) + + def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True): + return LArray(self.data.astype(dtype, order, casting, subok, copy), self.axes) + astype.__doc__ = np.ndarray.astype.__doc__ + + def shift(self, axis, n=1): + """Shifts the cells of the array n-times to the left along axis. + + Parameters + ---------- + axis : int, str or Axis + Axis for which we want to perform the shift. + n : int + Number of cells to shift. + + Returns + ------- + LArray + + Examples + -------- + >>> a = ndtest('sex=M,F;type=type1,type2,type3') + >>> a + sex\\type type1 type2 type3 + M 0 1 2 + F 3 4 5 + >>> a.shift(X.type) + sex\\type type2 type3 + M 0 1 + F 3 4 + >>> a.shift(X.type, n=-1) + sex\\type type1 type2 + M 1 2 + F 4 5 + """ + axis = self.axes[axis] + if n > 0: + return self[axis.i[:-n]].set_labels(axis, axis.labels[n:]) + elif n < 0: + return self[axis.i[-n:]].set_labels(axis, axis.labels[:n]) + else: + return self[:] + + # TODO: add support for groups as axis (like aggregates) + # eg a.diff(x.year[2018:]) instead of a[2018:].diff(x.year) + def diff(self, axis=-1, d=1, n=1, label='upper'): + """Calculates the n-th order discrete difference along a given axis. + + The first order difference is given by out[n] = a[n + 1] - a[n] along the given axis, higher order differences + are calculated by using diff recursively. + + Parameters + ---------- + axis : int, str, Group or Axis, optional + Axis or group along which the difference is taken. Defaults to the last axis. + d : int, optional + Periods to shift for forming difference. Defaults to 1. + n : int, optional + The number of times values are differenced. Defaults to 1. + label : {'lower', 'upper'}, optional + The new labels in `axis` will have the labels of either the array being subtracted ('lower') or the array + it is subtracted from ('upper'). Defaults to 'upper'. + + Returns + ------- + LArray : + The n-th order differences. The shape of the output is the same as `a` except for `axis` which is smaller + by `n` * `d`. + + Examples + -------- + >>> a = ndtest('sex=M,F;type=type1,type2,type3').cumsum('type') + >>> a + sex\\type type1 type2 type3 + M 0 1 3 + F 3 7 12 + >>> a.diff() + sex\\type type2 type3 + M 1 2 + F 4 5 + >>> a.diff(n=2) + sex\\type type3 + M 1 + F 1 + >>> a.diff('sex') + sex\\type type1 type2 type3 + F 3 6 9 + >>> a.diff(a.type['type2':]) + sex\\type type3 + M 2 + F 5 + """ + if isinstance(axis, Group): + array = self[axis] + axis = array.axes[axis.axis] + else: + array = self + for _ in range(n): + axis_obj = array.axes[axis] + left = array[axis_obj.i[d:]] + right = array[axis_obj.i[:-d]] + if label == 'upper': + right = right.drop_labels(axis) + else: + left = left.drop_labels(axis) + array = left - right + return array + + # XXX: this is called pct_change in Pandas (but returns the same results, not results * 100, which I find silly). + # Maybe change_rate would be better (because growth is not always positive)? + def growth_rate(self, axis=-1, d=1, label='upper'): + """Calculates the growth along a given axis. + + Roughly equivalent to a.diff(axis, d, label) / a[axis.i[:-d]] + + Parameters + ---------- + axis : int, str, Group or Axis, optional + Axis or group along which the difference is taken. Defaults to the last axis. + d : int, optional + Periods to shift for forming difference. Defaults to 1. + label : {'lower', 'upper'}, optional + The new labels in `axis` will have the labels of either + the array being subtracted ('lower') or the array it is + subtracted from ('upper'). Defaults to 'upper'. + + Returns + ------- + LArray + + Examples + -------- + >>> data = [[2, 4, 5, 4, 6], [4, 6, 3, 6, 9]] + >>> a = LArray(data, "sex=M,F; year=2016..2020") + >>> a + sex\\year 2016 2017 2018 2019 2020 + M 2 4 5 4 6 + F 4 6 3 6 9 + >>> a.growth_rate() + sex\\year 2017 2018 2019 2020 + M 1.0 0.25 -0.2 0.5 + F 0.5 -0.5 1.0 0.5 + >>> a.growth_rate(label='lower') + sex\\year 2016 2017 2018 2019 + M 1.0 0.25 -0.2 0.5 + F 0.5 -0.5 1.0 0.5 + >>> a.growth_rate(d=2) + sex\\year 2018 2019 2020 + M 1.5 0.0 0.2 + F -0.25 0.0 2.0 + >>> a.growth_rate('sex') + sex\\year 2016 2017 2018 2019 2020 + F 1.0 0.5 -0.4 0.5 0.5 + >>> a.growth_rate(a.year[2017:]) + sex\\year 2018 2019 2020 + M 0.25 -0.2 0.5 + F -0.5 1.0 0.5 + """ + if isinstance(axis, Group): + array = self[axis] + axis = array.axes[axis.axis] + else: + array = self + axis = array.axes[axis] + diff = array.diff(axis=axis, d=d, label=label) + return diff / array[axis.i[:-d]].drop_labels(axis) + + def compact(self): + """Detects and removes "useless" axes (ie axes for which values are constant over the whole axis) + + Returns + ------- + LArray or scalar + Array with constant axes removed. + + Examples + -------- + >>> a = LArray([[1, 2], + ... [1, 2]], [Axis('sex=M,F'), Axis('nat=BE,FO')]) + >>> a + sex\\nat BE FO + M 1 2 + F 1 2 + >>> a.compact() + nat BE FO + 1 2 + """ + res = self + for axis in res.axes: + if (res == res[axis.i[0]]).all(): + res = res[axis.i[0]] + return res + + def combine_axes(self, axes=None, sep='_', wildcard=False): + """Combine several axes into one. + + Parameters + ---------- + axes : tuple, list, AxisCollection of axes or list of combination of those or dict, optional + axes to combine. Tuple, list or AxisCollection will combine several axes into one. To chain several axes + combinations, pass a list of tuple/list/AxisCollection of axes. To set the name(s) of resulting axis(es), + use a {(axes, to, combine): 'new_axis_name'} dictionary. Defaults to all axes. + sep : str, optional + delimiter to use for combining. Defaults to '_'. + wildcard : bool, optional + whether or not to produce a wildcard axis even if the axes to combine are not. This is much faster, + but loose axes labels. + + Returns + ------- + LArray + Array with combined axes. + + Examples + -------- + >>> arr = ndtest((2, 3)) + >>> arr + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> arr.combine_axes() + a_b a0_b0 a0_b1 a0_b2 a1_b0 a1_b1 a1_b2 + 0 1 2 3 4 5 + >>> arr.combine_axes(sep='/') + a/b a0/b0 a0/b1 a0/b2 a1/b0 a1/b1 a1/b2 + 0 1 2 3 4 5 + >>> arr = ndtest((2, 2, 2, 2)) + >>> arr + a b c\\d d0 d1 + a0 b0 c0 0 1 + a0 b0 c1 2 3 + a0 b1 c0 4 5 + a0 b1 c1 6 7 + a1 b0 c0 8 9 + a1 b0 c1 10 11 + a1 b1 c0 12 13 + a1 b1 c1 14 15 + >>> arr.combine_axes(('a', 'c')) + a_c b\\d d0 d1 + a0_c0 b0 0 1 + a0_c0 b1 4 5 + a0_c1 b0 2 3 + a0_c1 b1 6 7 + a1_c0 b0 8 9 + a1_c0 b1 12 13 + a1_c1 b0 10 11 + a1_c1 b1 14 15 + >>> arr.combine_axes({('a', 'c'): 'ac'}) + ac b\\d d0 d1 + a0_c0 b0 0 1 + a0_c0 b1 4 5 + a0_c1 b0 2 3 + a0_c1 b1 6 7 + a1_c0 b0 8 9 + a1_c0 b1 12 13 + a1_c1 b0 10 11 + a1_c1 b1 14 15 + + # make several combinations at once + + >>> arr.combine_axes([('a', 'c'), ('b', 'd')]) + a_c\\b_d b0_d0 b0_d1 b1_d0 b1_d1 + a0_c0 0 1 4 5 + a0_c1 2 3 6 7 + a1_c0 8 9 12 13 + a1_c1 10 11 14 15 + >>> arr.combine_axes({('a', 'c'): 'ac', ('b', 'd'): 'bd'}) + ac\\bd b0_d0 b0_d1 b1_d0 b1_d1 + a0_c0 0 1 4 5 + a0_c1 2 3 6 7 + a1_c0 8 9 12 13 + a1_c1 10 11 14 15 + """ + if axes is None: + axes = {tuple(self.axes): None} + elif isinstance(axes, AxisCollection): + axes = {tuple(axes): None} + elif isinstance(axes, (list, tuple)): + # checks for nested tuple/list + if all(isinstance(axis, (list, tuple, AxisCollection)) for axis in axes): + axes = {tuple(axes_to_combine): None for axes_to_combine in axes} + else: + axes = {tuple(axes): None} + # axes should be a dict at this time + assert isinstance(axes, dict) + + transposed_axes = self.axes[:] + for axes_to_combine, name in axes.items(): + # transpose all axes next to each other, using index of first axis + axes_to_combine = self.axes[axes_to_combine] + axes_indices = [transposed_axes.index(axis) for axis in axes_to_combine] + min_axis_index = min(axes_indices) + transposed_axes = transposed_axes - axes_to_combine + transposed_axes = transposed_axes[:min_axis_index] + axes_to_combine + transposed_axes[min_axis_index:] + transposed = self.transpose(transposed_axes) + + new_axes = transposed.axes.combine_axes(axes, sep=sep, wildcard=wildcard) + return transposed.reshape(new_axes) + + def split_axes(self, axes=None, sep='_', names=None, regex=None, sort=False, fill_value=nan): + """Split axes and returns a new array + + Parameters + ---------- + axes : int, str, Axis or any combination of those + axes to split. All labels *must* contain the given delimiter string. To split several axes at once, pass + a list or tuple of axes to split. To set the names of resulting axes, use a {'axis_to_split': (new, axes)} + dictionary. Defaults to all axes whose name contains the `sep` delimiter. + sep : str, optional + delimiter to use for splitting. Defaults to '_'. + When `regex` is provided, the delimiter is only used on `names` if given as one string or on axis name if + `names` is None. + names : str or list of str, optional + names of resulting axes. Defaults to None. + regex : str, optional + use regex instead of delimiter to split labels. Defaults to None. + sort : bool, optional + Whether or not to sort the combined axis before splitting it. When all combinations of labels are present in + the combined axis, sorting is faster than not sorting. Defaults to False. + fill_value : scalar or LArray, optional + Value to use for missing values when the combined axis does not contain all combination of labels. + Defaults to NaN. + + Returns + ------- + LArray + + Examples + -------- + >>> arr = ndtest((2, 3)) + >>> arr + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> combined = arr.combine_axes() + >>> combined + a_b a0_b0 a0_b1 a0_b2 a1_b0 a1_b1 a1_b2 + 0 1 2 3 4 5 + >>> combined.split_axes() + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + + Split labels using regex + + >>> combined = ndtest('a_b=a0b0..a1b2') + >>> combined + a_b a0b0 a0b1 a0b2 a1b0 a1b1 a1b2 + 0 1 2 3 4 5 + >>> combined.split_axes('a_b', regex='(\\\\w{2})(\\\\w{2})') + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + + Split several axes at once + + >>> combined = ndtest('a_b=a0_b0..a1_b1; c_d=c0_d0..c1_d1') + >>> combined + a_b\\c_d c0_d0 c0_d1 c1_d0 c1_d1 + a0_b0 0 1 2 3 + a0_b1 4 5 6 7 + a1_b0 8 9 10 11 + a1_b1 12 13 14 15 + >>> # equivalent to combined.split_axes() which split all axes whose name contains the `sep` delimiter. + >>> combined.split_axes(['a_b', 'c_d']) + a b c\\d d0 d1 + a0 b0 c0 0 1 + a0 b0 c1 2 3 + a0 b1 c0 4 5 + a0 b1 c1 6 7 + a1 b0 c0 8 9 + a1 b0 c1 10 11 + a1 b1 c0 12 13 + a1 b1 c1 14 15 + >>> combined.split_axes({'a_b': ('A', 'B'), 'c_d': ('C', 'D')}) + A B C\\D d0 d1 + a0 b0 c0 0 1 + a0 b0 c1 2 3 + a0 b1 c0 4 5 + a0 b1 c1 6 7 + a1 b0 c0 8 9 + a1 b0 c1 10 11 + a1 b1 c0 12 13 + a1 b1 c1 14 15 + """ + array = self.sort_axes(axes) if sort else self + # TODO: + # * do multiple axes split in one go + # * somehow factorize this code with AxisCollection.split_axes + if axes is None: + axes = {axis: None for axis in array.axes if sep in axis.name} + elif isinstance(axes, (int, basestring, Axis)): + axes = {axes: None} + elif isinstance(axes, (list, tuple)): + if all(isinstance(axis, (int, basestring, Axis)) for axis in axes): + axes = {axis: None for axis in axes} + else: + raise ValueError("Expected tuple or list of int, string or Axis instances") + # axes should be a dict at this time + assert isinstance(axes, dict) + for axis, names in axes.items(): + axis = array.axes[axis] + split_axes, split_labels = axis.split(sep, names, regex, return_labels=True) + + axis_index = array.axes.index(axis) + new_axes = array.axes[:axis_index] + split_axes + array.axes[axis_index + 1:] + # fast path when all combinations of labels are present in the combined axis + all_combinations_present = AxisCollection(split_axes).size == len(np.unique(axis.labels)) + if all_combinations_present and sort: + array = array.reshape(new_axes) + else: + if all_combinations_present: + res = empty(new_axes, dtype=array.dtype) + else: + res = full(new_axes, fill_value=fill_value, dtype=common_type((array, fill_value))) + if names is None: + names = axis.name.split(sep) + # Rename axis to make sure we broadcast correctly. We should NOT use sep here, but rather '_' must be + # kept in sync with the default sep of _bool_key_new_axes + new_axis_name = '_'.join(names) + if new_axis_name != axis.name: + array = array.rename(axis, new_axis_name) + res.points[split_labels] = array + array = res + return array + split_axis = renamed_to(split_axes, 'split_axis') + + +def larray_equal(a1, a2): + import warnings + msg = "larray_equal() is deprecated. Use LArray.equals() instead." + warnings.warn(msg, FutureWarning, stacklevel=2) + try: + a1 = aslarray(a1) + except Exception: + return False + return a1.equals(a2) + + +def larray_nan_equal(a1, a2): + import warnings + msg = "larray_nan_equal() is deprecated. Use LArray.equals() instead." + warnings.warn(msg, FutureWarning, stacklevel=2) + try: + a1 = aslarray(a1) + except Exception: + return False + return a1.equals(a2, nan_equals=True) + + +def aslarray(a): + """ + Converts input as LArray if possible. + + Parameters + ---------- + a : array-like + Input array to convert into a LArray. + + Returns + ------- + LArray + + Examples + -------- + >>> # NumPy array + >>> np_arr = np.arange(6).reshape((2,3)) + >>> aslarray(np_arr) + {0}*\{1}* 0 1 2 + 0 0 1 2 + 1 3 4 5 + >>> # Pandas dataframe + >>> data = {'normal' : pd.Series([1., 2., 3.], index=['a', 'b', 'c']), + ... 'reverse' : pd.Series([3., 2., 1.], index=['a', 'b', 'c'])} + >>> df = pd.DataFrame(data) + >>> aslarray(df) + {0}\{1} normal reverse + a 1.0 3.0 + b 2.0 2.0 + c 3.0 1.0 + """ + if isinstance(a, LArray): + return a + elif hasattr(a, '__larray__'): + return a.__larray__() + elif isinstance(a, pd.DataFrame): + from larray.inout.array import from_frame + return from_frame(a) + else: + return LArray(a) + + +def _check_axes_argument(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + if len(args) > 1 and isinstance(args[1], (int, Axis)): + raise ValueError("If you want to pass several axes or dimension lengths to {}, you must pass them as a " + "list (using []) or tuple (using()).".format(func.__name__)) + return func(*args, **kwargs) + return wrapper + + +@_check_axes_argument +def zeros(axes, title='', dtype=float, order='C'): + """Returns an array with the specified axes and filled with zeros. + + Parameters + ---------- + axes : int, tuple of int, Axis or tuple/list/AxisCollection of Axis + Collection of axes or a shape. + title : str, optional + Title. + dtype : data-type, optional + Desired data-type for the array, e.g., `numpy.int8`. Default is `numpy.float64`. + order : {'C', 'F'}, optional + Whether to store multidimensional data in C- (default) or Fortran-contiguous (row- or column-wise) order in + memory. + + Returns + ------- + LArray + + Examples + -------- + >>> zeros('nat=BE,FO;sex=M,F') + nat\sex M F + BE 0.0 0.0 + FO 0.0 0.0 + >>> zeros([(['BE', 'FO'], 'nat'), + ... (['M', 'F'], 'sex')]) + nat\sex M F + BE 0.0 0.0 + FO 0.0 0.0 + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> zeros([nat, sex]) + nat\sex M F + BE 0.0 0.0 + FO 0.0 0.0 + """ + axes = AxisCollection(axes) + return LArray(np.zeros(axes.shape, dtype, order), axes, title) + + +def zeros_like(array, title='', dtype=None, order='K'): + """Returns an array with the same axes as array and filled with zeros. + + Parameters + ---------- + array : LArray + Input array. + title : str, optional + Title. + dtype : data-type, optional + Overrides the data type of the result. + order : {'C', 'F', 'A', or 'K'}, optional + Overrides the memory layout of the result. + 'C' means C-order, 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, 'C' otherwise. + 'K' (default) means match the layout of `a` as closely as possible. + + Returns + ------- + LArray + + Examples + -------- + >>> a = ndtest((2, 3)) + >>> zeros_like(a) + a\\b b0 b1 b2 + a0 0 0 0 + a1 0 0 0 + """ + if not title: + title = array.title + return LArray(np.zeros_like(array, dtype, order), array.axes, title) + + +@_check_axes_argument +def ones(axes, title='', dtype=float, order='C'): + """Returns an array with the specified axes and filled with ones. + + Parameters + ---------- + axes : int, tuple of int, Axis or tuple/list/AxisCollection of Axis + Collection of axes or a shape. + title : str, optional + Title. + dtype : data-type, optional + Desired data-type for the array, e.g., `numpy.int8`. Default is `numpy.float64`. + order : {'C', 'F'}, optional + Whether to store multidimensional data in C- (default) or Fortran-contiguous (row- or column-wise) order in + memory. + + Returns + ------- + LArray + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> ones([nat, sex]) + nat\\sex M F + BE 1.0 1.0 + FO 1.0 1.0 + """ + axes = AxisCollection(axes) + return LArray(np.ones(axes.shape, dtype, order), axes, title) + + +def ones_like(array, title='', dtype=None, order='K'): + """Returns an array with the same axes as array and filled with ones. + + Parameters + ---------- + array : LArray + Input array. + title : str, optional + Title. + dtype : data-type, optional + Overrides the data type of the result. + order : {'C', 'F', 'A', or 'K'}, optional + Overrides the memory layout of the result. + 'C' means C-order, 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, 'C' otherwise. + 'K' (default) means match the layout of `a` as closely as possible. + + Returns + ------- + LArray + + Examples + -------- + >>> a = ndtest((2, 3)) + >>> ones_like(a) + a\\b b0 b1 b2 + a0 1 1 1 + a1 1 1 1 + """ + axes = array.axes + if not title: + title = array.title + return LArray(np.ones_like(array, dtype, order), axes, title) + + +@_check_axes_argument +def empty(axes, title='', dtype=float, order='C'): + """Returns an array with the specified axes and uninitialized (arbitrary) data. + + Parameters + ---------- + axes : int, tuple of int, Axis or tuple/list/AxisCollection of Axis + Collection of axes or a shape. + title : str, optional + Title. + dtype : data-type, optional + Desired data-type for the array, e.g., `numpy.int8`. Default is `numpy.float64`. + order : {'C', 'F'}, optional + Whether to store multidimensional data in C- (default) or Fortran-contiguous (row- or column-wise) order in + memory. + + Returns + ------- + LArray + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> empty([nat, sex]) # doctest: +SKIP + nat\\sex M F + BE 2.47311483356e-315 2.47498446195e-315 + FO 0.0 6.07684618082e-31 + """ + axes = AxisCollection(axes) + return LArray(np.empty(axes.shape, dtype, order), axes, title) + + +def empty_like(array, title='', dtype=None, order='K'): + """Returns an array with the same axes as array and uninitialized (arbitrary) data. + + Parameters + ---------- + array : LArray + Input array. + title : str, optional + Title. + dtype : data-type, optional + Overrides the data type of the result. Defaults to the data type of array. + order : {'C', 'F', 'A', or 'K'}, optional + Overrides the memory layout of the result. + 'C' means C-order, 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, 'C' otherwise. + 'K' (default) means match the layout of `a` as closely as possible. + + Returns + ------- + LArray + + Examples + -------- + >>> a = ndtest((3, 2)) + >>> empty_like(a) # doctest: +SKIP + a\\b b0 b1 + a0 2.12199579097e-314 6.36598737388e-314 + a1 1.06099789568e-313 1.48539705397e-313 + a2 1.90979621226e-313 2.33419537056e-313 + """ + if not title: + title = array.title + # cannot use empty() because order == 'K' is not understood + return LArray(np.empty_like(array.data, dtype, order), array.axes, title) + + +# We cannot use @_check_axes_argument here because an integer fill_value would be considered as an error +def full(axes, fill_value, title='', dtype=None, order='C'): + """Returns an array with the specified axes and filled with fill_value. + + Parameters + ---------- + axes : int, tuple of int, Axis or tuple/list/AxisCollection of Axis + Collection of axes or a shape. + fill_value : scalar or LArray + Value to fill the array + title : str, optional + Title. + dtype : data-type, optional + Desired data-type for the array. Default is the data type of fill_value. + order : {'C', 'F'}, optional + Whether to store multidimensional data in C- (default) or Fortran-contiguous (row- or column-wise) order in + memory. + + Returns + ------- + LArray + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> full([nat, sex], 42.0) + nat\\sex M F + BE 42.0 42.0 + FO 42.0 42.0 + >>> initial_value = ndtest([sex]) + >>> initial_value + sex M F + 0 1 + >>> full([nat, sex], initial_value) + nat\\sex M F + BE 0 1 + FO 0 1 + """ + if isinstance(fill_value, Axis): + raise ValueError("If you want to pass several axes or dimension lengths to full, you must pass them as a " + "list (using []) or tuple (using()).") + if dtype is None: + dtype = np.asarray(fill_value).dtype + res = empty(axes, title, dtype, order) + res[:] = fill_value + return res + + +def full_like(array, fill_value, title='', dtype=None, order='K'): + """Returns an array with the same axes and type as input array and filled with fill_value. + + Parameters + ---------- + array : LArray + Input array. + fill_value : scalar or LArray + Value to fill the array + title : str, optional + Title. + dtype : data-type, optional + Overrides the data type of the result. Defaults to the data type of array. + order : {'C', 'F', 'A', or 'K'}, optional + Overrides the memory layout of the result. + 'C' means C-order, 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, 'C' otherwise. + 'K' (default) means match the layout of `a` as closely as possible. + + Returns + ------- + LArray + + Examples + -------- + >>> a = ndtest((2, 3)) + >>> full_like(a, 5) + a\\b b0 b1 b2 + a0 5 5 5 + a1 5 5 5 + """ + if not title: + title = array.title + # cannot use full() because order == 'K' is not understood + # cannot use np.full_like() because it would not handle LArray fill_value + res = empty_like(array, title, dtype, order) + res[:] = fill_value + return res + + +# XXX: would it be possible to generalize to multiple axes? +def sequence(axis, initial=0, inc=None, mult=1, func=None, axes=None, title=''): + """ + Creates an array by sequentially applying modifications to the array along axis. + + The value for each label in axis will be given by sequentially transforming the value for the previous label. + This transformation on the previous label value consists of applying the function "func" on that value if provided, + or to multiply it by mult and increment it by inc otherwise. + + Parameters + ---------- + axis : axis definition (Axis, str, int) + Axis along which to apply mod. An axis definition can be passed as a string. An int will be interpreted as the + length for a new anonymous axis. + initial : scalar or LArray, optional + Value for the first label of axis. Defaults to 0. + inc : scalar, LArray, optional + Value to increment the previous value by. Defaults to 0 if mult is provided, 1 otherwise. + mult : scalar, LArray, optional + Value to multiply the previous value by. Defaults to 1. + func : function/callable, optional + Function to apply to the previous value. Defaults to None. + Note that this is much slower than using inc and/or mult. + axes : int, tuple of int or tuple/list/AxisCollection of Axis, optional + Axes of the result. Defaults to the union of axes present in other arguments. + title : str, optional + Title. + + Examples + -------- + >>> year = Axis('year=2016..2019') + >>> sex = Axis('sex=M,F') + >>> sequence(year) + year 2016 2017 2018 2019 + 0 1 2 3 + >>> sequence('year=2016..2019') + year 2016 2017 2018 2019 + 0 1 2 3 + >>> sequence(year, 1.0, 0.5) + year 2016 2017 2018 2019 + 1.0 1.5 2.0 2.5 + >>> sequence(year, 1.0, mult=1.5) + year 2016 2017 2018 2019 + 1.0 1.5 2.25 3.375 + >>> inc = LArray([1, 2], [sex]) + >>> inc + sex M F + 1 2 + >>> sequence(year, 1.0, inc) + sex\\year 2016 2017 2018 2019 + M 1.0 2.0 3.0 4.0 + F 1.0 3.0 5.0 7.0 + >>> mult = LArray([2, 3], [sex]) + >>> mult + sex M F + 2 3 + >>> sequence(year, 1.0, mult=mult) + sex\\year 2016 2017 2018 2019 + M 1.0 2.0 4.0 8.0 + F 1.0 3.0 9.0 27.0 + >>> initial = LArray([3, 4], [sex]) + >>> initial + sex M F + 3 4 + >>> sequence(year, initial, 1) + sex\\year 2016 2017 2018 2019 + M 3 4 5 6 + F 4 5 6 7 + >>> sequence(year, initial, mult=2) + sex\\year 2016 2017 2018 2019 + M 3 6 12 24 + F 4 8 16 32 + >>> sequence(year, initial, inc, mult) + sex\\year 2016 2017 2018 2019 + M 3 7 15 31 + F 4 14 44 134 + >>> def modify(prev_value): + ... return prev_value / 2 + >>> sequence(year, 8, func=modify) + year 2016 2017 2018 2019 + 8 4 2 1 + >>> sequence(3) + {0}* 0 1 2 + 0 1 2 + >>> sequence(X.year, axes=(sex, year)) + sex\\year 2016 2017 2018 2019 + M 0 1 2 3 + F 0 1 2 3 + + sequence can be used as the inverse of growth_rate: + + >>> a = LArray([1.0, 2.0, 3.0, 3.0], year) + >>> a + year 2016 2017 2018 2019 + 1.0 2.0 3.0 3.0 + >>> g = a.growth_rate() + 1 + >>> g + year 2017 2018 2019 + 2.0 1.5 1.0 + >>> sequence(year, a[2016], mult=g) + year 2016 2017 2018 2019 + 1.0 2.0 3.0 3.0 + """ + if inc is None: + inc = 1 if mult is 1 else 0 + + if axes is None: + if not isinstance(axis, Axis): + axis = _make_axis(axis) + + def strip_axes(col): + return get_axes(col) - axis + # we need to remove axis if present, because it might be incompatible + axes = strip_axes(initial) | strip_axes(inc) | strip_axes(mult) | axis + else: + axes = AxisCollection(axes) + axis = axes[axis] + res_dtype = np.dtype(common_type((initial, inc, mult))) + res = empty(axes, title=title, dtype=res_dtype) + res[axis.i[0]] = initial + def has_axis(a, axis): + return isinstance(a, LArray) and axis in a.axes + if func is not None: + for i in range(1, len(axis)): + res[axis.i[i]] = func(res[axis.i[i - 1]]) + elif has_axis(inc, axis) and has_axis(mult, axis): + # This case is more complicated to vectorize. It seems + # doable (probably by adding a fictive axis), but let us wait until + # someone requests it. The trick is to be able to write this: + # a[i] = initial * prod(mult[j]) + inc[1] * prod(mult[j]) + ... + # j=1..i j=2..i + # + inc[i-2] * prod(mult[j]) + inc[i-1] * mult[i] + inc[i] + # j=i-1..i + + # a[0] = initial + # a[1] = initial * mult[1] + # + inc[1] + # a[2] = initial * mult[1] * mult[2] + # + inc[1] * mult[2] + # + inc[2] + # a[3] = initial * mult[1] * mult[2] * mult[3] + # + inc[1] * mult[2] * mult[3] + # + inc[2] * mult[3] + # + inc[3] + # a[4] = initial * mult[1] * mult[2] * mult[3] * mult[4] + # + inc[1] * mult[2] * mult[3] * mult[4] + # + inc[2] * mult[3] * mult[4] + # + inc[3] * mult[4] + # + inc[4] + + # a[1:] = initial * cumprod(mult[1:]) + ... + def index_if_exists(a, axis, i): + if isinstance(a, LArray) and axis in a.axes: + a_axis = a.axes[axis] + return a[a_axis[axis.labels[i]]] + else: + return a + for i in range(1, len(axis)): + i_mult = index_if_exists(mult, axis, i) + i_inc = index_if_exists(inc, axis, i) + res[axis.i[i]] = res[axis.i[i - 1]] * i_mult + i_inc + else: + # TODO: use cumprod and cumsum to avoid the explicit loop + # it is easy for constant inc OR constant mult. + # it is easy for array inc OR array mult. + # it is a bit more complicated for constant inc AND constant mult + # + # it gets hairy for array inc AND array mult. It seems doable but let us wait until someone requests it. + def array_or_full(a, axis, initial): + dt = common_type((a, initial)) + r = empty((get_axes(a) - axis) | axis, title=title, dtype=dt) + r[axis.i[0]] = initial + if isinstance(a, LArray) and axis in a.axes: + # not using axis.i[1:] because a could have less ticks + # on axis than axis + r[axis.i[1:]] = a[axis[axis.labels[1]:]] + else: + r[axis.i[1:]] = a + return r + + if isinstance(initial, LArray) and np.isscalar(inc): + inc = full_like(initial, inc) + + # inc only (integer scalar) + if np.isscalar(mult) and mult == 1 and np.isscalar(inc) and res_dtype.kind == 'i': + # stop is not included + stop = initial + inc * len(axis) + data = np.arange(initial, stop, inc) + res[:] = LArray(data, axis) + # inc only (other scalar) + elif np.isscalar(mult) and mult == 1 and np.isscalar(inc): + # stop is included + stop = initial + inc * (len(axis) - 1) + data = np.linspace(initial, stop=stop, num=len(axis)) + res[:] = LArray(data, axis) + # inc only (array) + elif np.isscalar(mult) and mult == 1: + inc_array = array_or_full(inc, axis, initial) + res[axis.i[1:]] = inc_array.cumsum(axis)[axis.i[1:]] + # mult only (scalar or array) + elif np.isscalar(inc) and inc == 0: + mult_array = array_or_full(mult, axis, initial) + res[axis.i[1:]] = mult_array.cumprod(axis)[axis.i[1:]] + # both inc and mult defined but scalars or axis not present + else: + mult_array = array_or_full(mult, axis, 1.0) + cum_mult = mult_array.cumprod(axis)[axis.i[1:]] + res[axis.i[1:]] = ((1 - cum_mult) / (1 - mult)) * inc + initial * cum_mult + return res + +create_sequential = renamed_to(sequence, 'create_sequential') + +@_check_axes_argument +def ndrange(axes, start=0, title='', dtype=int): + import warnings + warnings.warn("ndrange() is deprecated. Use sequence() or ndtest() instead.", FutureWarning, stacklevel=2) + return ndtest(axes, start=start, title=title, dtype=dtype) + + +@_check_axes_argument +def ndtest(shape_or_axes, start=0, label_start=0, title='', dtype=int): + """Returns test array with given shape. + + Axes are named by single letters starting from 'a'. + Axes labels are constructed using a '{axis_name}{label_pos}' pattern (e.g. 'a0'). + Values start from `start` increase by steps of 1. + + Parameters + ---------- + shape_or_axes : int, tuple/list of int, str, single axis or tuple/list/AxisCollection of axes + If int or tuple/list of int, represents the shape of the array to create. + In that case, default axes are generated. + If string, it is used to generate axes (see :py:class:`AxisCollection` constructor). + start : int or float, optional + Start value + label_start : int, optional + Label index for each axis is `label_start + position`. `label_start` defaults to 0. + title : str, optional + Title. + dtype : type or np.dtype, optional + Type of resulting array. + + Returns + ------- + LArray + + Examples + -------- + Create test array by passing a shape + + >>> ndtest(6) + a a0 a1 a2 a3 a4 a5 + 0 1 2 3 4 5 + >>> ndtest((2, 3)) + a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + >>> ndtest((2, 3), label_start=1) + a\\b b1 b2 b3 + a1 0 1 2 + a2 3 4 5 + >>> ndtest((2, 3), start=2) + a\\b b0 b1 b2 + a0 2 3 4 + a1 5 6 7 + >>> ndtest((2, 3), dtype=float) + a\\b b0 b1 b2 + a0 0.0 1.0 2.0 + a1 3.0 4.0 5.0 + + Create test array by passing axes + + >>> ndtest("nat=BE,FO;sex=M,F") + nat\\sex M F + BE 0 1 + FO 2 3 + >>> nat = Axis("nat=BE,FO") + >>> sex = Axis("sex=M,F") + >>> ndtest([nat, sex]) + nat\\sex M F + BE 0 1 + FO 2 3 + """ + # XXX: try to come up with a syntax where start is before "end". + # For ndim > 1, I cannot think of anything nice. + if isinstance(shape_or_axes, int): + shape_or_axes = (shape_or_axes,) + if isinstance(shape_or_axes, (list, tuple)) and all([isinstance(i, int) for i in shape_or_axes]): + # TODO: move this to a class method on AxisCollection + assert len(shape_or_axes) <= 26 + axes_names = [chr(ord('a') + i) for i in range(len(shape_or_axes))] + label_ranges = [range(label_start, label_start + length) for length in shape_or_axes] + shape_or_axes = [Axis(['{}{}'.format(name, i) for i in label_range], name) + for name, label_range in zip(axes_names, label_ranges)] + if isinstance(shape_or_axes, AxisCollection): + axes = shape_or_axes + else: + axes = AxisCollection(shape_or_axes) + data = np.arange(start, start + axes.size, dtype=dtype).reshape(axes.shape) + return LArray(data, axes, title=title) + + +def kth_diag_indices(shape, k): + indices = np.diag_indices(min(shape), ndim=len(shape)) + if len(shape) == 2 and k != 0: + rows, cols = indices + if k < 0: + return rows[-k:], cols[:k] + elif k > 0: + return rows[:-k], cols[k:] + elif k != 0: + raise NotImplementedError("k != 0 and len(axes) != 2") + else: + return indices + + +def diag(a, k=0, axes=(0, 1), ndim=2, split=True): + """ + Extracts a diagonal or construct a diagonal array. + + Parameters + ---------- + a : LArray + If `a` has 2 dimensions or more, return a copy of its `k`-th diagonal. + If `a` has 1 dimension, return an array with `ndim` dimensions on the `k`-th diagonal. + k : int, optional + Offset of the diagonal from the main diagonal. Can be positive or negative. Defaults to main diagonal (0). + axes : tuple or list or AxisCollection of axes references, optional + Axes along which the diagonals should be taken. Use None for all axes. Defaults to the first two axes (0, 1). + ndim : int, optional + Target number of dimensions when constructing a diagonal array from an array without axes names/labels. + Defaults to 2. + split : bool, optional + Whether or not to try to split the axis name and labels + + Returns + ------- + LArray + The extracted diagonal or constructed diagonal array. + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> a = ndtest([nat, sex], start=1) + >>> a + nat\\sex M F + BE 1 2 + FO 3 4 + >>> d = diag(a) + >>> d + nat_sex BE_M FO_F + 1 4 + >>> diag(d) + nat\\sex M F + BE 1 0 + FO 0 4 + >>> a = ndtest(sex, start=1) + >>> a + sex M F + 1 2 + >>> diag(a) + sex\\sex M F + M 1 0 + F 0 2 + """ + if a.ndim == 1: + axis = a.axes[0] + axis_name = axis.name + if k != 0: + raise NotImplementedError("k != 0 not supported for 1D arrays") + if split and isinstance(axis_name, str) and '_' in axis_name: + axes_names = axis_name.split('_') + axes_labels = list(zip(*np.char.split(axis.labels, '_'))) + axes = [Axis(labels, name) for labels, name in zip(axes_labels, axes_names)] + else: + axes = [axis] + [axis.copy() for _ in range(ndim - 1)] + res = zeros(axes, dtype=a.dtype) + diag_indices = kth_diag_indices(res.shape, k) + res.ipoints[diag_indices] = a + return res + else: + if k != 0 and len(axes) > 2: + raise NotImplementedError("k != 0 and len(axes) > 2") + if axes is None: + axes = a.axes + else: + axes = a.axes[axes] + axes_indices = kth_diag_indices(axes.shape, k) + indexer = tuple(axis.i[indices] for axis, indices in zip(axes, axes_indices)) + return a.points[indexer] + + +@_check_axes_argument +def labels_array(axes, title=''): + """Returns an array with specified axes and the combination of + corresponding labels as values. + + Parameters + ---------- + axes : Axis or collection of Axis + title : str, optional + Title. + + Returns + ------- + LArray + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> labels_array(sex) + sex M F + M F + >>> labels_array((nat, sex)) + nat sex\\axis nat sex + BE M BE M + BE F BE F + FO M FO M + FO F FO F + """ + # >>> labels_array((nat, sex)) + # nat\\sex M F + # BE BE,M BE,F + # FO FO,M FO,F + axes = AxisCollection(axes) + if len(axes) > 1: + res_axes = axes + Axis(axes.names, 'axis') + res_data = np.empty(res_axes.shape, dtype=object) + res_data.flat[:] = list(product(*axes.labels)) + # XXX: I wonder if it wouldn't be better to return LGroups or a similar object which would display as "a,b" but + # where each label is stored separately. + # flat_data = np.array([p for p in product(*axes.labels)]) + # res_data = flat_data.reshape(axes.shape) + else: + res_axes = axes + res_data = axes[0].labels + return LArray(res_data, res_axes, title) + + +def identity(axis): + raise NotImplementedError("identity(axis) is deprecated. In most cases, you can now use the axis directly. " + "For example, 'identity(age) < 10' can be replaced by 'age < 10'. " + "In other cases, you should use labels_array(axis) instead.") + + +def eye(rows, columns=None, k=0, title='', dtype=None): + """Returns a 2-D array with ones on the diagonal and zeros elsewhere. + + Parameters + ---------- + rows : int or Axis + Rows of the output. + columns : int or Axis, optional + Columns of the output. If None, defaults to rows. + k : int, optional + Index of the diagonal: 0 (the default) refers to the main diagonal, a positive value refers to an upper + diagonal, and a negative value to a lower diagonal. + title : str, optional + Title. + dtype : data-type, optional + Data-type of the returned array. Defaults to float. + + Returns + ------- + LArray of shape (rows, columns) + An array where all elements are equal to zero, except for the k-th diagonal, whose values are equal to one. + + Examples + -------- + >>> eye(2, dtype=int) + {0}*\\{1}* 0 1 + 0 1 0 + 1 0 1 + >>> sex = Axis('sex=M,F') + >>> eye(sex) + sex\\sex M F + M 1.0 0.0 + F 0.0 1.0 + >>> age = Axis('age=0..2') + >>> eye(age, sex) + age\\sex M F + 0 1.0 0.0 + 1 0.0 1.0 + 2 0.0 0.0 + >>> eye(3, k=1) + {0}*\\{1}* 0 1 2 + 0 0.0 1.0 0.0 + 1 0.0 0.0 1.0 + 2 0.0 0.0 0.0 + """ + if columns is None: + columns = rows.copy() if isinstance(rows, Axis) else rows + axes = AxisCollection([rows, columns]) + shape = axes.shape + data = np.eye(shape[0], shape[1], k, dtype) + return LArray(data, axes, title) + + +# XXX: we could change the syntax to use *args +# => less punctuation but forces kwarg +# => potentially longer +# => unsure for now. The most important point is that it should be consistent with other functions. +# stack(a1, a2, axis=Axis('M,F', 'sex')) +# stack(('M', a1), ('F', a2), axis='sex') +# stack(a1, a2, axis='sex') + +# on Python 3.6, we could do something like (it would make from_lists obsolete for 1D arrays): +# stack('sex', M=1, F=2) + +# which is almost equivalent to: + +# stack(M=1, F=2, axis='sex') + +# but we cannot support the current syntax unmodified AND the first version, but second version we could. + +# we would only have to explain that they cannot do: + +# stack(0=1, 1=2, axis='age') +# stack(0A=1, 1B=2, axis='code') + +# but should use this instead: + +# stack({0: 1, 1: 2}, 'age=0,1') +# stack({'0A': 1, '1B': 2}, 'code=0A,1B') + +# stack({0: 1, 1: 2}, age) +# stack({'0A': 1, '1B': 2}, code) + +# or this, if we decide to support *args instead: + +# stack((0, 1), (1, 2), axis='age') +# stack(('0A', 1), ('1B', 2), axis='code') + +# stack(M=1, F=2, axis='sex') + +# is much nicer than: + +# from_lists(['sex', 'M', 'F'], +# [ '', 1, 2]) + +# for 2D arrays, from_lists and stack would be mostly as ugly and for 3D+ from_lists stays nicer even though I still do +# not like it much. + +# stack('nationality', +# BE=stack('sex', M=0, F=1), +# FR=stack('sex', M=2, F=3), +# DE=stack('sex', M=4, F=5)) +# +# from_lists([['nationality\\sex', 'M', 'F'], +# [ 'BE', 0, 1], +# [ 'FR', 2, 3], +# [ 'DE', 4, 5]]) + +# SUPER SLOPPY (I hate this, but I bet users would like it): + +# stack(BE_M=0, BE_F=1, +# FR_M=2, FR_F=3, +# DE_M=4, DE_F=5, axis='nationality_sex') + +# stack(('nationality', 'sex'), { +# ('BE', 'M'): 0, ('BE', 'F'): 1, +# ('FR', 'M'): 2, ('FR', 'F'): 3, +# ('DE', 'M'): 4, ('DE', 'F'): 5}) + +def stack(elements=None, axis=None, title='', **kwargs): + """ + Combines several arrays or sessions along an axis. + + Parameters + ---------- + elements : tuple, list or dict. + Elements to stack. Elements can be scalars, arrays, sessions, (label, value) pairs or a {label: value} mapping. + In the later case, axis must be defined and cannot be a name only, because we need to have labels order, + which the mapping does not provide. + + Stacking sessions will return a new session containing the arrays of all sessions stacked together. An array + missing in a session will be replaced by NaN. + axis : str or Axis or Group, optional + Axis to create. If None, defaults to a range() axis. + title : str, optional + Title. + + Returns + ------- + LArray + A single array combining arrays. + + Examples + -------- + >>> nat = Axis('nat=BE,FO') + >>> sex = Axis('sex=M,F') + >>> arr1 = ones(sex) + >>> arr1 + sex M F + 1.0 1.0 + >>> arr2 = zeros(sex) + >>> arr2 + sex M F + 0.0 0.0 + + In the case the axis to create has already been defined in a variable (Axis or Group) + + >>> stack({'BE': arr1, 'FO': arr2}, nat) + sex\\nat BE FO + M 1.0 0.0 + F 1.0 0.0 + >>> all_nat = Axis('nat=BE,DE,FR,NL,UK') + >>> stack({'BE': arr1, 'DE': arr2}, all_nat[:'DE']) + sex\\nat BE DE + M 1.0 0.0 + F 1.0 0.0 + + Otherwise (when one wants to create an axis from scratch), any of these syntaxes works: + + >>> stack([arr1, arr2], 'nat=BE,FO') + sex\\nat BE FO + M 1.0 0.0 + F 1.0 0.0 + >>> stack({'BE': arr1, 'FO': arr2}, 'nat=BE,FO') + sex\\nat BE FO + M 1.0 0.0 + F 1.0 0.0 + >>> stack([('BE', arr1), ('FO', arr2)], 'nat=BE,FO') + sex\\nat BE FO + M 1.0 0.0 + F 1.0 0.0 + + When stacking arrays with different axes, the result has the union of all axes present: + + >>> stack({'BE': arr1, 'FO': 0}, nat) + sex\\nat BE FO + M 1.0 0.0 + F 1.0 0.0 + + Creating an axis without name nor labels can be done using: + + >>> stack((arr1, arr2)) + sex\\{1}* 0 1 + M 1.0 0.0 + F 1.0 0.0 + + When labels are "simple" strings (ie no integers, no string starting with integers, etc.), using keyword + arguments can be an attractive alternative. + + >>> stack(FO=arr2, BE=arr1, axis=nat) + sex\\nat BE FO + M 1.0 0.0 + F 1.0 0.0 + + Without passing an explicit order for labels (or an axis object like above), it should only be used on Python 3.6 + or later because keyword arguments are NOT ordered on earlier Python versions. + + >>> # use this only on Python 3.6 and later + >>> stack(BE=arr1, FO=arr2, axis='nat') # doctest: +SKIP + sex\\nat BE FO + M 1.0 0.0 + F 1.0 0.0 + + To stack sessions, let us first create two test sessions. For example suppose we have a session storing the results + of a baseline simulation: + + >>> from larray import Session + >>> baseline = Session([('arr1', arr1), ('arr2', arr2)]) + + and another session with a variant (here we simply added 0.5 to each array) + + >>> variant = Session([('arr1', arr1 + 0.5), ('arr2', arr2 + 0.5)]) + + then we stack them together + + >>> stacked = stack([('baseline', baseline), ('variant', variant)], 'sessions') + >>> stacked + Session(arr1, arr2) + >>> stacked.arr1 + sex\sessions baseline variant + M 1.0 1.5 + F 1.0 1.5 + >>> stacked.arr2 + sex\sessions baseline variant + M 0.0 0.5 + F 0.0 0.5 + """ + from larray import Session + + if isinstance(axis, str) and '=' in axis: + axis = Axis(axis) + if isinstance(axis, Group): + axis = Axis(axis) + if elements is None: + if not isinstance(axis, Axis) and sys.version_info[:2] < (3, 6): + raise TypeError("axis argument should provide label order when using keyword arguments on Python < 3.6") + elements = kwargs.items() + elif kwargs: + raise TypeError("stack() accept either keyword arguments OR a collection of elements, not both") + + if isinstance(axis, Axis) and all(isinstance(e, tuple) for e in elements): + assert all(len(e) == 2 for e in elements) + elements = {k: v for k, v in elements} + + if isinstance(elements, LArray): + if axis is None: + axis = -1 + axis = elements.axes[axis] + values = [elements[k] for k in axis] + elif isinstance(elements, dict): + assert isinstance(axis, Axis) + values = [elements[v] for v in axis.labels] + elif isinstance(elements, Iterable): + if not isinstance(elements, Sequence): + elements = list(elements) + + if all(isinstance(e, tuple) for e in elements): + assert all(len(e) == 2 for e in elements) + keys = [k for k, v in elements] + values = [v for k, v in elements] + assert all(np.isscalar(k) for k in keys) + # this case should already be handled + assert not isinstance(axis, Axis) + # axis should be None or str + axis = Axis(keys, axis) + else: + values = elements + if axis is None or isinstance(axis, basestring): + axis = Axis(len(elements), axis) + else: + assert len(axis) == len(elements) + else: + raise TypeError('unsupported type for arrays: %s' % type(elements).__name__) + + if any(isinstance(v, Session) for v in values): + sessions = values + if not all(isinstance(s, Session) for s in sessions): + raise TypeError("stack() only supports stacking Session with other Session objects") + + seen = set() + all_keys = [] + for s in sessions: + unique_list(s.keys(), all_keys, seen) + res = [] + for name in all_keys: + try: + stacked = stack([s.get(name, np.nan) for s in sessions], axis=axis) + # TypeError for str arrays, ValueError for incompatible axes, ... + except Exception: + stacked = np.nan + res.append((name, stacked)) + return Session(res) + else: + # XXX : use concat? + result_axes = AxisCollection.union(*[get_axes(v) for v in values]) + result_axes.append(axis) + result = empty(result_axes, title=title, dtype=common_type(values)) + for k, v in zip(axis, values): + result[k] = v + return result + + +def get_axes(value): + return value.axes if isinstance(value, LArray) else AxisCollection([]) + + +def _strip_shape(shape): + return tuple(s for s in shape if s != 1) + + +def _equal_modulo_len1(shape1, shape2): + return _strip_shape(shape1) == _strip_shape(shape2) + + +# assigning a temporary name to anonymous axes before broadcasting and removing it afterwards is not a good idea after +# all because it copies the axes/change the object, and thus "flatten" wouldn't work with index axes: +# a[ones(a.axes[axes], dtype=bool)] +# but if we had assigned axes names from the start (without dropping them) this wouldn't be a problem. +def make_numpy_broadcastable(values): + """ + Returns values where LArrays are (NumPy) broadcastable between them. + For that to be possible, all common axes must be compatible (see Axis class documentation). + Extra axes (in any array) can have any length. + + * the resulting arrays will have the combination of all axes found in the input arrays, the earlier arrays defining + the order of axes. Axes with labels take priority over wildcard axes. + * length 1 wildcard axes will be added for axes not present in input + + Parameters + ---------- + values : iterable of arrays + Arrays that requires to be (NumPy) broadcastable between them. + + Returns + ------- + list of arrays + List of arrays broadcastable between them. Arrays will have the combination of all axes found in the input + arrays, the earlier arrays defining the order of axes. + AxisCollection + Collection of axes of all input arrays. + + See Also + -------- + Axis.iscompatible : tests if axes are compatible between them. + """ + all_axes = AxisCollection.union(*[get_axes(v) for v in values]) + return [v.broadcast_with(all_axes) if isinstance(v, LArray) else v + for v in values], all_axes + + +_default_float_error_handler = float_error_handler_factory(3) + + +original_float_error_settings = np.seterr(divide='call', invalid='call') +original_float_error_handler = np.seterrcall(_default_float_error_handler) + +# excel IO tools in Python +# - openpyxl: the slowest but most-complete package but still lags behind PHPExcel from which it was ported. despite +# the drawbacks the API is very complete. +# biggest drawbacks: +# * you can get either the "cached" value of cells OR their formulas but NOT BOTH and this is a file-wide setting +# (data_only=True). if you have an excel file and want to add a sheet to it, you either loose all cached values +# (which is problematic in many cases since you do not necessarily have linked files) or loose all formulas. +# * it loose "charts" on read. => cannot append/update a sheet to a file with charts, which is precisely what many +# users asked. => users need to create their charts using code. +# - xlsxwriter: faster and slightly more feature-complete than openpyxl regarding writing but does not read anything +# => cannot update an existing file. API seems extremely complete. +# - pyexcelerate: yet faster but also write only. Didn't check whether API is more featured than xlsxwriter or not. +# - xlwings: wraps win32com & equivalent on mac, so can potentially do everything (I guess) but this is SLOW and needs +# a running excel instance, etc. diff --git a/larray/core/axis.py b/larray/core/axis.py new file mode 100644 index 000000000..00587fd7f --- /dev/null +++ b/larray/core/axis.py @@ -0,0 +1,2654 @@ +# -*- coding: utf8 -*- +from __future__ import absolute_import, division, print_function + +import re +import sys +import warnings +from itertools import product + +import numpy as np + +from larray.core.abstractbases import ABCAxis, ABCAxisReference, ABCLArray +from larray.core.expr import ExprNode +from larray.core.group import (Group, LGroup, IGroup, IGroupMaker, _to_tick, _to_ticks, _to_key, _seq_summary, + _contain_group_ticks, _seq_group_to_name) +from larray.util.oset import * +from larray.util.misc import (basestring, PY2, unicode, long, duplicates, array_lookup2, ReprString, index_by_id, + renamed_to, common_type) + +__all__ = ['Axis', 'AxisCollection', 'X', 'x'] + + +class Axis(ABCAxis): + """ + Represents an axis. It consists of a name and a list of labels. + + Parameters + ---------- + labels : array-like or int + collection of values usable as labels, i.e. numbers or strings or the size of the axis. + In the last case, a wildcard axis is created. + name : str or Axis, optional + name of the axis or another instance of Axis. In the second case, the name of the other axis is simply copied. + By default None. + + Attributes + ---------- + labels : array-like or int + collection of values usable as labels, i.e. numbers or strings + name : str + name of the axis. None in the case of an anonymous axis. + + Examples + -------- + >>> gender = Axis(['M', 'F'], 'gender') + >>> gender + Axis(['M', 'F'], 'gender') + >>> gender.name + 'gender' + >>> list(gender.labels) + ['M', 'F'] + + using a string definition + + >>> gender = Axis('gender=M,F') + >>> gender + Axis(['M', 'F'], 'gender') + >>> age = Axis('age=0..9') + >>> age + Axis([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 'age') + >>> code = Axis('code=A,C..E,F..G,Z') + >>> code + Axis(['A', 'C', 'D', 'E', 'F', 'G', 'Z'], 'code') + + a wildcard axis only needs a length + + >>> row = Axis(10, 'row') + >>> row + Axis(10, 'row') + >>> row.labels + array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + + axes can also be defined without name + + >>> anonymous = Axis('0..4') + >>> anonymous + Axis([0, 1, 2, 3, 4], None) + """ + # ticks instead of labels? + def __init__(self, labels, name=None): + if isinstance(labels, Group) and name is None: + name = labels.axis + if isinstance(name, Axis): + name = name.name + if isinstance(labels, basestring): + if '=' in labels: + name, labels = [o.strip() for o in labels.split('=')] + elif '..' not in labels and ',' not in labels: + warnings.warn("Arguments 'name' and 'labels' of Axis constructor have been inverted in " + "version 0.22 of larray. Please check you are passing labels first and name " + "as second argument.", FutureWarning, stacklevel=2) + name, labels = labels, name + + # make sure we do not have np.str_ as it causes problems down the + # line with xlwings. Cannot use isinstance to check that though. + is_python_str = type(name) is unicode or type(name) is bytes + assert name is None or isinstance(name, int) or is_python_str, type(name) + self.name = name + self._labels = None + self.__mapping = None + self.__sorted_keys = None + self.__sorted_values = None + self._length = None + self._iswildcard = False + self.labels = labels + + @property + def _mapping(self): + # To map labels with their positions + mapping = self.__mapping + if mapping is None: + labels = self._labels + # TODO: this would be more efficient for wildcard axes but does not work in all cases + # mapping = labels + mapping = {label: i for i, label in enumerate(labels)} + if not self._iswildcard: + # we have no choice but to do that, otherwise we could not make geo['Brussels'] work efficiently + # (we could have to traverse the whole mapping checking for each name, which is not an option) + # TODO: only do this if labels.dtype is object, or add "contains_lgroup" flag in above code + # (if any(...)) + mapping.update({label.name: i for i, label in enumerate(labels) if isinstance(label, Group)}) + self.__mapping = mapping + return mapping + + def _update_key_values(self): + mapping = self._mapping + if mapping: + sorted_keys, sorted_values = tuple(zip(*sorted(mapping.items()))) + else: + sorted_keys, sorted_values = (), () + keys, values = np.array(sorted_keys), np.array(sorted_values) + self.__sorted_keys = keys + self.__sorted_values = values + return keys, values + + @property + def _sorted_keys(self): + if self.__sorted_keys is None: + keys, _ = self._update_key_values() + return self.__sorted_keys + + @property + def _sorted_values(self): + values = self.__sorted_values + if values is None: + _, values = self._update_key_values() + return values + + @property + def i(self): + """ + Allows to define a subset using positions along the axis + instead of labels. + + Examples + -------- + >>> from larray import ndtest + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> arr = ndtest([sex, time]) + >>> arr + sex\\time 2007 2008 2009 2010 + M 0 1 2 3 + F 4 5 6 7 + >>> arr[time.i[0, -1]] + sex\\time 2007 2010 + M 0 3 + F 4 7 + """ + return IGroupMaker(self) + + @property + def labels(self): + """ + labels of the axis. + """ + return self._labels + + @labels.setter + def labels(self, labels): + if labels is None: + raise TypeError("labels should be a sequence or a single int") + if isinstance(labels, (int, long)): + length = labels + labels = np.arange(length) + iswildcard = True + else: + labels = _to_ticks(labels, parse_single_int=True) + length = len(labels) + iswildcard = False + + self._length = length + self._labels = labels + self._iswildcard = iswildcard + + def by(self, length, step=None): + """Split axis into several groups of specified length. + + Parameters + ---------- + length : int + length of groups + step : int, optional + step between groups. Defaults to length. + + Notes + ----- + step can be smaller than length, in which case, this will produce overlapping groups. + + Returns + ------- + list of Group + + Examples + -------- + >>> age = Axis(range(10), 'age') + >>> age.by(3) + (age.i[0:3], age.i[3:6], age.i[6:9], age.i[9:10]) + >>> age.by(3, 4) + (age.i[0:3], age.i[4:7], age.i[8:10]) + >>> age.by(5, 3) + (age.i[0:5], age.i[3:8], age.i[6:10], age.i[9:10]) + """ + return self[:].by(length, step) + + def extend(self, labels): + """ + Append new labels to an axis or increase its length in case of wildcard axis. + Note that `extend` does not occur in-place: a new axis object is allocated, filled and returned. + + Parameters + ---------- + labels : int, iterable or Axis + New labels to append to the axis. Passing directly another Axis is also possible. + If the current axis is a wildcard axis, passing a length is enough. + + Returns + ------- + Axis + A copy of the axis with new labels appended to it or with increased length (if wildcard). + + Examples + -------- + >>> time = Axis([2007, 2008], 'time') + >>> time + Axis([2007, 2008], 'time') + >>> time.extend([2009, 2010]) + Axis([2007, 2008, 2009, 2010], 'time') + >>> waxis = Axis(10, 'wildcard_axis') + >>> waxis + Axis(10, 'wildcard_axis') + >>> waxis.extend(5) + Axis(15, 'wildcard_axis') + >>> waxis.extend([11, 12, 13, 14]) + Traceback (most recent call last): + ... + ValueError: Axis to append must (not) be wildcard if self is (not) wildcard + """ + other = labels if isinstance(labels, Axis) else Axis(labels) + if self.iswildcard != other.iswildcard: + raise ValueError ("Axis to append must (not) be wildcard if self is (not) wildcard") + labels = self._length + other._length if self.iswildcard else np.append(self.labels, other.labels) + return Axis(labels, self.name) + + def split(self, sep='_', names=None, regex=None, return_labels=False): + """Split axis and returns a list of Axis. + + Parameters + ---------- + sep : str, optional + Delimiter to use for splitting. Defaults to '_'. + When `regex` is provided, the delimiter is only used on `names` if given as one string or on axis name if + `names` is None. + names : str or list of str, optional + Names of resulting axes. Defaults to None. + regex : str, optional + Use regex instead of delimiter to split labels. Defaults to None. + labels : bool, optional + Whether or not split labels must be returned (as a tuple of tuples). These labels are suitable for indexing + via array.points[labels]. Defaults to False. + + Returns + ------- + list of Axis or (list of Axis, array-like) + + Examples + -------- + >>> a_b = Axis('a_b=a0_b0,a0_b1,a0_b2,a1_b0,a1_b1,a1_b2') + >>> a_b.split() + [Axis(['a0', 'a1'], 'a'), Axis(['b0', 'b1', 'b2'], 'b')] + """ + if names is None: + if sep not in self.name: + raise ValueError('{} not found in self name ({})'.format(sep, self.name)) + else: + names = self.name.split(sep) + elif isinstance(names, str): + if sep not in names: + raise ValueError('{} not found in names ({})'.format(sep, names)) + else: + names = names.split(sep) + else: + assert all(isinstance(name, str) for name in names) + if not regex: + # np.char.split does not work on arrays with object dtype + labels = self.labels if self.labels.dtype.kind != 'O' else self.labels.astype(str) + # gives us an array of lists + split_labels = np.char.split(labels, sep) + else: + match = re.compile(regex).match + split_labels = [match(l).groups() for l in self.labels] + indexing_labels = zip(*split_labels) + if return_labels: + indexing_labels = tuple(indexing_labels) + # not using np.unique because we want to keep the original order + split_axes = [Axis(unique_list(ax_labels), name) for ax_labels, name in zip(indexing_labels, names)] + if return_labels: + indexing_labels = tuple(axis[labels] for axis, labels in zip(split_axes, indexing_labels)) + return split_axes, indexing_labels + else: + return split_axes + + def insert(self, new_labels, before=None, after=None): + """ + Return a new axis with `new_labels` inserted before `before` or after `after`. + + Parameters + ---------- + new_labels : scalar, tuple/list/array of scalars, Group or Axis + New label(s) to append to the axis. + before : scalar or Group, optional + Label or group before which to insert `new_labels`. + after : scalar or Group, optional + Label or group after which to insert `new_labels`. + + Returns + ------- + Axis + A copy of the axis with the new labels inserted. + + Examples + -------- + >>> time = Axis([2007, 2009], 'time') + >>> time.insert(2008, before=2009) + Axis([2007, 2008, 2009], 'time') + >>> time.insert(2008, after=2007) + Axis([2007, 2008, 2009], 'time') + >>> time.insert(2008, before=time.i[1]) + Axis([2007, 2008, 2009], 'time') + >>> time.insert(2008, after=time.i[0]) + Axis([2007, 2008, 2009], 'time') + >>> b = Axis(['b1', 'b2'], 'b') + >>> b.insert('b1.5', before='b2') + Axis(['b1', 'b1.5', 'b2'], 'b') + >>> b.insert(['b1.1', 'b1.2'], before='b2') + Axis(['b1', 'b1.1', 'b1.2', 'b2'], 'b') + >>> c = Axis(['c1', 'c2'], 'c') + >>> b.insert(c, before='b2') + Axis(['b1', 'c1', 'c2', 'b2'], 'b') + """ + if sum([before is not None, after is not None]) != 1: + raise ValueError("must specify exactly one of before or after") + if before is not None: + before = self.index(before) + else: + assert after is not None + before = self.index(after) + 1 + + if isinstance(new_labels, Axis): + new_labels = new_labels.labels + elif isinstance(new_labels, Group): + new_labels = new_labels.eval() + else: + if np.isscalar(new_labels): + new_labels = [new_labels] + new_labels = np.asarray(new_labels) + + current_labels = self.labels + labels_type = common_type((current_labels, new_labels)) + if labels_type is object: + # astype always copies, while asarray only copies if necessary + current_labels = np.asarray(current_labels, dtype=object) + new_labels = np.asarray(new_labels, dtype=object) + + # not using np.insert to avoid inserted string labels being truncated (because of current_labels.dtype) + res_labels = np.concatenate((current_labels[:before], new_labels, current_labels[before:])) + return Axis(res_labels, self.name) + + @property + def iswildcard(self): + return self._iswildcard + + def _group(self, *args, **kwargs): + """ + Deprecated. + + Parameters + ---------- + *args + (collection of) selected label(s) to form a group. + **kwargs + name of the group. There is no other accepted keywords. + + Examples + -------- + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> odd_years = time._group([2007, 2009], name='odd_years') + >>> odd_years + time[2007, 2009] >> 'odd_years' + """ + name = kwargs.pop('name', None) + if kwargs: + raise ValueError("invalid keyword argument(s): %s" % list(kwargs.keys())) + key = args[0] if len(args) == 1 else args + return self[key] >> name if name else self[key] + + def group(self, *args, **kwargs): + group_name = kwargs.pop('name', None) + key = args[0] if len(args) == 1 else args + syntax = '{}[{}]'.format(self.name if self.name else 'axis', key) + if group_name is not None: + syntax += ' >> {}'.format(repr(group_name)) + raise NotImplementedError('Axis.group is deprecated. Use {} instead.'.format(syntax)) + + def all(self, name=None): + """ + (Deprecated) Returns a group containing all labels. + + Parameters + ---------- + name : str, optional + Name of the group. If not provided, name is set to 'all'. + """ + axis_name = self.name if self.name else 'axis' + group_name = name if name else 'all' + raise NotImplementedError('Axis.all is deprecated. Use {}[:] >> {} instead.' + .format(axis_name, repr(group_name))) + + def subaxis(self, key, name=None): + """ + Returns an axis for a sub-array. + + Parameters + ---------- + key : int, or collection (list, slice, array, LArray) of them + Position(s) of labels to use for the new axis. + name : str, optional + Name of the subaxis. Defaults to the name of the parent axis. + + Returns + ------- + Axis + Subaxis. If key is a None slice and name is None, the original Axis is returned. + If key is a LArray, the list of axes is returned. + + Examples + -------- + >>> age = Axis(range(100), 'age') + >>> age.subaxis(range(10, 19), 'teenagers') + Axis([10, 11, 12, 13, 14, 15, 16, 17, 18], 'teenagers') + """ + if name is None and isinstance(key, slice) and key.start is None and key.stop is None and key.step is None: + return self + # we must NOT modify the axis name, even though this creates a new axis that is independent from the original + # one because the original name is probably what users will want to use to filter + if name is None: + name = self.name + if isinstance(key, ABCLArray): + return tuple(key.axes) + # TODO: compute length for wildcard axes more efficiently + labels = len(self.labels[key]) if self.iswildcard else self.labels[key] + return Axis(labels, name) + + def iscompatible(self, other): + """ + Checks if self is compatible with another axis. + + * Two non-wildcard axes are compatible if they have the same name and labels. + * A wildcard axis of length 1 is compatible with any other axis sharing the same name. + * A wildcard axis of length > 1 is compatible with any axis of the same length or length 1 and sharing the + same name. + + Parameters + ---------- + other : Axis + Axis to compare with. + + Returns + ------- + bool + True if input axis is compatible with self, False otherwise. + + Examples + -------- + >>> a10 = Axis(range(10), 'a') + >>> wa10 = Axis(10, 'a') + >>> wa1 = Axis(1, 'a') + >>> b10 = Axis(range(10), 'b') + >>> a10.iscompatible(b10) + False + >>> a10.iscompatible(wa10) + True + >>> a10.iscompatible(wa1) + True + >>> wa1.iscompatible(b10) + False + """ + if self is other: + return True + if not isinstance(other, Axis): + return False + if self.name is not None and other.name is not None and self.name != other.name: + return False + if self.iswildcard or other.iswildcard: + # wildcard axes of length 1 match with anything + # wildcard axes of length > 1 match with equal len or len 1 + return len(self) == 1 or len(other) == 1 or len(self) == len(other) + else: + return np.array_equal(self.labels, other.labels) + + def equals(self, other): + """ + Checks if self is equal to another axis. + Two axes are equal if they have the same name and label(s). + + Parameters + ---------- + other : Axis + Axis to compare with. + + Returns + ------- + bool + True if input axis is equal to self, False otherwise. + + Examples + -------- + >>> age = Axis(range(5), 'age') + >>> age_2 = Axis(5, 'age') + >>> age_3 = Axis(range(5), 'young children') + >>> age_4 = Axis([0, 1, 2, 3, 4], 'age') + >>> age.equals(age_2) + False + >>> age.equals(age_3) + False + >>> age.equals(age_4) + True + """ + if self is other: + return True + + # this might need to change if we ever support wildcard axes with real labels + return isinstance(other, Axis) and self.name == other.name and self.iswildcard == other.iswildcard and \ + (len(self) == len(other) if self.iswildcard else np.array_equal(self.labels, other.labels)) + + def matching(self, pattern): + """ + Returns a group with all the labels matching the specified pattern (regular expression). + + Parameters + ---------- + pattern : str or Group + Regular expression (regex). + + Returns + ------- + LGroup + Group containing all the labels matching the pattern. + + Notes + ----- + See `Regular Expression `_ + for more details about how to build a pattern. + + Examples + -------- + >>> people = Axis(['Bruce Wayne', 'Bruce Willis', 'Waldo', 'Arthur Dent', 'Harvey Dent'], 'people') + + All labels starting with "W" and ending with "o" are given by + + >>> people.matching('W.*o') + people['Waldo'] + + All labels not containing character "a" + + >>> people.matching('[^a]*$') + people['Bruce Willis', 'Arthur Dent'] + """ + if isinstance(pattern, Group): + pattern = pattern.eval() + rx = re.compile(pattern) + return LGroup([v for v in self.labels if rx.match(v)], axis=self) + + matches = renamed_to(matching, 'matches') + + def startingwith(self, prefix): + """ + Returns a group with the labels starting with the specified string. + + Parameters + ---------- + prefix : str or Group + The prefix to search for. + + Returns + ------- + LGroup + Group containing all the labels starting with the given string. + + Examples + -------- + >>> people = Axis(['Bruce Wayne', 'Bruce Willis', 'Waldo', 'Arthur Dent', 'Harvey Dent'], 'people') + >>> people.startingwith('Bru') + people['Bruce Wayne', 'Bruce Willis'] + """ + if isinstance(prefix, Group): + prefix = prefix.eval() + return LGroup([v for v in self.labels if v.startswith(prefix)], axis=self) + + startswith = renamed_to(startingwith, 'startswith') + + def endingwith(self, suffix): + """ + Returns a group with the labels ending with the specified string. + + Parameters + ---------- + suffix : str or Group + The suffix to search for. + + Returns + ------- + LGroup + Group containing all the labels ending with the given string. + + Examples + -------- + >>> people = Axis(['Bruce Wayne', 'Bruce Willis', 'Waldo', 'Arthur Dent', 'Harvey Dent'], 'people') + >>> people.endingwith('Dent') + people['Arthur Dent', 'Harvey Dent'] + """ + if isinstance(suffix, Group): + suffix = suffix.eval() + return LGroup([v for v in self.labels if v.endswith(suffix)], axis=self) + + endswith = renamed_to(endingwith, 'endswith') + + def containing(self, substring): + """ + Returns a group with all the labels containing the specified substring. + + Parameters + ---------- + substring : str or Group + The substring to search for. + + Returns + ------- + LGroup + Group containing all the labels containing the substring. + + Examples + -------- + >>> people = Axis(['Bruce Wayne', 'Bruce Willis', 'Arthur Dent'], 'people') + >>> people.containing('Will') + people['Bruce Willis'] + """ + if isinstance(substring, Group): + substring = substring.eval() + return LGroup([v for v in self.labels if substring in v], axis=self) + + def __len__(self): + return self._length + + def __iter__(self): + return iter([self.i[i] for i in range(self._length)]) + + def __getitem__(self, key): + """ + Returns a group (list or unique element) of label(s) usable in .sum or .filter + + key is a label-based key (other axis, slice and fancy indexing are supported) + + Returns + ------- + Group + group containing selected label(s)/position(s). + + Notes + ----- + key is label-based (slice and fancy indexing are supported) + """ + # if isinstance(key, basestring): + # key = to_keys(key) + + def isscalar(k): + return np.isscalar(k) or (isinstance(k, Group) and np.isscalar(k.key)) + + if isinstance(key, Axis): + key = key.labels + + # the not all(np.isscalar) part is necessary to support axis[a, b, c] and axis[[a, b, c]] + if isinstance(key, (tuple, list)) and not all(isscalar(k) for k in key): + # this creates a group for each key if it wasn't and retargets IGroup + list_res = [self[k] for k in key] + return list_res if isinstance(key, list) else tuple(list_res) + + name = key.name if isinstance(key, Group) else None + return LGroup(key, name, self) + + def _ipython_key_completions_(self): + return list(self.labels) + + def __contains__(self, key): + # TODO: ideally, _to_tick shouldn't be necessary, the __hash__ and __eq__ of Group should include this + return _to_tick(key) in self._mapping + + def __hash__(self): + return id(self) + + def _is_key_type_compatible(self, key): + key_kind = np.dtype(type(key)).kind + label_kind = self.labels.dtype.kind + # on Python2, ascii-only unicode string can match byte strings (and vice versa), so we shouldn't be more picky + # here than dict hashing + str_key = key_kind in ('S', 'U') + str_label = label_kind in ('S', 'U') + py2_str_match = PY2 and str_key and str_label + # object kind can match anything + return key_kind == label_kind or key_kind == 'O' or label_kind == 'O' or py2_str_match + + def index(self, key, bool_passthrough=True): + """ + Translates a label key to its numerical index counterpart. + + Parameters + ---------- + key : key + Everything usable as a key. + bool_passthrough : bool, optional + If set to True and key is a boolean vector, it is returned as it. + + Returns + ------- + (array of) int + Numerical index(ices) of (all) label(s) represented by the key + + Notes + ----- + Fancy index with boolean vectors are passed through unmodified + + Examples + -------- + >>> people = Axis(['John Doe', 'Bruce Wayne', 'Bruce Willis', 'Waldo', 'Arthur Dent', 'Harvey Dent'], 'people') + >>> people.index('Waldo') + 3 + >>> people.index(people.matching('Bruce')) + array([1, 2]) + """ + mapping = self._mapping + + if isinstance(key, Group) and key.axis is not self and key.axis is not None: + try: + # XXX: this is potentially very expensive if key.key is an array or list and should be tried as a last + # resort + potential_tick = _to_tick(key) + # avoid matching 0 against False or 0.0, note that None has object dtype and so always pass this test + if self._is_key_type_compatible(potential_tick): + return mapping[potential_tick] + # we must catch TypeError because key might not be hashable (eg slice) + # IndexError is for when mapping is an ndarray + except (KeyError, TypeError, IndexError): + pass + + if isinstance(key, basestring): + # try the key as-is to allow getting at ticks with special characters (",", ":", ...) + try: + # avoid matching 0 against False or 0.0, note that Group keys have object dtype and so always pass this + # test + if self._is_key_type_compatible(key): + return mapping[key] + # we must catch TypeError because key might not be hashable (eg slice) + # IndexError is for when mapping is an ndarray + except (KeyError, TypeError, IndexError): + pass + + # transform "specially formatted strings" for slices, lists, LGroup and IGroup to actual objects + key = _to_key(key) + + if not PY2 and isinstance(key, range): + key = list(key) + + if isinstance(key, IGroup): + assert key.axis is self + return key.key + + if isinstance(key, LGroup): + # this can happen when key was passed as a string and converted to an LGroup via _to_key + if isinstance(key.axis, basestring) and key.axis != self.name: + raise KeyError(key) + + # at this point we do not care about the axis nor the name + key = key.key + + if isinstance(key, slice): + start = mapping[key.start] if key.start is not None else None + # stop is inclusive in the input key and exclusive in the output ! + stop = mapping[key.stop] + 1 if key.stop is not None else None + return slice(start, stop, key.step) + # XXX: bool LArray do not pass through??? + elif isinstance(key, np.ndarray) and key.dtype.kind is 'b' and bool_passthrough: + return key + elif isinstance(key, (tuple, list, OrderedSet)): + # TODO: the result should be cached + # Note that this is faster than array_lookup(np.array(key), mapping) + res = np.empty(len(key), int) + try: + for i, label in enumerate(_seq_group_to_name(key)): + res[i] = mapping[label] + except KeyError: + for i, label in enumerate(key): + res[i] = mapping[label] + return res + elif isinstance(key, np.ndarray): + # handle fancy indexing with a ndarray of labels + # TODO: the result should be cached + # TODO: benchmark this against the tuple/list version above when mapping is large + # array_lookup is O(len(key) * log(len(mapping))) + # vs + # tuple/list version is O(len(key)) (dict.getitem is O(1)) + # XXX: we might want to special case dtype bool, because in that case the mapping will in most case be + # {False: 0, True: 1} or {False: 1, True: 0} and in those case key.astype(int) and (~key).astype(int) + # are MUCH faster + # see C:\Users\gdm\devel\lookup_methods.py and C:\Users\gdm\Desktop\lookup_methods.html + try: + return array_lookup2(_seq_group_to_name(key), self._sorted_keys, self._sorted_values) + except KeyError: + return array_lookup2(key, self._sorted_keys, self._sorted_values) + elif isinstance(key, ABCLArray): + from .array import LArray + return LArray(self.index(key.data), key.axes) + else: + # the first mapping[key] above will cover most cases. + # This code path is only used if the key was given in "non normalized form" + assert np.isscalar(key), "%s (%s) is not scalar" % (key, type(key)) + # key is scalar (integer, float, string, ...) + if self._is_key_type_compatible(key): + return mapping[key] + else: + # print("diff dtype", ) + raise KeyError(key) + + translate = renamed_to(index, 'translate') + + # FIXME: remove id + @property + def id(self): + if self.name is not None: + return self.name + else: + raise ValueError('Axis has no name, so no id') + + def __str__(self): + name = str(self.name) if self.name is not None else '{?}' + return (name + '*') if self.iswildcard else name + + def __repr__(self): + labels = len(self) if self.iswildcard else list(self.labels) + return 'Axis(%r, %r)' % (labels, self.name) + + def labels_summary(self): + """ + Returns a short representation of the labels. + + Examples + -------- + >>> Axis(100, 'age').labels_summary() + '0 1 2 ... 97 98 99' + """ + def repr_on_strings(v): + return repr(v) if isinstance(v, str) else str(v) + return _seq_summary(self.labels, repr_func=repr_on_strings) + + # method factory + def _binop(opname): + """ + Method factory to create binary operators special methods. + """ + fullname = '__%s__' % opname + + def opmethod(self, other): + # give a chance to AxisCollection.__rXXX__ ops to trigger + if isinstance(other, AxisCollection): + # in this case it is indeed return NotImplemented, not raise NotImplementedError! + return NotImplemented + + from .array import labels_array + self_array = labels_array(self) + if isinstance(other, Axis): + other = labels_array(other) + return getattr(self_array, fullname)(other) + opmethod.__name__ = fullname + return opmethod + + __lt__ = _binop('lt') + __le__ = _binop('le') + __eq__ = _binop('eq') + __ne__ = _binop('ne') + __gt__ = _binop('gt') + __ge__ = _binop('ge') + __add__ = _binop('add') + __radd__ = _binop('radd') + __sub__ = _binop('sub') + __rsub__ = _binop('rsub') + __mul__ = _binop('mul') + __rmul__ = _binop('rmul') + if sys.version < '3': + __div__ = _binop('div') + __rdiv__ = _binop('rdiv') + __truediv__ = _binop('truediv') + __rtruediv__ = _binop('rtruediv') + __floordiv__ = _binop('floordiv') + __rfloordiv__ = _binop('rfloordiv') + __mod__ = _binop('mod') + __rmod__ = _binop('rmod') + __divmod__ = _binop('divmod') + __rdivmod__ = _binop('rdivmod') + __pow__ = _binop('pow') + __rpow__ = _binop('rpow') + __lshift__ = _binop('lshift') + __rlshift__ = _binop('rlshift') + __rshift__ = _binop('rshift') + __rrshift__ = _binop('rrshift') + __and__ = _binop('and') + __rand__ = _binop('rand') + __xor__ = _binop('xor') + __rxor__ = _binop('rxor') + __or__ = _binop('or') + __ror__ = _binop('ror') + __matmul__ = _binop('matmul') + + def __larray__(self): + """ + Returns axis as LArray. + """ + from .array import labels_array + return labels_array(self) + + def copy(self): + """ + Returns a copy of the axis. + """ + new_axis = Axis([], self.name) + # XXX: I wonder if we should make a copy of the labels + mapping. There should at least be an option. + new_axis._labels = self._labels + new_axis.__mapping = self.__mapping + new_axis._length = self._length + new_axis._iswildcard = self._iswildcard + new_axis.__sorted_keys = self.__sorted_keys + new_axis.__sorted_values = self.__sorted_values + return new_axis + + def replace(self, old, new=None): + """ + Returns a new axis with some labels replaced. + + Parameters + ---------- + old : any scalar (bool, int, str, ...), tuple/list/array of scalars, or a mapping. + the label(s) to be replaced. Old can be a mapping {old1: new1, old2: new2, ...} + new : any scalar (bool, int, str, ...) or tuple/list/array of scalars, optional + the new label(s). This is argument must not be used if old is a mapping. + + Returns + ------- + Axis + a new Axis with the old labels replaced by new labels. + + Examples + -------- + >>> sex = Axis('sex=M,F') + >>> sex + Axis(['M', 'F'], 'sex') + >>> sex.replace('M', 'Male') + Axis(['Male', 'F'], 'sex') + >>> sex.replace({'M': 'Male', 'F': 'Female'}) + Axis(['Male', 'Female'], 'sex') + >>> sex.replace(['M', 'F'], ['Male', 'Female']) + Axis(['Male', 'Female'], 'sex') + """ + if isinstance(old, dict): + new = list(old.values()) + old = list(old.keys()) + elif np.isscalar(old): + assert new is not None and np.isscalar(new), "%s is not a scalar but a %s" % (new, type(new).__name__) + old = [old] + new = [new] + else: + seq = (tuple, list, np.ndarray) + assert isinstance(old, seq), "%s is not a sequence but a %s" % (old, type(old).__name__) + assert isinstance(new, seq), "%s is not a sequence but a %s" % (new, type(new).__name__) + assert len(old) == len(new) + # using object dtype because new labels length can be larger than the fixed str length in the self.labels array + labels = self.labels.astype(object) + indices = self.index(old) + labels[indices] = new + return Axis(labels, self.name) + + # XXX: rename to named like Group? + def rename(self, name): + """ + Renames the axis. + + Parameters + ---------- + name : str + the new name for the axis. + + Returns + ------- + Axis + a new Axis with the same labels but a different name. + + Examples + -------- + >>> sex = Axis('sex=M,F') + >>> sex + Axis(['M', 'F'], 'sex') + >>> sex.rename('gender') + Axis(['M', 'F'], 'gender') + """ + res = self.copy() + if isinstance(name, Axis): + name = name.name + res.name = name + return res + + def _rename(self, name): + raise TypeError("Axis._rename is deprecated, use Axis.rename instead") + + def union(self, other): + """Returns axis with the union of this axis labels and other labels. + + Labels relative order will be kept intact, but only unique labels will be returned. Labels from this axis will + be before labels from other. + + Parameters + ---------- + other : Axis or any sequence of labels + other labels + + Returns + ------- + Axis + + Examples + -------- + >>> a = Axis('a=a0..a2') + >>> a.union('a1') + Axis(['a0', 'a1', 'a2'], 'a') + >>> a.union('a3') + Axis(['a0', 'a1', 'a2', 'a3'], 'a') + >>> a.union(Axis('a=a1..a3')) + Axis(['a0', 'a1', 'a2', 'a3'], 'a') + >>> a.union('a1..a3') + Axis(['a0', 'a1', 'a2', 'a3'], 'a') + >>> a.union(['a1', 'a2', 'a3']) + Axis(['a0', 'a1', 'a2', 'a3'], 'a') + """ + if isinstance(other, basestring): + # TODO : remove [other] if ... when FuturWarning raised in Axis.init will be removed + other = _to_ticks(other, parse_single_int=True) if '..' in other or ',' in other else [other] + if isinstance(other, Axis): + other = other.labels + unique_labels = [] + seen = set() + unique_list(self.labels, unique_labels, seen) + unique_list(other, unique_labels, seen) + return Axis(unique_labels, self.name) + + def intersection(self, other): + """Returns axis with the (set) intersection of this axis labels and other labels. + + In other words, this will use labels from this axis if they are also in other. Labels relative order will be + kept intact. + + Parameters + ---------- + other : Axis or any sequence of labels + other labels + + Returns + ------- + Axis + + Examples + -------- + >>> a = Axis('a=a0..a2') + >>> a.intersection('a1') + Axis(['a1'], 'a') + >>> a.intersection('a3') + Axis([], 'a') + >>> a.intersection(Axis('a=a1..a3')) + Axis(['a1', 'a2'], 'a') + >>> a.intersection('a1..a3') + Axis(['a1', 'a2'], 'a') + >>> a.intersection(['a1', 'a2', 'a3']) + Axis(['a1', 'a2'], 'a') + """ + if isinstance(other, basestring): + # TODO : remove [other] if ... when FuturWarning raised in Axis.init will be removed + other = _to_ticks(other, parse_single_int=True) if '..' in other or ',' in other else [other] + if isinstance(other, Axis): + other = other.labels + to_keep = set(other) + return Axis([l for l in self.labels if l in to_keep], self.name) + + def difference(self, other): + """Returns axis with the (set) difference of this axis labels and other labels. + + In other words, this will use labels from this axis if they are not in other. Labels relative order will be + kept intact. + + Parameters + ---------- + other : Axis or any sequence of labels + other labels + + Returns + ------- + Axis + + Examples + -------- + >>> a = Axis('a=a0..a2') + >>> a.difference('a1') + Axis(['a0', 'a2'], 'a') + >>> a.difference('a3') + Axis(['a0', 'a1', 'a2'], 'a') + >>> a.difference(Axis('a=a1..a3')) + Axis(['a0'], 'a') + >>> a.difference('a1..a3') + Axis(['a0'], 'a') + >>> a.difference(['a1', 'a2', 'a3']) + Axis(['a0'], 'a') + """ + if isinstance(other, basestring): + # TODO : remove [other] if ... when FuturWarning raised in Axis.init will be removed + other = _to_ticks(other, parse_single_int=True) if '..' in other or ',' in other else [other] + if isinstance(other, Axis): + other = other.labels + to_drop = set(other) + return Axis([l for l in self.labels if l not in to_drop], self.name) + + def align(self, other, join='outer'): + """Align axis with other object using specified join method. + + Parameters + ---------- + other : Axis or label sequence + join : {'outer', 'inner', 'left', 'right'}, optional + Defaults to 'outer'. + + Returns + ------- + Axis + Aligned axis + + See Also + -------- + LArray.align + + Examples + -------- + >>> axis1 = Axis('a=a0..a2') + >>> axis2 = Axis('a=a1..a3') + >>> axis1.align(axis2) + Axis(['a0', 'a1', 'a2', 'a3'], 'a') + >>> axis1.align(axis2, join='inner') + Axis(['a1', 'a2'], 'a') + >>> axis1.align(axis2, join='left') + Axis(['a0', 'a1', 'a2'], 'a') + >>> axis1.align(axis2, join='right') + Axis(['a1', 'a2', 'a3'], 'a') + """ + assert join in {'outer', 'inner', 'left', 'right'} + if join == 'outer': + return self.union(other) + elif join == 'inner': + return self.intersection(other) + elif join == 'left': + return self + elif join == 'right': + if not isinstance(other, Axis): + other = Axis(other) + return other + + +def _make_axis(obj): + if isinstance(obj, Axis): + return obj + elif isinstance(obj, tuple): + assert len(obj) == 2 + labels, name = obj + return Axis(labels, name) + elif isinstance(obj, Group): + return Axis(obj.eval(), obj.axis) + else: + # int, str, list, ndarray + return Axis(obj) + + +# not using OrderedDict because it does not support indices-based getitem +# not using namedtuple because we have to know the fields in advance (it is a one-off class) and we need more +# functionality than just a named tuple +class AxisCollection(object): + """ + Represents a collection of axes. + + Parameters + ---------- + axes : sequence of Axis or int or tuple or str, optional + An axis can be given as an Axis object, an int or a + tuple (labels, name) or a string of the kind + 'name=label_1,label_2,label_3'. + + Raises + ------ + ValueError + Cannot have multiple occurrences of the same axis object in a collection. + + Notes + ----- + Multiple occurrences of the same axis object is not allowed. + However, several axes with the same name are allowed but this is not recommended. + + Examples + -------- + >>> age = Axis(range(10), 'age') + >>> AxisCollection([3, age, (['M', 'F'], 'sex'), 'time = 2007, 2008, 2009, 2010']) + AxisCollection([ + Axis(3, None), + Axis([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 'age'), + Axis(['M', 'F'], 'sex'), + Axis([2007, 2008, 2009, 2010], 'time') + ]) + >>> AxisCollection('age=0..9; sex=M,F; time=2007..2010') + AxisCollection([ + Axis([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 'age'), + Axis(['M', 'F'], 'sex'), + Axis([2007, 2008, 2009, 2010], 'time') + ]) + """ + def __init__(self, axes=None): + if axes is None: + axes = [] + elif isinstance(axes, (int, long, Group, Axis)): + axes = [axes] + elif isinstance(axes, str): + axes = [axis.strip() for axis in axes.split(';')] + + axes = [_make_axis(axis) for axis in axes] + assert all(isinstance(a, Axis) for a in axes) + # check for duplicate axes + dupe_axes = list(duplicates(axes)) + if dupe_axes: + axis = dupe_axes[0] + raise ValueError("Cannot have multiple occurrences of the same axis object in a collection ('%s' -- %s "\ + "with id %d). Several axes with the same name are allowed though (but not recommended)." + % (axis.name, axis.labels_summary(), id(axis))) + self._list = axes + self._map = {axis.name: axis for axis in axes if axis.name is not None} + + # # check dupes on each axis + # for axis in axes: + # axis_dupes = list(duplicates(axis.labels)) + # if axis_dupes: + # dupe_labels = ', '.join(str(l) for l in axis_dupes) + # warnings.warn("duplicate labels found for axis %s: %s" % (axis.name, dupe_labels), + # category=UserWarning, stacklevel=2) + # + # # check dupes between axes. Using unique to not spot the dupes within the same axis that we just displayed. + # all_labels = chain(*[np.unique(axis.labels) for axis in axes]) + # dupe_labels = list(duplicates(all_labels)) + # if dupe_labels: + # label_axes = [(label, ', '.join(display_name for axis, display_name in zip(axes, self.display_names) + # if label in axis)) + # for label in dupe_labels] + # dupes = '\n'.join("{} is valid in {{{}}}".format(label, axes) for label, axes in label_axes) + # warnings.warn("ambiguous labels found:\n%s" % dupes, category=UserWarning, stacklevel=5) + + def __dir__(self): + # called by dir() and tab-completion at the interactive prompt, must return a list of any valid getattr key. + # dir() takes care of sorting but not uniqueness, so we must ensure that. + names = set(axis.name for axis in self._list if axis.name is not None) + return list(set(dir(self.__class__)) | names) + + def __iter__(self): + return iter(self._list) + + def __getattr__(self, key): + try: + return self._map[key] + except KeyError: + return self.__getattribute__(key) + + # needed to make *un*pickling work (because otherwise, __getattr__ is called before _map exists, which leads to + # an infinite recursion) + def __getstate__(self): + return self.__dict__ + + def __setstate__(self, d): + self.__dict__ = d + + def __getitem__(self, key): + if isinstance(key, Axis): + try: + key = self.index(key) + # transform ValueError to KeyError + except ValueError: + if key.name is None: + raise KeyError("axis '%s' not found in %s" % (key, self)) + else: + # we should NOT check that the object is the same, so that we can use AxisReference objects to + # target real axes + key = key.name + + if isinstance(key, int): + return self._list[key] + elif isinstance(key, (tuple, list)): + if any(axis is Ellipsis for axis in key): + ellipsis_idx = index_by_id(key, Ellipsis) + # going through lists (instead of doing self[key[:ellipsis_idx]] to avoid problems with anonymous axes + before_ellipsis = [self[k] for k in key[:ellipsis_idx]] + after_ellipsis = [self[k] for k in key[ellipsis_idx + 1:]] + ellipsis_axes = list(self - before_ellipsis - after_ellipsis) + return AxisCollection(before_ellipsis + ellipsis_axes + after_ellipsis) + # XXX: also use get_by_pos if tuple/list of Axis? + return AxisCollection([self[k] for k in key]) + elif isinstance(key, AxisCollection): + return AxisCollection([self.get_by_pos(k, i) + for i, k in enumerate(key)]) + elif isinstance(key, slice): + return AxisCollection(self._list[key]) + elif key is None: + raise KeyError("axis '%s' not found in %s" % (key, self)) + else: + assert isinstance(key, basestring), type(key) + if key in self._map: + return self._map[key] + else: + raise KeyError("axis '%s' not found in %s" % (key, self)) + + def _ipython_key_completions_(self): + return list(self._map.keys()) + + # XXX: I wonder if this whole positional crap should really be part of AxisCollection or the default behavior. + # It could either be moved to make_numpy_broadcastable or made non default + def get_by_pos(self, key, i): + """ + Returns axis corresponding to a key, or to position i if the key has no name and key object not found. + + Parameters + ---------- + key : key + Key corresponding to an axis. + i : int + Position of the axis (used only if search by key failed). + + Returns + ------- + Axis + Axis corresponding to the key or the position i. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> col = AxisCollection([age, sex, time]) + >>> col.get_by_pos('sex', 1) + Axis(['M', 'F'], 'sex') + """ + if isinstance(key, Axis) and key.name is None: + try: + # try by object + return self[key] + except KeyError: + if i in self: + res = self[i] + if res.iscompatible(key): + return res + else: + raise ValueError("axis %s is not compatible with %s" % (res, key)) + # XXX: KeyError instead? + raise ValueError("axis %s not found in %s" % (key, self)) + else: + return self[key] + + def __setitem__(self, key, value): + if isinstance(key, slice): + assert isinstance(value, (tuple, list, AxisCollection)) + + def slice_bound(bound): + if bound is None or isinstance(bound, int): + # out of bounds integer bounds are allowed in slice setitem so we cannot use .index + return bound + else: + return self.index(bound) + start_idx = slice_bound(key.start) + # XXX: we might want to make the stop bound inclusive, which makes more sense for label bounds (but + # prevents inserts via setitem) + stop_idx = slice_bound(key.stop) + old = self._list[start_idx:stop_idx:key.step] + for axis in old: + if axis.name is not None: + del self._map[axis.name] + for axis in value: + if axis.name is not None: + self._map[axis.name] = axis + self._list[start_idx:stop_idx:key.step] = value + elif isinstance(key, (tuple, list, AxisCollection)): + assert isinstance(value, (tuple, list, AxisCollection)) + if len(key) != len(value): + raise ValueError('must have as many old axes as new axes') + for k, v in zip(key, value): + self[k] = v + else: + if not isinstance(value, Axis): + value = Axis(value) + idx = self.index(key) + step = 1 if idx >= 0 else -1 + self[idx:idx + step:step] = [value] + + def __delitem__(self, key): + if isinstance(key, slice): + self[key] = [] + else: + idx = self.index(key) + axis = self._list.pop(idx) + if axis.name is not None: + del self._map[axis.name] + + def union(self, *args, **kwargs): + validate = kwargs.pop('validate', True) + replace_wildcards = kwargs.pop('replace_wildcards', True) + result = self[:] + for a in args: + if not isinstance(a, AxisCollection): + a = AxisCollection(a) + result.extend(a, validate=validate, replace_wildcards=replace_wildcards) + return result + __or__ = union + __add__ = union + + def __radd__(self, other): + result = AxisCollection(other) + result.extend(self) + return result + + def __and__(self, other): + """ + Returns the intersection of this collection and other. + """ + if not isinstance(other, AxisCollection): + other = AxisCollection(other) + + # XXX: add iscompatible when matching by position? + # TODO: move this to a class method (possibly private) so that we are sure we use same heuristic than in .extend + def contains(col, i, axis): + return axis in col or (axis.name is None and i in col) + + return AxisCollection([axis for i, axis in enumerate(self) if contains(other, i, axis)]) + + def __eq__(self, other): + """ + Other collection compares equal if all axes compare equal and in the same order. Works with a list. + """ + if self is other: + return True + if not isinstance(other, list): + other = list(other) + return len(self._list) == len(other) and all(a.equals(b) for a, b in zip(self._list, other)) + + # for python2, we need to define it explicitly + def __ne__(self, other): + return not self == other + + def __contains__(self, key): + if isinstance(key, int): + return -len(self) <= key < len(self) + elif isinstance(key, Axis): + # the special case is just a performance optimization to avoid scanning through the whole list + if key.name is not None: + return key.name in self._map + else: + try: + self.index(key) + return True + except ValueError: + return False + # key can be anything, it should just return False in case of weird types + return key in self._map + + def isaxis(self, value): + """ + Tests if input is an Axis object or the name of an axis contained in self. + + Parameters + ---------- + value : Axis or str + Input axis or string + + Returns + ------- + bool + True if input is an Axis object or the name of an axis contained in the current AxisCollection instance, + False otherwise. + + Examples + -------- + >>> a = Axis('a=a0,a1') + >>> b = Axis('b=b0,b1') + >>> col = AxisCollection([a, b]) + >>> col.isaxis(a) + True + >>> col.isaxis('b') + True + >>> col.isaxis('c') + False + """ + # this is tricky. 0 and 1 can be both axes indices and axes ticks. + # not sure what's worse: + # 1) disallow aggregates(axis_num): users could still use arr.sum(arr.axes[0]) + # we could also provide an explicit kwarg (ie this would effectively forbid having an axis named "axis"). + # arr.sum(axis=0). I think this is the sanest option. The error message in case we use it without the + # keyword needs to be clearer though. + return isinstance(value, Axis) or (isinstance(value, basestring) and value in self) + # 2) slightly inconsistent API: allow aggregate over single labels if they are string, but not int + # arr.sum(0) would sum on the first axis, but arr.sum('M') would + # sum a single tick. I don't like this option. + # 3) disallow single tick aggregates. Single labels make little sense in the context of an aggregate, + # but you don't always know/want to differenciate the code in that case anyway. + # It would be annoying for e.g. Brussels + # 4) give priority to axes, + # arr.sum(0) would sum on the first axis but arr.sum(5) would + # sum a single tick (assuming there is a int axis and less than six axes). + # return value in self + + def __len__(self): + return len(self._list) + ndim = property(__len__) + + def __str__(self): + return "{%s}" % ', '.join(self.display_names) + + def __repr__(self): + axes_repr = (repr(axis) for axis in self._list) + return "AxisCollection([\n %s\n])" % ',\n '.join(axes_repr) + + def get(self, key, default=None, name=None): + """ + Returns axis corresponding to key. If not found, the argument `name` is used to create a new Axis. + If `name` is None, the `default` axis is then returned. + + Parameters + ---------- + key : key + Key corresponding to an axis of the current AxisCollection. + default : axis, optional + Default axis to return if key doesn't correspond to any axis of the collection and argument `name` is None. + name : str, optional + If key doesn't correspond to any axis of the collection, a new Axis with this name is created and returned. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> col = AxisCollection([age, time]) + >>> col.get('time') + Axis([2007, 2008, 2009, 2010], 'time') + >>> col.get('sex', sex) + Axis(['M', 'F'], 'sex') + >>> col.get('nb_children', None, 'nb_children') + Axis(1, 'nb_children') + """ + # XXX: use if key in self? + try: + return self[key] + except KeyError: + if name is None: + return default + else: + return Axis(1, name) + + def get_all(self, key): + """ + Returns all axes from key if present and length 1 wildcard axes otherwise. + + Parameters + ---------- + key : AxisCollection + + Returns + ------- + AxisCollection + + Raises + ------ + AssertionError + Raised if the input key is not an AxisCollection object. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> city = Axis(['London', 'Paris', 'Rome'], 'city') + >>> col = AxisCollection([age, sex, time]) + >>> col2 = AxisCollection([age, city, time]) + >>> col.get_all(col2) + AxisCollection([ + Axis([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 'age'), + Axis(1, 'city'), + Axis([2007, 2008, 2009, 2010], 'time') + ]) + """ + assert isinstance(key, AxisCollection) + + def get_pos_default(k, i): + try: + return self.get_by_pos(k, i) + except (ValueError, KeyError): + # XXX: is having i as name really helps? + if len(k) == 1: + return k + else: + return Axis(1, k.name if k.name is not None else i) + + return AxisCollection([get_pos_default(k, i) for i, k in enumerate(key)]) + + def keys(self): + """ + Returns list of all axis names. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> AxisCollection([age, sex, time]).keys() + ['age', 'sex', 'time'] + """ + # XXX: include id/num for anonymous axes? I think I should + return [a.name for a in self._list] + + def pop(self, axis=-1): + """ + Removes and returns an axis. + + Parameters + ---------- + axis : key, optional + Axis to remove and return. Default value is -1 (last axis). + + Returns + ------- + Axis + If no argument is provided, the last axis is removed and returned. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> col = AxisCollection([age, sex, time]) + >>> col.pop('age') + Axis([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 'age') + >>> col + AxisCollection([ + Axis(['M', 'F'], 'sex'), + Axis([2007, 2008, 2009, 2010], 'time') + ]) + >>> col.pop() + Axis([2007, 2008, 2009, 2010], 'time') + """ + axis = self[axis] + del self[axis] + return axis + + def append(self, axis): + """ + Appends axis at the end of the collection. + + Parameters + ---------- + axis : Axis + Axis to append. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> col = AxisCollection([age, sex]) + >>> col.append(time) + >>> col + AxisCollection([ + Axis([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 'age'), + Axis(['M', 'F'], 'sex'), + Axis([2007, 2008, 2009, 2010], 'time') + ]) + """ + self[len(self):len(self)] = [axis] + + def check_compatible(self, axes): + """ + Checks if axes passed as argument are compatible with those contained in the collection. + Raises ValueError if not. + + See Also + -------- + Axis.iscompatible + """ + for i, axis in enumerate(axes): + local_axis = self.get_by_pos(axis, i) + if not local_axis.iscompatible(axis): + raise ValueError("incompatible axes:\n{!r}\nvs\n{!r}".format(axis, local_axis)) + + def extend(self, axes, validate=True, replace_wildcards=False): + """ + Extends the collection by appending the axes from `axes`. + + Parameters + ---------- + axes : sequence of Axis (list, tuple, AxisCollection) + validate : bool, optional + replace_wildcards : bool, optional + + Raises + ------ + TypeError + Raised if `axes` is not a sequence of Axis (list, tuple or AxisCollection) + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> col = AxisCollection(age) + >>> col.extend([sex, time]) + >>> col + AxisCollection([ + Axis([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 'age'), + Axis(['M', 'F'], 'sex'), + Axis([2007, 2008, 2009, 2010], 'time') + ]) + """ + # axes should be a sequence + if not isinstance(axes, (tuple, list, AxisCollection)): + raise TypeError("AxisCollection can only be extended by a sequence of Axis, not %s" % type(axes).__name__) + # check that common axes are the same + # if validate: + # self.check_compatible(axes) + + # TODO: factorize with get_by_pos + def get_axis(col, i, axis): + if axis in col: + return col[axis] + elif axis.name is None and i in col: + return col[i] + else: + return None + + for i, axis in enumerate(axes): + old_axis = get_axis(self, i, axis) + if old_axis is None: + # append axis + self[len(self):len(self)] = [axis] + # elif replace_wildcards and old_axis.iswildcard: + # self[old_axis] = axis + else: + # check that common axes are the same + if validate and not old_axis.iscompatible(axis): + raise ValueError("incompatible axes:\n%r\nvs\n%r" % (axis, old_axis)) + if replace_wildcards and old_axis.iswildcard: + self[old_axis] = axis + + def index(self, axis): + """ + Returns the index of axis. + + `axis` can be a name or an Axis object (or an index). If the Axis object itself exists in the list, index() + will return it. Otherwise, it will return the index of the local axis with the same name than the key (whether + it is compatible or not). + + Parameters + ---------- + axis : Axis or int or str + Can be the axis itself or its position (returned if represents a valid index) or its name. + + Returns + ------- + int + Index of the axis. + + Raises + ------ + ValueError + Raised if the axis is not present. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> col = AxisCollection([age, sex, time]) + >>> col.index(time) + 2 + >>> col.index('sex') + 1 + """ + if isinstance(axis, int): + if -len(self) <= axis < len(self): + return axis + else: + raise ValueError("axis %d is not in collection" % axis) + elif isinstance(axis, Axis): + try: + # 1) first look for that particular axis object + + # This avoids testing labels of each axis and makes sure the result is correct even if there are + # several axes with the same name and labels. + return index_by_id(self._list, axis) + except ValueError: + # 2) look for an axis with the same name and labels using axis.equals + + # This makes sure that if there are several axes with the same name but different labels, it returns + # the index of the one with the correct labels. This is especially important for anonymous axes but is + # also useful for other axes. Note that this shouldn't be too slow as labels will only be actually + # checked if the name match. + + # We cannot use self._list.index because it use Axis.__eq__ which produces an LArray + for i, item in enumerate(self._list): + if item.equals(axis): + return i + + # 3) otherwise look for any axis with the same name + name = axis.name + else: + name = axis + if name is None: + raise ValueError("%r is not in collection" % axis) + return self.names.index(name) + + # XXX: we might want to return a new AxisCollection (same question for other inplace operations: + # append, extend, pop, __delitem__, __setitem__) + def insert(self, index, axis): + """ + Inserts axis before index. + + Parameters + ---------- + index : int + position of the inserted axis. + axis : Axis + axis to insert. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> col = AxisCollection([age, time]) + >>> col.insert(1, sex) + >>> col + AxisCollection([ + Axis([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 'age'), + Axis(['M', 'F'], 'sex'), + Axis([2007, 2008, 2009, 2010], 'time') + ]) + """ + self[index:index] = [axis] + + def copy(self): + """ + Returns a copy. + """ + return self[:] + + def replace(self, axes_to_replace=None, new_axis=None, inplace=False, **kwargs): + """Replace one, several or all axes of the collection. + + Parameters + ---------- + axes_to_replace : axis ref or dict {axis ref: axis} or list of tuple (axis ref, axis) \ + or list of Axis or AxisCollection, optional + Axes to replace. If a single axis reference is given, the `new_axis` argument must be provided. + If a list of Axis or an AxisCollection is given, all axes will be replaced by the new ones. + In that case, the number of new axes must match the number of the old ones. Defaults to None. + new_axis : axis ref, optional + New axis if `axes_to_replace` contains a single axis reference. Defaults to None. + inplace : bool, optional + Whether or not to modify the original object or return a new AxisCollection and leave the original intact. + Defaults to False. + **kwargs : Axis + New axis for each axis to replace given as a keyword argument. + + Returns + ------- + AxisCollection + AxisCollection with axes replaced. + + Examples + -------- + >>> from larray import ndtest + >>> axes = ndtest((2, 3)).axes + >>> axes + AxisCollection([ + Axis(['a0', 'a1'], 'a'), + Axis(['b0', 'b1', 'b2'], 'b') + ]) + >>> row = Axis(['r0', 'r1'], 'row') + >>> column = Axis(['c0', 'c1', 'c2'], 'column') + + Replace one axis (second argument `new_axis` must be provided) + + >>> axes.replace(X.a, row) # doctest: +SKIP + >>> # or + >>> axes.replace(X.a, "row=r0,r1") + AxisCollection([ + Axis(['r0', 'r1'], 'row'), + Axis(['b0', 'b1', 'b2'], 'b') + ]) + + Replace several axes (keywords, list of tuple or dictionary) + + >>> axes.replace(a=row, b=column) # doctest: +SKIP + >>> # or + >>> axes.replace(a="row=r0,r1", b="column=c0,c1,c2") # doctest: +SKIP + >>> # or + >>> axes.replace([(X.a, row), (X.b, column)]) # doctest: +SKIP + >>> # or + >>> axes.replace({X.a: row, X.b: column}) + AxisCollection([ + Axis(['r0', 'r1'], 'row'), + Axis(['c0', 'c1', 'c2'], 'column') + ]) + + Replace all axes (list of axes or AxisCollection) + + >>> axes.replace([row, column]) + AxisCollection([ + Axis(['r0', 'r1'], 'row'), + Axis(['c0', 'c1', 'c2'], 'column') + ]) + >>> arr = ndtest([row, column]) + >>> axes.replace(arr.axes) + AxisCollection([ + Axis(['r0', 'r1'], 'row'), + Axis(['c0', 'c1', 'c2'], 'column') + ]) + """ + if not PY2 and isinstance(axes_to_replace, zip): + axes_to_replace = list(axes_to_replace) + + if isinstance(axes_to_replace, (list, AxisCollection)) and \ + all([isinstance(axis, Axis) for axis in axes_to_replace]): + if len(axes_to_replace) != len(self): + raise ValueError('{} axes given as argument, expected {}'.format(len(axes_to_replace), len(self))) + axes = axes_to_replace + else: + axes = self if inplace else self[:] + if isinstance(axes_to_replace, dict): + items = list(axes_to_replace.items()) + elif isinstance(axes_to_replace, list): + assert all([isinstance(item, tuple) and len(item) == 2 for item in axes_to_replace]) + items = axes_to_replace[:] + elif isinstance(axes_to_replace, (basestring, Axis, int)): + items = [(axes_to_replace, new_axis)] + else: + items = [] + items += kwargs.items() + for old, new in items: + axes[old] = new + if inplace: + return self + else: + return AxisCollection(axes) + + # XXX: kill this method? + def without(self, axes): + """ + Returns a new collection without some axes. + + You can use a comma separated list of names. + + Parameters + ---------- + axes : int, str, Axis or sequence of those + Axes to not include in the returned AxisCollection. + In case of string, axes are separated by a comma and no whitespace is accepted. + + Returns + ------- + AxisCollection + New collection without some axes. + + Notes + ----- + Set operation so axes can contain axes not present in self + + Examples + -------- + >>> age = Axis('age=0..5') + >>> sex = Axis('sex=M,F') + >>> time = Axis('time=2015..2017') + >>> col = AxisCollection([age, sex, time]) + >>> col.without([age, sex]) + AxisCollection([ + Axis([2015, 2016, 2017], 'time') + ]) + >>> col.without(0) + AxisCollection([ + Axis(['M', 'F'], 'sex'), + Axis([2015, 2016, 2017], 'time') + ]) + >>> col.without('sex,time') + AxisCollection([ + Axis([0, 1, 2, 3, 4, 5], 'age') + ]) + """ + return self - axes + + def __sub__(self, axes): + """ + See Also + -------- + without + """ + if isinstance(axes, basestring): + axes = axes.split(',') + elif isinstance(axes, (int, Axis)): + axes = [axes] + + # only keep indices (as this works for unnamed axes too) + to_remove = set(self.index(axis) for axis in axes if axis in self) + return AxisCollection([axis for i, axis in enumerate(self) if i not in to_remove]) + + def translate_full_key(self, key): + """ + Translates a label-based key to a positional key. + + Parameters + ---------- + key : tuple + A full label-based key. All dimensions must be present and in the correct order. + + Returns + ------- + tuple + A full positional key. + + See Also + -------- + Axis.translate + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> AxisCollection([age,sex,time]).translate_full_key((':', 'F', 2009)) + (slice(None, None, None), 1, 2) + """ + assert len(key) == len(self) + return tuple(axis.index(axis_key) for axis_key, axis in zip(key, self)) + + @property + def labels(self): + """ + Returns the list of labels of the axes. + + Returns + ------- + list + List of labels of the axes. + + Examples + -------- + >>> age = Axis(range(10), 'age') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> AxisCollection([age, time]).labels # doctest: +NORMALIZE_WHITESPACE + [array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), + array([2007, 2008, 2009, 2010])] + """ + return [axis.labels for axis in self._list] + + @property + def names(self): + """ + Returns the list of (raw) names of the axes. + + Returns + ------- + list + List of names of the axes. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> AxisCollection([age, sex, time]).names + ['age', 'sex', 'time'] + """ + return [axis.name for axis in self._list] + + @property + def display_names(self): + """ + Returns the list of (display) names of the axes. + + Returns + ------- + list + List of names of the axes. Wildcard axes are displayed with an attached \*. + Anonymous axes (name = None) are replaced by their position wrapped in braces. + + Examples + -------- + >>> a = Axis(['a1', 'a2'], 'a') + >>> b = Axis(2, 'b') + >>> c = Axis(['c1', 'c2']) + >>> d = Axis(3) + >>> AxisCollection([a, b, c, d]).display_names + ['a', 'b*', '{2}', '{3}*'] + """ + def display_name(i, axis): + name = axis.name if axis.name is not None else '{%d}' % i + return (name + '*') if axis.iswildcard else name + + return [display_name(i, axis) for i, axis in enumerate(self._list)] + + @property + def ids(self): + """ + Returns the list of ids of the axes. + + Returns + ------- + list + List of ids of the axes. + + See Also + -------- + axis_id + + Examples + -------- + >>> a = Axis(2, 'a') + >>> b = Axis(2) + >>> c = Axis(2, 'c') + >>> AxisCollection([a, b, c]).ids + ['a', 1, 'c'] + """ + return [axis.name if axis.name is not None else i + for i, axis in enumerate(self._list)] + + def axis_id(self, axis): + """ + Returns the id of an axis. + + Returns + ------- + str or int + Id of axis, which is its name if defined and its position otherwise. + + Examples + -------- + >>> a = Axis(2, 'a') + >>> b = Axis(2) + >>> c = Axis(2, 'c') + >>> col = AxisCollection([a, b, c]) + >>> col.axis_id(a) + 'a' + >>> col.axis_id(b) + 1 + >>> col.axis_id(c) + 'c' + """ + axis = self[axis] + return axis.name if axis.name is not None else self.index(axis) + + @property + def shape(self): + """ + Returns the shape of the collection. + + Returns + ------- + tuple + Tuple of lengths of axes. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> AxisCollection([age, sex, time]).shape + (20, 2, 4) + """ + return tuple(len(axis) for axis in self._list) + + @property + def size(self): + """ + Returns the size of the collection, i.e. + the number of elements of the array. + + Returns + ------- + int + Number of elements of the array. + + Examples + -------- + >>> age = Axis(range(20), 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> AxisCollection([age, sex, time]).size + 160 + """ + return np.prod(self.shape) + + @property + def info(self): + """ + Describes the collection (shape and labels for each axis). + + Returns + ------- + str + Description of the AxisCollection (shape and labels for each axis). + + Examples + -------- + >>> age = Axis(20, 'age') + >>> sex = Axis('sex=M,F') + >>> time = Axis([2007, 2008, 2009, 2010], 'time') + >>> AxisCollection([age, sex, time]).info + 20 x 2 x 4 + age* [20]: 0 1 2 ... 17 18 19 + sex [2]: 'M' 'F' + time [4]: 2007 2008 2009 2010 + """ + lines = [" %s [%d]: %s" % (name, len(axis), axis.labels_summary()) + for name, axis in zip(self.display_names, self._list)] + shape = " x ".join(str(s) for s in self.shape) + return ReprString('\n'.join([shape] + lines)) + + # XXX: instead of front_if_spread, we might want to require axes to be contiguous + # (ie the caller would have to transpose axes before calling this) + def combine_axes(self, axes=None, sep='_', wildcard=False, front_if_spread=False): + """Combine several axes into one. + + Parameters + ---------- + axes : tuple, list, AxisCollection of axes or list of combination of those or dict, optional + axes to combine. Tuple, list or AxisCollection will combine several axes into one. To chain several axes + combinations, pass a list of tuple/list/AxisCollection of axes. To set the name(s) of resulting axis(es), + use a {(axes, to, combine): 'new_axis_name'} dictionary. Defaults to all axes. + sep : str, optional + delimiter to use for combining. Defaults to '_'. + wildcard : bool, optional + whether or not to produce a wildcard axis even if the axes to combine are not. + This is much faster, but loose axes labels. + front_if_spread : bool, optional + whether or not to move the combined axis at the front (it will be the first axis) if the combined axes are + not next to each other. + + Returns + ------- + AxisCollection + New AxisCollection with combined axes. + + Examples + -------- + >>> axes = AxisCollection('a=a0,a1;b=b0..b2') + >>> axes + AxisCollection([ + Axis(['a0', 'a1'], 'a'), + Axis(['b0', 'b1', 'b2'], 'b') + ]) + >>> axes.combine_axes() + AxisCollection([ + Axis(['a0_b0', 'a0_b1', 'a0_b2', 'a1_b0', 'a1_b1', 'a1_b2'], 'a_b') + ]) + >>> axes.combine_axes(sep='/') + AxisCollection([ + Axis(['a0/b0', 'a0/b1', 'a0/b2', 'a1/b0', 'a1/b1', 'a1/b2'], 'a/b') + ]) + >>> axes += AxisCollection('c=c0..c2;d=d0,d1') + >>> axes.combine_axes(('a', 'c')) + AxisCollection([ + Axis(['a0_c0', 'a0_c1', 'a0_c2', 'a1_c0', 'a1_c1', 'a1_c2'], 'a_c'), + Axis(['b0', 'b1', 'b2'], 'b'), + Axis(['d0', 'd1'], 'd') + ]) + >>> axes.combine_axes({('a', 'c'): 'ac'}) + AxisCollection([ + Axis(['a0_c0', 'a0_c1', 'a0_c2', 'a1_c0', 'a1_c1', 'a1_c2'], 'ac'), + Axis(['b0', 'b1', 'b2'], 'b'), + Axis(['d0', 'd1'], 'd') + ]) + + # make several combinations at once + + >>> axes.combine_axes([('a', 'c'), ('b', 'd')]) + AxisCollection([ + Axis(['a0_c0', 'a0_c1', 'a0_c2', 'a1_c0', 'a1_c1', 'a1_c2'], 'a_c'), + Axis(['b0_d0', 'b0_d1', 'b1_d0', 'b1_d1', 'b2_d0', 'b2_d1'], 'b_d') + ]) + >>> axes.combine_axes({('a', 'c'): 'ac', ('b', 'd'): 'bd'}) + AxisCollection([ + Axis(['a0_c0', 'a0_c1', 'a0_c2', 'a1_c0', 'a1_c1', 'a1_c2'], 'ac'), + Axis(['b0_d0', 'b0_d1', 'b1_d0', 'b1_d1', 'b2_d0', 'b2_d1'], 'bd') + ]) + """ + if axes is None: + axes = {tuple(self): None} + elif isinstance(axes, AxisCollection): + axes = {tuple(self[axes]): None} + elif isinstance(axes, (list, tuple)): + # checks for nested tuple/list + if all(isinstance(axis, (list, tuple, AxisCollection)) for axis in axes): + axes = {tuple(self[axes_to_combine]): None for axes_to_combine in axes} + else: + axes = {tuple(self[axes]): None} + # axes should be a dict at this time + assert isinstance(axes, dict) + + new_axes = self[:] + for _axes, name in axes.items(): + _axes = new_axes[_axes] + axes_indices = [new_axes.index(axis) for axis in _axes] + diff = np.diff(axes_indices) + # combined axes in front + if front_if_spread and np.any(diff > 1): + combined_axis_pos = 0 + else: + combined_axis_pos = min(axes_indices) + + if name is not None: + combined_name = name + # all anonymous axes => anonymous combined axis + elif all(axis.name is None for axis in _axes): + combined_name = None + else: + combined_name = sep.join(str(id_) for id_ in _axes.ids) + + if wildcard: + combined_axis = Axis(_axes.size, combined_name) + else: + # TODO: the combined keys should be objects which display as: (axis1_label, axis2_label, ...) but + # which should also store the axes names) + # Q: Should it be the same object as the NDLGroup?/NDKey? + # A: yes. On the Pandas backend, we could/should have separate axes. On the numpy backend we cannot. + if len(_axes) == 1: + # Q: if axis is a wildcard axis, should the result be a wildcard axis (and axes_labels discarded?) + combined_labels = _axes[0].labels + else: + combined_labels = [sep.join(str(l) for l in p) + for p in product(*_axes.labels)] + + combined_axis = Axis(combined_labels, combined_name) + new_axes = new_axes - _axes + new_axes.insert(combined_axis_pos, combined_axis) + return new_axes + + def split_axes(self, axes=None, sep='_', names=None, regex=None): + """Split axes and returns a new collection + + The split axes are inserted where the combined axis was. + + Parameters + ---------- + axes : int, str, Axis or any combination of those, optional + axes to split. All labels *must* contain the given delimiter string. To split several axes at once, pass + a list or tuple of axes to split. To set the names of resulting axes, use a {'axis_to_split': (new, axes)} + dictionary. Defaults to all axes whose name contains the `sep` delimiter. + sep : str, optional + delimiter to use for splitting. Defaults to '_'. When `regex` is provided, the delimiter is only used on + `names` if given as one string or on axis name if `names` is None. + names : str or list of str, optional + names of resulting axes. Defaults to None. + regex : str, optional + use regex instead of delimiter to split labels. Defaults to None. + + See Also + -------- + Axis.split + LArray.split_axes + + Returns + ------- + AxisCollection + + Examples + -------- + >>> col = AxisCollection('a=a0,a1;b=b0..b2') + >>> col + AxisCollection([ + Axis(['a0', 'a1'], 'a'), + Axis(['b0', 'b1', 'b2'], 'b') + ]) + >>> combined = col.combine_axes() + >>> combined + AxisCollection([ + Axis(['a0_b0', 'a0_b1', 'a0_b2', 'a1_b0', 'a1_b1', 'a1_b2'], 'a_b') + ]) + >>> combined.split_axes() + AxisCollection([ + Axis(['a0', 'a1'], 'a'), + Axis(['b0', 'b1', 'b2'], 'b') + ]) + + Split labels using regex + + >>> combined = AxisCollection('a_b = a0b0..a1b2') + >>> combined + AxisCollection([ + Axis(['a0b0', 'a0b1', 'a0b2', 'a1b0', 'a1b1', 'a1b2'], 'a_b') + ]) + >>> combined.split_axes('a_b', regex='(\\\\w{2})(\\\\w{2})') + AxisCollection([ + Axis(['a0', 'a1'], 'a'), + Axis(['b0', 'b1', 'b2'], 'b') + ]) + + Split several axes at once + + >>> combined = AxisCollection('a_b = a0_b0..a1_b1; c_d = c0_d0..c1_d1') + >>> combined + AxisCollection([ + Axis(['a0_b0', 'a0_b1', 'a1_b0', 'a1_b1'], 'a_b'), + Axis(['c0_d0', 'c0_d1', 'c1_d0', 'c1_d1'], 'c_d') + ]) + >>> # equivalent to combined.split_axes() which split all axes + >>> # containing the delimiter defined by the argument `sep` + >>> combined.split_axes(['a_b', 'c_d']) + AxisCollection([ + Axis(['a0', 'a1'], 'a'), + Axis(['b0', 'b1'], 'b'), + Axis(['c0', 'c1'], 'c'), + Axis(['d0', 'd1'], 'd') + ]) + >>> combined.split_axes({'a_b': ('A', 'B'), 'c_d': ('C', 'D')}) + AxisCollection([ + Axis(['a0', 'a1'], 'A'), + Axis(['b0', 'b1'], 'B'), + Axis(['c0', 'c1'], 'C'), + Axis(['d0', 'd1'], 'D') + ]) + """ + if axes is None: + axes = {axis: None for axis in self if sep in axis.name} + elif isinstance(axes, (int, basestring, Axis)): + axes = {axes: None} + elif isinstance(axes, (list, tuple)): + if all(isinstance(axis, (int, basestring, Axis)) for axis in axes): + axes = {axis: None for axis in axes} + else: + raise ValueError("Expected tuple or list of int, string or Axis instances") + # axes should be a dict at this time + assert isinstance(axes, dict) + + new_axes = self[:] + for axis, names in axes.items(): + axis = new_axes[axis] + axis_index = new_axes.index(axis) + split_axes = axis.split(sep, names, regex) + new_axes = new_axes[:axis_index] + split_axes + new_axes[axis_index + 1:] + return new_axes + split_axis = renamed_to(split_axes, 'split_axis') + + def align(self, other, join='outer', axes=None): + """Align this axis collection with another. + + This ensures all common axes are compatible. + + Parameters + ---------- + other : AxisCollection + join : {'outer', 'inner', 'left', 'right'}, optional + Defaults to 'outer'. + axes : AxisReference or sequence of them, optional + Axes to align. Need to be valid in both arrays. Defaults to None (all common axes). This must be specified + when mixing anonymous and non-anonymous axes. + + Returns + ------- + (left, right) : (AxisCollection, AxisCollection) + Aligned collections + + See Also + -------- + LArray.align + + Examples + -------- + >>> col1 = AxisCollection("a=a0..a1;b=b0..b2") + >>> col1 + AxisCollection([ + Axis(['a0', 'a1'], 'a'), + Axis(['b0', 'b1', 'b2'], 'b') + ]) + >>> col2 = AxisCollection("a=a0..a2;c=c0..c0;b=b0..b1") + >>> col2 + AxisCollection([ + Axis(['a0', 'a1', 'a2'], 'a'), + Axis(['c0'], 'c'), + Axis(['b0', 'b1'], 'b') + ]) + >>> aligned1, aligned2 = col1.align(col2) + >>> aligned1 + AxisCollection([ + Axis(['a0', 'a1', 'a2'], 'a'), + Axis(['b0', 'b1', 'b2'], 'b') + ]) + >>> aligned2 + AxisCollection([ + Axis(['a0', 'a1', 'a2'], 'a'), + Axis(['c0'], 'c'), + Axis(['b0', 'b1', 'b2'], 'b') + ]) + + Using anonymous axes + + >>> col1 = AxisCollection("a0..a1;b0..b2") + >>> col1 + AxisCollection([ + Axis(['a0', 'a1'], None), + Axis(['b0', 'b1', 'b2'], None) + ]) + >>> col2 = AxisCollection("a0..a2;b0..b1;c0..c0") + >>> col2 + AxisCollection([ + Axis(['a0', 'a1', 'a2'], None), + Axis(['b0', 'b1'], None), + Axis(['c0'], None) + ]) + >>> aligned1, aligned2 = col1.align(col2) + >>> aligned1 + AxisCollection([ + Axis(['a0', 'a1', 'a2'], None), + Axis(['b0', 'b1', 'b2'], None) + ]) + >>> aligned2 + AxisCollection([ + Axis(['a0', 'a1', 'a2'], None), + Axis(['b0', 'b1', 'b2'], None), + Axis(['c0'], None) + ]) + """ + if join not in {'outer', 'inner', 'left', 'right'}: + raise ValueError("join should be one of 'outer', 'inner', 'left' or 'right'") + other = other if isinstance(other, AxisCollection) else AxisCollection(other) + + # if axes not specified + if axes is None: + # and we have only anonymous axes on both sides + if all(name is None for name in self.names) and all(name is None for name in other.names): + # use N first axes by position + join_axes = list(range(min(len(self), len(other)))) + elif any(name is None for name in self.names) or any(name is None for name in other.names): + raise ValueError("axes collections with mixed anonymous/non anonymous axes are not supported by align" + "without specifying axes explicitly") + else: + assert all(name is not None for name in self.names) and all(name is not None for name in other.names) + # use all common axes + join_axes = list(OrderedSet(self.names) & OrderedSet(other.names)) + else: + if isinstance(axes, (int, str, Axis)): + axes = [axes] + join_axes = axes + new_axes = [self_axis.align(other_axis, join=join) + for self_axis, other_axis in zip(self[join_axes], other[join_axes])] + axes_changes = list(zip(join_axes, new_axes)) + return self.replace(axes_changes), other.replace(axes_changes) + + +class AxisReference(ABCAxisReference, ExprNode, Axis): + def __init__(self, name): + self.name = name + self._labels = None + self._iswildcard = False + + def index(self, key): + raise NotImplementedError("an AxisReference (X.) cannot translate labels") + + def __repr__(self): + return 'AxisReference(%r)' % self.name + + def evaluate(self, context): + """ + Parameters + ---------- + context : AxisCollection + Use axes from this collection + """ + return context[self] + + # needed because ExprNode.__hash__ (which is object.__hash__) takes precedence over Axis.__hash__ + def __hash__(self): + return id(self) + + +class AxisReferenceFactory(object): + # needed to make pickle work (because we have a __getattr__ which does not return AttributeError on __getstate__) + def __getstate__(self): + return self.__dict__ + + def __setstate__(self, d): + self.__dict__ = d + + def __getattr__(self, key): + return AxisReference(key) + + def __getitem__(self, key): + return AxisReference(key) + + +X = AxisReferenceFactory() + + +class DeprecatedAxisReferenceFactory(object): + # needed to make pickle work (because we have a __getattr__ which does not return AttributeError on __getstate__) + def __getstate__(self): + return self.__dict__ + + def __setstate__(self, d): + self.__dict__ = d + + def __getattr__(self, key): + warnings.warn("Special variable 'x' is deprecated, use 'X' instead", FutureWarning, stacklevel=2) + return AxisReference(key) + + def __getitem__(self, key): + warnings.warn("Special variable 'x' is deprecated, use 'X' instead", FutureWarning, stacklevel=2) + return AxisReference(key) + + +x = DeprecatedAxisReferenceFactory() diff --git a/larray/core/expr.py b/larray/core/expr.py new file mode 100644 index 000000000..52ed5aab3 --- /dev/null +++ b/larray/core/expr.py @@ -0,0 +1,95 @@ +# -*- coding: utf8 -*- +from __future__ import absolute_import, division, print_function + +import sys + + +class ExprNode(object): + # method factory + def _binop(opname): + def opmethod(self, other): + return BinaryOp(opname, self, other) + + opmethod.__name__ = '__{}__'.format(opname) + return opmethod + + __matmul__ = _binop('matmul') + __ror__ = _binop('ror') + __or__ = _binop('or') + __rxor__ = _binop('rxor') + __xor__ = _binop('xor') + __rand__ = _binop('rand') + __and__ = _binop('and') + __rrshift__ = _binop('rrshift') + __rshift__ = _binop('rshift') + __rlshift__ = _binop('rlshift') + __lshift__ = _binop('lshift') + __rpow__ = _binop('rpow') + __pow__ = _binop('pow') + __rdivmod__ = _binop('rdivmod') + __divmod__ = _binop('divmod') + __rmod__ = _binop('rmod') + __mod__ = _binop('mod') + __rfloordiv__ = _binop('rfloordiv') + __floordiv__ = _binop('floordiv') + __rtruediv__ = _binop('rtruediv') + __truediv__ = _binop('truediv') + if sys.version < '3': + __div__ = _binop('div') + __rdiv__ = _binop('rdiv') + __rmul__ = _binop('rmul') + __mul__ = _binop('mul') + __rsub__ = _binop('rsub') + __sub__ = _binop('sub') + __radd__ = _binop('radd') + __add__ = _binop('add') + __ge__ = _binop('ge') + __gt__ = _binop('gt') + __ne__ = _binop('ne') + __eq__ = _binop('eq') + __le__ = _binop('le') + __lt__ = _binop('lt') + + def _unaryop(opname): + def opmethod(self): + return UnaryOp(opname, self) + + opmethod.__name__ = '__{}__'.format(opname) + return opmethod + + # unary ops do not need broadcasting so do not need to be overridden + __neg__ = _unaryop('neg') + __pos__ = _unaryop('pos') + __abs__ = _unaryop('abs') + __invert__ = _unaryop('invert') + + def evaluate(self, context): + raise NotImplementedError() + + +def expr_eval(expr, context): + return expr.evaluate(context) if isinstance(expr, ExprNode) else expr + + +class BinaryOp(ExprNode): + def __init__(self, op, expr1, expr2): + self.op = op + self.expr1 = expr1 + self.expr2 = expr2 + + def evaluate(self, context): + # TODO: implement eval via numexpr + expr1 = expr_eval(self.expr1, context) + expr2 = expr_eval(self.expr2, context) + return getattr(expr1, '__{}__'.format(self.op))(expr2) + + +class UnaryOp(ExprNode): + def __init__(self, op, expr): + self.op = op + self.expr = expr + + def evaluate(self, context): + # TODO: implement eval via numexpr + expr = expr_eval(self.expr, context) + return getattr(expr, '__{}__'.format(self.op))() diff --git a/larray/core/group.py b/larray/core/group.py new file mode 100644 index 000000000..fb48aeaac --- /dev/null +++ b/larray/core/group.py @@ -0,0 +1,1517 @@ +# -*- coding: utf8 -*- +from __future__ import absolute_import, division, print_function + +import re +import sys +import warnings +from itertools import product, chain + +import numpy as np +import pandas as pd + +from larray.core.abstractbases import ABCAxis, ABCAxisReference, ABCLArray +from larray.util.oset import * +from larray.util.misc import basestring, PY2, unique, find_closing_chr, _parse_bound, _seq_summary, renamed_to + +__all__ = ['Group', 'LGroup', 'LSet', 'IGroup', 'union'] + + +def _slice_to_str(key, repr_func=str): + """ + Converts a slice to a string + + Examples + -------- + >>> _slice_to_str(slice(None)) + ':' + >>> _slice_to_str(slice(24)) + ':24' + >>> _slice_to_str(slice(25, None)) + '25:' + >>> _slice_to_str(slice(5, 10)) + '5:10' + >>> _slice_to_str(slice(None, 5, 2)) + ':5:2' + """ + # examples of result: ":24" "25:" ":" ":5:2" + start = repr_func(key.start) if key.start is not None else '' + stop = repr_func(key.stop) if key.stop is not None else '' + step = (":" + repr_func(key.step)) if key.step is not None else '' + return '%s:%s%s' % (start, stop, step) + + +def irange(start, stop, step=None): + """Create a range, with inclusive stop bound and automatic sign for step. + + Parameters + ---------- + start : int + Start bound + stop : int + Inclusive stop bound + step : int, optional + Distance between two generated numbers. If provided this *must* be a positive integer. + + Returns + ------- + range + + Examples + -------- + >>> list(irange(1, 3)) + [1, 2, 3] + >>> list(irange(2, 0)) + [2, 1, 0] + >>> list(irange(1, 6, 2)) + [1, 3, 5] + >>> list(irange(6, 1, 2)) + [6, 4, 2] + >>> list(irange(-1, 1)) + [-1, 0, 1] + """ + if step is None: + step = 1 + elif step <= 0: + raise ValueError("step must be a positive integer or None") + step = step if start <= stop else -step + stop = stop + 1 if start <= stop else stop - 1 + return range(start, stop, step) + + +_range_bound_pattern = re.compile('([0-9]+|[a-zA-Z]+)') + + +def generalized_range(start, stop, step=1): + """Create a range, with inclusive stop bound and automatic sign for step. Bounds can be strings. + + Parameters + ---------- + start : int or str + Start bound + stop : int or str + Inclusive stop bound + step : int, optional + Distance between two generated numbers. If provided this *must* be a positive integer. + + Returns + ------- + range + + Examples + -------- + works with both number and letter bounds + + >>> list(generalized_range(-1, 2)) + [-1, 0, 1, 2] + >>> generalized_range('a', 'c') + ['a', 'b', 'c'] + + can generate in reverse + + >>> list(generalized_range(2, 0)) + [2, 1, 0] + >>> generalized_range('c', 'a') + ['c', 'b', 'a'] + + can combine letters and numbers + + >>> generalized_range('a0', 'c1') + ['a0', 'a1', 'b0', 'b1', 'c0', 'c1'] + + any special character is left intact + + >>> generalized_range('a_0', 'c_1') + ['a_0', 'a_1', 'b_0', 'b_1', 'c_0', 'c_1'] + + consecutive digits are treated like numbers + + >>> generalized_range('A8', 'A10') + ['A8', 'A9', 'A10'] + + one may use zero padding on numbers + + >>> generalized_range('A08', 'A10') + ['A08', 'A09', 'A10'] + + consecutive letters create all combinations + + >>> generalized_range('AA', 'CC') + ['AA', 'AB', 'AC', 'BA', 'BB', 'BC', 'CA', 'CB', 'CC'] + + one cannot go from a integer to a letter and vice versa + + >>> generalized_range('1', 'F') + Traceback (most recent call last): + ... + ValueError: expected an integer for the stop bound (because the start bound is an integer) but got 'F' instead + + when using special characters, they must be the same on both sides + + >>> generalized_range('a|1', 'a/2') + Traceback (most recent call last): + ... + ValueError: Special characters must be the same for start and stop + """ + if isinstance(start, str): + assert isinstance(stop, str) + start_parts = _range_bound_pattern.split(start) + stop_parts = _range_bound_pattern.split(stop) + assert len(start_parts) == len(stop_parts) + ranges = [] + for start_part, stop_part in zip(start_parts, stop_parts): + # we only handle non-negative int-like strings on purpose. Int-only bounds should already be converted to + # real integers by now, and mixing negative int-like strings and letters yields some strange results. + if start_part.isdigit(): + if not stop_part.isdigit(): + raise ValueError("expected an integer for the stop bound (because the start bound is an integer) " + "but got '%s' instead" % stop_part) + rng = irange(int(start_part), int(stop_part)) + start_pad = len(start_part) if start_part.startswith('0') else None + stop_pad = len(stop_part) if stop_part.startswith('0') else None + if start_pad is not None and stop_pad is not None and start_pad != stop_pad: + raise ValueError("Inconsistent zero padding for start and stop ({} vs {}) of the numerical part. " + "Must be either the same on both sides or no padding on either side" + .format(start_pad, stop_pad)) + elif start_pad is None and stop_pad is None: + r = [str(num) for num in rng] + else: + pad = start_pad if stop_pad is None else stop_pad + r = ['%0*d' % (pad, num) for num in rng] + elif start_part.isalpha(): + assert stop_part.isalpha() + int_start = [ord(c) for c in start_part] + int_stop = [ord(c) for c in stop_part] + sranges = [[chr(c) for c in irange(r_start, r_stop) if chr(c).isalnum()] + for r_start, r_stop in zip(int_start, int_stop)] + r = [''.join(p) for p in product(*sranges)] + else: + # special characters + if start_part != stop_part: + raise ValueError("Special characters must be the same for start and stop") + r = [start_part] + ranges.append(r) + res = [''.join(p) for p in product(*ranges)] + return res if step == 1 else res[::step] + else: + return irange(start, stop, step) + + +_range_str_pattern = re.compile('(?P[^\s.]+)?\s*\.\.\s*(?P[^\s.]+)?(\s+step\s+(?P\d+))?') + + +def _range_str_to_range(s, stack_depth=1): + """ + Converts a range string to a range (of values). + The end point is included. + + Parameters + ---------- + s : str + String representing a range of values + + Returns + ------- + range + range of int or list of str. + + Examples + -------- + >>> list(_range_str_to_range('-1..2')) + [-1, 0, 1, 2] + >>> _range_str_to_range('a..c') + ['a', 'b', 'c'] + >>> list(_range_str_to_range('2..6 step 2')) + [2, 4, 6] + + 0 padding + >>> list(_range_str_to_range('01..12')) + ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'] + + any special character except . and spaces should work + >>> _range_str_to_range('a|+*@-b .. a|+*@-d') + ['a|+*@-b', 'a|+*@-c', 'a|+*@-d'] + """ + s = s.strip() + m = _range_str_pattern.match(s) + + groups = m.groupdict() + start, stop, step = groups['start'], groups['stop'], groups['step'] + start = _parse_bound(start, stack_depth + 1) if start is not None else 0 + if stop is None: + raise ValueError("no stop bound provided in range: %r" % s) + stop = _parse_bound(stop, stack_depth + 1) + if isinstance(start, basestring) or isinstance(stop, basestring): + start, stop = str(start), str(stop) + # TODO: use parse_bound + step = int(step) if step is not None else 1 + return generalized_range(start, stop, step) + + +def _range_to_slice(seq, length=None): + """ + Returns a slice if possible (including for sequences of 1 element) otherwise returns the input sequence itself + + Parameters + ---------- + seq : sequence-like of int + List, tuple or ndarray of integers representing the range. + It should be something like [start, start+step, start+2*step, ...] + length : int, optional + length of sequence of positions. This is only useful when you must be able to transform decreasing sequences + which can stop at 0. + + Returns + ------- + slice or sequence-like + return the input sequence if a slice cannot be defined + + Examples + -------- + >>> _range_to_slice([3, 4, 5]) + slice(3, 6, None) + >>> _range_to_slice([3, 5, 7]) + slice(3, 9, 2) + >>> _range_to_slice([-3, -2]) + slice(-3, -1, None) + >>> _range_to_slice([-1, -2]) + slice(-1, -3, -1) + >>> _range_to_slice([2, 1]) + slice(2, 0, -1) + >>> _range_to_slice([1, 0], 4) + slice(-3, -5, -1) + >>> _range_to_slice([1, 0]) + [1, 0] + >>> _range_to_slice([1]) + slice(1, 2, None) + >>> _range_to_slice([]) + [] + """ + if len(seq) < 1: + return seq + start = seq[0] + if len(seq) == 1: + return slice(start, start + 1) + second = seq[1] + step = second - start + prev_value = second + for value in seq[2:]: + if value != prev_value + step: + return seq + prev_value = value + stop = prev_value + step + if prev_value == 0 and step < 0: + if length is None: + return seq + else: + stop -= length + start -= length + if step == 1: + step = None + return slice(start, stop, step) + + +def _is_object_array(array): + return isinstance(array, np.ndarray) and array.dtype.type == np.object_ + + +def _can_have_groups(seq): + return _is_object_array(seq) or isinstance(seq, (tuple, list)) + + +def _contain_group_ticks(ticks): + return _can_have_groups(ticks) and any(isinstance(tick, Group) for tick in ticks) + + +def _seq_group_to_name(seq): + if _can_have_groups(seq): + return [v.name if isinstance(v, Group) else v for v in seq] + else: + return seq + + +def _to_tick(v): + """ + Converts any value to a tick (ie makes it hashable, and acceptable as an ndarray element) + + scalar -> not modified + slice -> 'start:stop' + list|tuple -> 'v1,v2,v3' + Group with name -> v.name + Group without name -> _to_tick(v.key) + other -> str(v) + + Parameters + ---------- + v : any + value to be converted. + + Returns + ------- + any scalar + scalar representing the tick + """ + # the fact that an "aggregated tick" is passed as a LGroup or as a string should be as irrelevant as possible. + # The thing is that we cannot (currently) use the more elegant _to_tick(e.key) that means the LGroup is not + # available in Axis.__init__ after to_ticks, and we need it to update the mapping if it was named. Effectively, + # this creates two entries in the mapping for a single tick. Besides, I like having the LGroup as the tick, as it + # provides extra info as to where it comes from. + if np.isscalar(v): + return v + elif isinstance(v, Group): + return v.name if v.name is not None else _to_tick(v.to_label()) + elif isinstance(v, slice): + return _slice_to_str(v) + elif isinstance(v, (tuple, list)): + if len(v) == 1: + return str(v) + ',' + else: + # TODO: it would be nicer/saner to use n=1, sep='' but this currently breaks at lot of tests + return _seq_summary(v, n=1000, repr_func=str, sep=',') + else: + return str(v) + + +# TODO: remove the conversion to list in doctests once Python 2 is dropped +def _to_ticks(s, parse_single_int=False): + """ + Makes a (list of) value(s) usable as the collection of labels for an Axis (ie hashable). + + Strip strings, split them on ',' and translate "range strings" to list of values **including the end point** ! + + Parameters + ---------- + s : iterable + List of values usable as the collection of labels for an Axis. + + Returns + ------- + Numpy 1D array containing labels + + Examples + -------- + >>> list(_to_ticks('M , F')) + ['M', 'F'] + >>> list(_to_ticks('A,C..E,F..G,Z')) + ['A', 'C', 'D', 'E', 'F', 'G', 'Z'] + >>> list(_to_ticks('U')) + ['U'] + >>> list(_to_ticks('..3')) + [0, 1, 2, 3] + >>> list(_to_ticks('01..12')) + ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'] + >>> list(_to_ticks('01,02,03,10,11,12')) + ['01', '02', '03', '10', '11', '12'] + """ + if isinstance(s, ABCAxis): + return s.labels + if isinstance(s, Group): + # a single LGroup used for all ticks of an Axis + return _to_ticks(s.eval()) + elif isinstance(s, np.ndarray): + # we assume it has already been translated + # XXX: Is it a safe assumption? + return s + + if isinstance(s, pd.Index): + ticks = s.values + elif isinstance(s, (list, tuple)): + ticks = [_to_tick(e) for e in s] + elif sys.version >= '3' and isinstance(s, range): + ticks = s + elif isinstance(s, basestring): + seq = _seq_str_to_seq(s, parse_single_int=parse_single_int) + if isinstance(seq, slice): + raise ValueError("using : to define axes is deprecated, please use .. instead") + ticks = [seq] if isinstance(seq, (basestring, int)) else seq + elif hasattr(s, '__array__'): + ticks = s.__array__() + else: + try: + ticks = list(s) + except TypeError: + raise TypeError("ticks must be iterable (%s is not)" % type(s)) + return np.asarray(ticks) + + +_axis_name_pattern = re.compile('\s*(([A-Za-z]\w*)(\.i)?\s*\[)?(.*)') + + +def _seq_str_to_seq(s, stack_depth=1, parse_single_int=False): + """ + Converts a sequence string to its sequence (or scalar) + + Parameters + ---------- + s : basestring + string to parse + + Returns + ------- + scalar, slice, range or list + """ + numcolons = s.count(':') + if numcolons: + assert numcolons <= 2 + # bounds can be of len 2 or 3 (if step is provided) + # stack_depth + 2 because the list comp has its own stack + bounds = [_parse_bound(b, stack_depth + 2) for b in s.split(':')] + return slice(*bounds) + elif ',' in s and '..' in s: + # strip extremity commas to avoid empty string sequence elements + s = s.strip(',') + + def to_seq(b, stack_depth=1): + if '..' in b: + return _range_str_to_range(b, stack_depth + 1) + else: + parsed = _parse_bound(b, stack_depth + 1) + return (parsed,) + + # stack_depth + 2 because the list comp has its own stack + return list(chain(*[to_seq(b, stack_depth + 2) for b in s.split(',')])) + elif ',' in s: + # strip extremity commas to avoid empty string sequence elements + s = s.strip(',') + return [_parse_bound(b, stack_depth + 2) for b in s.split(',')] + elif '..' in s: + return _range_str_to_range(s, stack_depth + 1) + else: + return _parse_bound(s, stack_depth + 1, parse_int=parse_single_int) + + +def _to_key(v, stack_depth=1, parse_single_int=False): + """ + Converts a value to a key usable for indexing (slice object, list of values,...). + Strings are split on ',' and stripped. Colons (:) are interpreted as slices. + + Parameters + ---------- + v : int or basestring or tuple or list or slice or LArray or Group + value to convert into a key usable for indexing + + Returns + ------- + key + a key represents any object that can be used for indexing + + Examples + -------- + >>> _to_key('a:c') + slice('a', 'c', None) + >>> _to_key('a, b,c ,') + ['a', 'b', 'c'] + >>> _to_key('a..c') + ['a', 'b', 'c'] + >>> _to_key('a,c..e,g..h,z') + ['a', 'c', 'd', 'e', 'g', 'h', 'z'] + >>> _to_key('a,') + ['a'] + >>> _to_key(' a ') + 'a' + >>> _to_key(10) + 10 + >>> _to_key('10') + '10' + >>> _to_key('10:20') + slice(10, 20, None) + >>> _to_key(slice('10', '20')) + slice('10', '20', None) + >>> _to_key('year.i[-1]') + year.i[-1] + >>> _to_key('age[10:19]>>teens') + age[10:19] >> 'teens' + >>> _to_key('a,b,c >> abc') + LGroup(['a', 'b', 'c']) >> 'abc' + >>> _to_key('a:c >> abc') + LGroup(slice('a', 'c', None)) >> 'abc' + + # evaluated variables do not work on Python 2, probably because the stackdepth is different + # >>> ext = [1, 2, 3] + # >>> _to_key('{ext} >> ext') + # LGroup([1, 2, 3]) >> 'ext' + # >>> answer = 42 + # >>> _to_key('{answer}') + # 42 + # >>> _to_key('{answer} >> answer') + # LGroup(42) >> 'answer' + # >>> _to_key('10:{answer} >> answer') + # LGroup(slice(10, 42, None)) >> 'answer' + # >>> _to_key('4,{answer},2 >> answer') + # LGroup([4, 42, 2]) >> 'answer' + # >>> list(_to_key('40..{answer}')) + # [40, 41, 42] + # >>> _to_key('4,40..{answer},2') + # [4, 40, 41, 42, 2] + # >>> _to_key('4,40..{answer},2 >> answer') + # LGroup([4, 40, 41, 42, 2]) >> 'answer' + """ + if isinstance(v, tuple): + return list(v) + elif isinstance(v, basestring): + # axis name + m = _axis_name_pattern.match(v) + _, axis, positional, key = m.groups() + # group name. using rfind in the unlikely case there is another >> + name_pos = key.rfind('>>') + name = None + if name_pos != -1: + key, name = key[:name_pos].strip(), key[name_pos + 2:].strip() + if axis is not None: + axis = axis.strip() + axis_bracket_open = m.end(1) - 1 + # check that the string parentheses are correctly balanced + _ = find_closing_chr(v, axis_bracket_open) + # strip closing bracket (it should be at the end because we took care of the name earlier) + assert key[-1] == ']' + key = key[:-1] + if name is not None or axis is not None: + cls = IGroup if positional else LGroup + key = _to_key(key, stack_depth + 1, parse_single_int=positional) + return cls(key, name=name, axis=axis) + else: + return _seq_str_to_seq(v, stack_depth + 1, parse_single_int=parse_single_int) + elif v is Ellipsis or np.isscalar(v) or isinstance(v, (Group, slice, list, np.ndarray, ABCLArray, OrderedSet)): + return v + else: + raise TypeError("%s has an invalid type (%s) for a key" % (v, type(v).__name__)) + + +def _to_keys(value, stack_depth=1): + """ + Converts a (collection of) group(s) to a structure usable for indexing. + + 'label' or ['l1', 'l2'] or [['l1', 'l2'], ['l3']] + + Parameters + ---------- + value : int or basestring or tuple or list or slice or LArray or Group + (collection of) value(s) to convert into key(s) usable for indexing + + Returns + ------- + list of keys + + Examples + -------- + It is only used for .sum(axis=xxx) + >>> _to_keys('P01,P02') # <-- one group => collapse dimension + ['P01', 'P02'] + >>> _to_keys(('P01,P02',)) # <-- do not collapse dimension + (['P01', 'P02'],) + >>> _to_keys('P01;P02,P03;:') + ('P01', ['P02', 'P03'], slice(None, None, None)) + + # evaluated variables do not work on Python 2, probably because the stack depth is different + # >>> ext = 'P03' + # >>> to_keys('P01,P02,{ext}') + # ['P01', 'P02', 'P03'] + # >>> to_keys('P01;P02;{ext}') + # ('P01', 'P02', 'P03') + + >>> _to_keys('age[10:19] >> teens ; year.i[-1]') + (age[10:19] >> 'teens', year.i[-1]) + + # >>> to_keys('P01,P02,:') # <-- INVALID ! + # it should have an explicit failure + + # we allow this, even though it is a dubious syntax + >>> _to_keys(('P01', 'P02', ':')) + ('P01', 'P02', slice(None, None, None)) + + # it is better to use explicit groups + >>> _to_keys(('P01,', 'P02,', ':')) + (['P01'], ['P02'], slice(None, None, None)) + + # or even the ugly duck... + >>> _to_keys((('P01',), ('P02',), ':')) + (['P01'], ['P02'], slice(None, None, None)) + """ + if isinstance(value, basestring) and ';' in value: + value = tuple(value.split(';')) + + if isinstance(value, tuple): + # stack_depth + 2 because the list comp has its own stack + return tuple([_to_key(group, stack_depth + 2) for group in value]) + else: + return _to_key(value, stack_depth + 1) + + +# forbidden characters in sheet names +_sheet_name_pattern = re.compile('[\\\/?*\[\]:]') + + +def _translate_sheet_name(sheet_name): + if isinstance(sheet_name, Group): + sheet_name = _sheet_name_pattern.sub('_', str(_to_tick(sheet_name))) + if isinstance(sheet_name, basestring) and len(sheet_name) > 30: + raise ValueError("Sheet names cannot exceed 31 characters") + return sheet_name + + +# forbidden characters for dataset names in HDF files +_key_hdf_pattern = re.compile('[\\\/]') + + +def _translate_key_hdf(key): + if isinstance(key, Group): + key = _key_hdf_pattern.sub('_', str(_to_tick(key))) + return key + + +def union(*args): + # TODO: add support for LGroup and lists + """ + Returns the union of several "value strings" as a list. + + Parameters + ---------- + *args + (collection of) value(s) to be converted into label(s). Repeated values are taken only once. + + Returns + ------- + list of labels + + Examples + -------- + >>> union('a', 'a, b, c, d', ['d', 'e', 'f'], '..2') + ['a', 'b', 'c', 'd', 'e', 'f', 0, 1, 2] + """ + if args: + return list(unique(chain(*(_to_ticks(arg) for arg in args)))) + else: + return [] + + +class IGroupMaker(object): + """ + Generates a new instance of IGroup for a given axis and key. + + Attributes + ---------- + axis : Axis + an axis. + + Notes + ----- + This class is used by the method `Axis.i` + """ + def __init__(self, axis): + assert isinstance(axis, ABCAxis) + self.axis = axis + + def __getitem__(self, key): + return IGroup(key, None, self.axis) + + +# We need a separate class for LGroup and cannot simply create a new Axis with a subset of values/ticks/labels: +# the subset of ticks/labels of the LGroup need to correspond to its *Axis* indices +class Group(object): + """Abstract Group. + """ + format_string = None + + def __init__(self, key, name=None, axis=None): + if isinstance(key, tuple): + key = list(key) + if isinstance(key, Group): + key = key.to_label() + self.key = remove_nested_groups(key) + + # we do NOT assign a name automatically when missing because that makes it impossible to know whether a name + # was explicitly given or not + self.name = str(_to_tick(name)) if name is not None else name + assert axis is None or isinstance(axis, (basestring, int, ABCAxis)), \ + "invalid axis '%s' (%s)" % (axis, type(axis).__name__) + + # we could check the key is valid but this can be slow and could be useless + # TODO: for performance reasons, we should cache the result. This will need to be invalidated correctly + # axis.translate(key) + + # we store the Axis object and not its name like we did previously so that groups on anonymous axes are more + # meaningful and that we can iterate on a slice of an axis (an LGroup). The reason to store the name instead of + # the object was to make sure that a Group from an axis (or without axis) could be used on another axis with + # the same name. See test_array.py:test_... + self.axis = axis + + def __repr__(self): + key = self.key + + # eval only returns a slice for groups without an Axis object + if isinstance(key, slice): + key_repr = _slice_to_str(key, repr_func=repr) + elif isinstance(key, (tuple, list, np.ndarray, OrderedSet)): + key_repr = _seq_summary(key, n=1000, repr_func=repr, sep=', ') + else: + key_repr = repr(key) + + axis_name = self.axis.name if isinstance(self.axis, ABCAxis) else self.axis + if axis_name is not None: + axis_name = 'X.{}'.format(axis_name) if isinstance(self.axis, ABCAxisReference) else axis_name + s = self.format_string.format(axis=axis_name, key=key_repr) + else: + if self.axis is not None: + # anonymous axis + axis_ref = ', axis={}'.format(repr(self.axis)) + else: + axis_ref = '' + if isinstance(key, slice): + key_repr = repr(key) + elif isinstance(key, list): + key_repr = '[{}]'.format(key_repr) + s = '{}({}{})'.format(self.__class__.__name__, key_repr, axis_ref) + return "{} >> {}".format(s, repr(self.name)) if self.name is not None else s + + def __str__(self): + return str(self.eval()) + + # TODO: rename to "to_positional" + def translate(self, bound=None, stop=False): + """ + Translate key to a position if it is not already + + Parameters + ---------- + bound : any, optional + stop : bool, optional + + Returns + ------- + int-based key (single int, slice of int or tuple/list/array of them) + """ + raise NotImplementedError() + + def eval(self): + """ + Translate key to labels, if it is not already, expanding slices in the process. + + Returns + ------- + label-based key (single scalar or tuple/list/array of them) + """ + raise NotImplementedError() + + def to_label(self): + """ + Translate key to labels, if it is not already + + Returns + ------- + label-based key (single scalar, slice of scalars or tuple/list/array of them) + """ + raise NotImplementedError() + + def retarget_to(self, target_axis): + """Retarget group to another axis. + + It will be translated to an LGroup using its former axis, if necessary. + + Parameters + ---------- + target_axis : Axis + axis to conform to + + Returns + ------- + Group with axis, raise ValueError if retargeting is not possible + """ + if self.axis is target_axis: + return self + elif isinstance(self.axis, basestring) or isinstance(self.axis, ABCAxisReference): + axis_name = self.axis.name if isinstance(self.axis, ABCAxisReference) else self.axis + if axis_name != target_axis.name: + raise ValueError('cannot retarget a Group defined without a real axis object (e.g. using ' + 'an AxisReference (x.)) to an axis with a different name') + return self.__class__(self.key, self.name, target_axis) + elif self.axis.equals(target_axis) or isinstance(self.axis, int): + # in the case of isinstance(self.axis, int), we can only hope the axis corresponds. This is the + # case if we come from _translate_axis_key_chunk, but if the users calls this manually, we cannot know. + # XXX: maybe changing this to retarget_to_axes would be a good idea after all? + + # just change the axis object + return self.__class__(self.key, self.name, target_axis) + else: + # to retarget to another (non-equal) Axis, we need to translate to labels and expand slices + return LGroup(self.eval(), self.name, target_axis) + + def __len__(self): + # XXX: we probably want to_label instead of .eval (so that we do not expand slices) + value = self.eval() + # for some reason this breaks having LGroup ticks/labels on an axis + # if isinstance(value, (tuple, list, LArray, np.ndarray, str)): + if hasattr(value, '__len__'): + return len(value) + elif isinstance(value, slice): + start, stop, key_step = value.start, value.stop, value.step + # not using stop - start because that does not work for string bounds + # (and it is different for LGroup & IGroup) + start_pos = self.translate(start) + stop_pos = self.translate(stop) + return stop_pos - start_pos + else: + raise TypeError('len() of unsized object ({})'.format(value)) + + def __iter__(self): + # XXX: use translate/IGroup instead, so that it works even in the presence of duplicate labels + # possibly, only if axis is set? + return iter([LGroup(v, axis=self.axis) for v in self.eval()]) + + def named(self, name): + """Returns group with a different name. + + Parameters + ---------- + name : str + new name for group + + Returns + ------- + Group + """ + return self.__class__(self.key, name, self.axis) + __rshift__ = named + + def with_axis(self, axis): + """Returns group with a different axis. + + Parameters + ---------- + axis : int, str, Axis + new axis for group + + Returns + ------- + Group + """ + return self.__class__(self.key, self.name, axis) + + def by(self, length, step=None): + """Split group into several groups of specified length. + + Parameters + ---------- + length : int + length of new groups + step : int, optional + step between groups. Defaults to length. + + Notes + ----- + step can be smaller than length, in which case, this will produce overlapping groups. + + Returns + ------- + list of Group + + Examples + -------- + >>> from larray import Axis, X + >>> age = Axis(range(10), 'age') + >>> age[[1, 2, 3, 4, 5]].by(2) + (age[1, 2], age[3, 4], age[5]) + >>> age[1:5].by(2) + (age.i[1:3], age.i[3:5], age.i[5:6]) + >>> age[1:5].by(2, 4) + (age.i[1:3], age.i[5:6]) + >>> age[1:5].by(3, 2) + (age.i[1:4], age.i[3:6], age.i[5:6]) + >>> X.age[[0, 1, 2, 3, 4]].by(2) + (X.age[0, 1], X.age[2, 3], X.age[4]) + """ + if step is None: + step = length + return tuple(self[start:start + length] + for start in range(0, len(self), step)) + + # TODO: __getitem__ should work by label and .i[] should work by position. I guess it would be more consistent this + # way even if the usefulness of subsetting a group with labels is dubious (but it is sometimes practical to treat + # the group as if it was an axis). + # >>> vla = geo['...'] + # >>> # first 10 regions of flanders (this could have some use) + # >>> vla.i[:10] # => IGroup on geo + # >>> vla["antwerp", "gent"] # => LGroup on geo + + # LGroup[] => LGroup + # IGroup[] => LGroup + # IGroup.i[] => IGroup + # LGroup.i[] => IGroup + def __getitem__(self, key): + """ + + Parameters + ---------- + key : int, slice of int or list of int + position-based key (even for LGroup) + + Returns + ------- + Group + """ + cls = self.__class__ + orig_key = self.key + # XXX: unsure we should support tuple + if isinstance(orig_key, (tuple, list)): + return cls(orig_key[key], None, self.axis) + elif isinstance(orig_key, slice): + orig_start, orig_stop, orig_step = orig_key.start, orig_key.stop, orig_key.step + if orig_step is None: + orig_step = 1 + + orig_start_pos = self.translate(orig_start) if orig_start is not None else 0 + if isinstance(key, slice): + key_start, key_stop, key_step = key.start, key.stop, key.step + if key_step is None: + key_step = 1 + + orig_stop_pos = self.translate(orig_stop, stop=True) if orig_stop is not None else len(self) + new_start = orig_start_pos + key_start * orig_step + new_stop = min(orig_start_pos + key_stop * orig_step, orig_stop_pos) + new_step = orig_step * key_step + if new_step == 1: + new_step = None + return IGroup(slice(new_start, new_stop, new_step), None, self.axis) + elif isinstance(key, int): + return IGroup(orig_start_pos + key * orig_step, None, self.axis) + elif isinstance(key, (tuple, list)): + return IGroup([orig_start_pos + k * orig_step for k in key], None, self.axis) + elif isinstance(orig_key, ABCLArray): + # XXX: why .i ? + return cls(orig_key.i[key], None, self.axis) + elif np.isscalar(orig_key): + # give the opportunity to subset the label/key itself (for example for string keys) + value = self.eval() + return value[key] + else: + raise TypeError("cannot take a subset of {} because it has a '{}' key".format(self.key, type(self.key))) + + def _ipython_key_completions_(self): + return list(self.eval()) + + # method factory + def _binop(opname): + op_fullname = '__%s__' % opname + + # TODO: implement this in a delayed fashion for axes references + if PY2: + # workaround the fact slice objects do not have any __binop__ methods defined on Python2 (even though + # the actual operations work on them). + def opmethod(self, other): + self_value = self.eval() + other_value = other.eval() if isinstance(other, Group) else other + # this can only happen when self.axis is not an Axis instance + if isinstance(self_value, slice): + if not isinstance(other_value, slice): + # FIXME: we should raise a TypeError instead for all ops except == and != + # FIXME: we should return True for != + return False + # FIXME: we should raise a TypeError instead of doing this for all ops except comparison ops + self_value = (self_value.start, self_value.stop, self_value.step) + other_value = (other_value.start, other_value.stop, other_value.step) + return getattr(self_value, op_fullname)(other_value) + else: + def opmethod(self, other): + other_value = other.eval() if isinstance(other, Group) else other + return getattr(self.eval(), op_fullname)(other_value) + + opmethod.__name__ = op_fullname + return opmethod + + __matmul__ = _binop('matmul') + __ror__ = _binop('ror') + __or__ = _binop('or') + __rxor__ = _binop('rxor') + __xor__ = _binop('xor') + __rand__ = _binop('rand') + __and__ = _binop('and') + __rpow__ = _binop('rpow') + __pow__ = _binop('pow') + __rdivmod__ = _binop('rdivmod') + __divmod__ = _binop('divmod') + __rmod__ = _binop('rmod') + __mod__ = _binop('mod') + __rfloordiv__ = _binop('rfloordiv') + __floordiv__ = _binop('floordiv') + __rtruediv__ = _binop('rtruediv') + __truediv__ = _binop('truediv') + if sys.version < '3': + __div__ = _binop('div') + __rdiv__ = _binop('rdiv') + __rmul__ = _binop('rmul') + __mul__ = _binop('mul') + __rsub__ = _binop('rsub') + __sub__ = _binop('sub') + __radd__ = _binop('radd') + __add__ = _binop('add') + + __ge__ = _binop('ge') + __gt__ = _binop('gt') + __le__ = _binop('le') + __lt__ = _binop('lt') + + # having ne and eq use .eval on a slice group creates an ndarray, for which __eq__ does not return a single value, + # which means, it cannot be in a mapping/Axis, but this is no longer a problem, since we do not create axes with + # LGroup labels anymore anyway + __ne__ = _binop('ne') + __eq__ = _binop('eq') + + def set(self): + """Creates LSet from this group + + Returns + ------- + LSet + """ + return LSet(self.eval(), self.name, self.axis) + + def union(self, other): + """Returns (set) union of this label group and other. + + Labels relative order will be kept intact, but only unique labels will be returned. Labels from this group will + be before labels from other. + + Parameters + ---------- + other : Group or any sequence of labels + other labels + + Returns + ------- + LSet + + Examples + -------- + >>> from larray import Axis + >>> a = Axis('a=a0..a2') + >>> a['a0', 'a1'].union(a['a1', 'a2']) + a['a0', 'a1', 'a2'].set() + >>> a['a0', 'a1'].union('a1,a2') + a['a0', 'a1', 'a2'].set() + >>> a['a0', 'a1'].union(['a1', 'a2']) + a['a0', 'a1', 'a2'].set() + """ + return self.set().union(other) + + def intersection(self, other): + """Returns (set) intersection of this label group and other. + + In other words, this will return labels from this group which are also in other. Labels relative order will be + kept intact, but only unique labels will be returned. + + Parameters + ---------- + other : Group or any sequence of labels + other labels + + Returns + ------- + LSet + + Examples + -------- + >>> from larray import Axis + >>> a = Axis('a=a0..a2') + >>> a['a0', 'a1'].intersection(a['a1', 'a2']) + a['a1'].set() + >>> a['a0', 'a1'].intersection('a1,a2') + a['a1'].set() + >>> a['a0', 'a1'].intersection(['a1', 'a2']) + a['a1'].set() + """ + return self.set().intersection(other) + + def difference(self, other): + """Returns (set) difference of this label group and other. + + In other words, this will return labels from this group without those in other. Labels relative order will be + kept intact, but only unique labels will be returned. + + Parameters + ---------- + other : Group or any sequence of labels + other labels + + Returns + ------- + LSet + + Examples + -------- + >>> from larray import Axis + >>> a = Axis('a=a0..a2') + >>> a['a0', 'a1'].difference(a['a1', 'a2']) + a['a0'].set() + >>> a['a0', 'a1'].difference('a1,a2') + a['a0'].set() + >>> a['a0', 'a1'].difference(['a1', 'a2']) + a['a0'].set() + """ + return self.set().difference(other) + + def __contains__(self, item): + if isinstance(item, Group): + item = item.eval() + return item in self.eval() + + def startingwith(self, prefix): + """ + Returns a group with the labels starting with the specified string. + + Parameters + ---------- + prefix : str or Group + The prefix to search for. + + Returns + ------- + LGroup + Group containing all the labels starting with the given string. + + Examples + -------- + >>> from larray import Axis + >>> people = Axis(['Bruce Wayne', 'Arthur Dent', 'Harvey Dent'], 'people') + >>> group = people.endingwith('Dent') + >>> group + people['Arthur Dent', 'Harvey Dent'] + >>> group.startingwith('Art') + people['Arthur Dent'] + """ + if isinstance(prefix, Group): + prefix = prefix.eval() + return LGroup([v for v in self.eval() if v.startswith(prefix)], axis=self.axis) + + def endingwith(self, suffix): + """ + Returns a group with the labels ending with the specified string. + + Parameters + ---------- + suffix : str or Group + The suffix to search for. + + Returns + ------- + LGroup + Group containing all the labels ending with the given string. + + Examples + -------- + >>> from larray import Axis + >>> people = Axis(['Bruce Wayne', 'Bruce Willis', 'Arthur Dent'], 'people') + >>> group = people.startingwith('Bru') + >>> group + people['Bruce Wayne', 'Bruce Willis'] + >>> people.endingwith('yne') + people['Bruce Wayne'] + """ + if isinstance(suffix, Group): + suffix = suffix.eval() + return LGroup([v for v in self.eval() if v.endswith(suffix)], axis=self.axis) + + def matching(self, pattern): + """ + Returns a group with all the labels matching the specified pattern (regular expression). + + Parameters + ---------- + pattern : str or Group + Regular expression (regex). + + Returns + ------- + LGroup + Group containing all the labels matching the pattern. + + Notes + ----- + See `Regular Expression `_ + for more details about how to build a pattern. + + Examples + -------- + >>> from larray import Axis + >>> people = Axis(['Bruce Wayne', 'Bruce Willis', 'Arthur Dent'], 'people') + + All labels containing "B" and "e" with exactly 3 characters in between are given by + + >>> group = people.matching('B...e') + >>> group + people['Bruce Wayne', 'Bruce Willis'] + + Within that group, all labels containing any characters then W then any characters then s are given by + >>> group.matching('.*W.*s') + people['Bruce Willis'] + """ + if isinstance(pattern, Group): + pattern = pattern.eval() + rx = re.compile(pattern) + return LGroup([v for v in self.eval() if rx.match(v)], axis=self.axis) + + def containing(self, substring): + """ + Returns a group with all the labels containing the specified substring. + + Parameters + ---------- + substring : str or Group + The substring to search for. + + Returns + ------- + LGroup + Group containing all the labels containing the substring. + + Examples + -------- + >>> from larray import Axis + >>> people = Axis(['Bruce Wayne', 'Bruce Willis', 'Arthur Dent'], 'people') + >>> group = people.startingwith('Bru') + >>> group + people['Bruce Wayne', 'Bruce Willis'] + >>> group.containing('Will') + people['Bruce Willis'] + """ + if isinstance(substring, Group): + substring = substring.eval() + return LGroup([v for v in self.eval() if substring in v], axis=self.axis) + + # this makes range(LGroup(int)) possible + def __index__(self): + return self.eval().__index__() + + def __int__(self): + # 'str' objects have no '__int__' attribute, so this is better than calling __int__ explicitly + return int(self.eval()) + + def __float__(self): + # 'str' objects have no '__float__' attribute, so this is better than calling __float__ explicitly + return float(self.eval()) + + def __array__(self, dtype=None): + return np.asarray(self.eval(), dtype=dtype) + + def __dir__(self): + # called by dir() and tab-completion at the interactive prompt, must return a list of any valid getattr key. + # dir() takes care of sorting but not uniqueness, so we must ensure that. + return list(set(dir(self.eval())) | set(self.__dict__.keys()) | set(dir(self.__class__))) + + def __getattr__(self, key): + if key == '__array_struct__': + raise AttributeError("'Group' object has no attribute '__array_struct__'") + else: + return getattr(self.eval(), key) + + def __hash__(self): + # to_tick & to_key are partially opposite operations but this standardize on a single notation so that they can + # all target each other. eg, this removes spaces in "list strings", instead of hashing them directly + # XXX: but we might want to include that normalization feature in to_tick directly, instead of using to_key + # explicitly here + # XXX: we might want to make hash use the position along the axis instead of the labels so that if an axis has + # ambiguous labels, they do not hash to the same thing. + # XXX: for performance reasons, I think hash should not evaluate slices. It should only translate pos bounds to + # labels or vice versa. We would loose equality between list Groups and equivalent slice groups but that + # is a small price to pay if the performance impact is large. + # the problem with using self.translate() is that we cannot compare groups without axis + # return hash(_to_tick(self.translate())) + return hash(_to_tick(self.key)) + + +def remove_nested_groups(key): + # "struct" key with Group elements -> key without Group + # TODO: ideally if all key elements are groups on the same Axis, we should make a group on that axis + # for slice bounds, watch out for None + if isinstance(key, slice): + key_start, key_stop = key.start, key.stop + start = key_start.to_label() if isinstance(key_start, Group) else key_start + stop = key_stop.to_label() if isinstance(key_stop, Group) else key_stop + return slice(start, stop, key.step) + elif isinstance(key, (tuple, list)): + res = [k.to_label() if isinstance(k, Group) else k for k in key] + return tuple(res) if isinstance(key, tuple) else res + else: + return key + + +class LGroup(Group): + """Label group. + + Represents a subset of labels of an axis. + + Parameters + ---------- + key : key + Anything usable for indexing. A key should be either sequence of labels, a slice with label bounds or a string. + name : str, optional + Name of the group. + axis : int, str, Axis, optional + Axis for group. + + Examples + -------- + >>> from larray import Axis, X + >>> age = Axis('0..100', 'age') + >>> teens = X.age[10:19].named('teens') + >>> teens + X.age[10:19] >> 'teens' + >>> teens = X.age[10:19] >> 'teens' + >>> teens + X.age[10:19] >> 'teens' + """ + format_string = "{axis}[{key}]" + + def __init__(self, key, name=None, axis=None): + key = _to_key(key) + Group.__init__(self, key, name, axis) + + # XXX: return IGroup instead? + def translate(self, bound=None, stop=False): + """ + compute position(s) of group + """ + if bound is None: + bound = self.key + if isinstance(self.axis, ABCAxis): + pos = self.axis.index(bound) + return pos + int(stop) if np.isscalar(pos) else pos + else: + raise ValueError("Cannot translate an LGroup without axis") + + def to_label(self): + return self.key + + def eval(self): + if isinstance(self.key, slice): + if isinstance(self.axis, ABCAxis): + # expand slices + return self.axis.labels[self.translate()] + else: + return self.key + # raise ValueError("Cannot evaluate a slice group without axis") + else: + # we do not check the group labels are actually valid on Axis + return self.key + + +class LSet(LGroup): + """Label set. + + Represents a set of (unique) labels of an axis. + + Parameters + ---------- + key : key + Anything usable for indexing. A key should be either sequence of labels, a slice with label bounds or a string. + name : str, optional + Name of the set. + axis : int, str, Axis, optional + Axis for set. + + Examples + -------- + >>> from larray import Axis + >>> letters = Axis('letters=a..z') + >>> abc = letters[':c'].set() >> 'abc' + >>> abc + letters['a', 'b', 'c'].set() >> 'abc' + >>> abc & letters['b:d'] + letters['b', 'c'].set() + """ + format_string = "{axis}[{key}].set()" + + def __init__(self, key, name=None, axis=None): + key = _to_key(key) + if isinstance(key, LGroup): + if name is None: + name = key.name + if axis is None: + axis = key.axis + if not isinstance(key, LSet): + key = key.eval() + if np.isscalar(key): + key = [key] + key = OrderedSet(key) + LGroup.__init__(self, key, name, axis) + + # method factory + def _binop(opname, c): + op_fullname = '__%s__' % opname + + # TODO: implement this in a delayed fashion for reference axes + def opmethod(self, other): + if not isinstance(other, LSet): + other = LSet(other) + axis = self.axis if self.axis is not None else other.axis + + # setting a meaningful name is hard when either one has no name + if self.name is not None and other.name is not None: + name = '%s %s %s' % (self.name, c, other.name) + else: + name = None + # TODO: implement this in a more efficient way for ndarray keys which can be large + result_set = getattr(self.key, op_fullname)(other.key) + return LSet(result_set, name=name, axis=axis) + opmethod.__name__ = op_fullname + return opmethod + + union = _binop('or', '|') + __or__ = union + + intersection = _binop('and', '&') + __and__ = intersection + + difference = _binop('sub', '-') + __sub__ = difference + + +class IGroup(Group): + """Index Group. + + Represents a subset of indices of an axis. + + Parameters + ---------- + key : key + Anything usable for indexing. A key should be either a single position, a sequence of positions, or a slice + with integer bounds. + name : str, optional + Name of the group. + axis : int, str, Axis, optional + Axis for group. + """ + format_string = "{axis}.i[{key}]" + + def translate(self, bound=None, stop=False): + """ + compute position(s) of group + """ + if bound is not None: + return bound + else: + return self.key + + def to_label(self): + if isinstance(self.axis, ABCAxis): + labels = self.axis.labels + key = self.key + if isinstance(key, slice): + start = labels[key.start] if key.start is not None else None + # FIXME: this probably breaks for reverse slices + # - 1 because IGroup slice stop is excluded while LGroup slice stop is included + stop = labels[key.stop - 1] if key.stop is not None else None + return slice(start, stop, key.step) + else: + # key is a single int or tuple/list/array of them + return labels[key] + else: + raise ValueError("Cannot evaluate a positional group without axis") + + def eval(self): + if isinstance(self.axis, ABCAxis): + return self.axis.labels[self.key] + else: + raise ValueError("Cannot evaluate a positional group without axis") + + def __hash__(self): + return hash(('IGroup', _to_tick(self.key))) + +PGroup = renamed_to(IGroup, 'PGroup') diff --git a/larray/core/session.py b/larray/core/session.py new file mode 100644 index 000000000..23fde4913 --- /dev/null +++ b/larray/core/session.py @@ -0,0 +1,1095 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function + +import os +import sys +import warnings +from collections import OrderedDict + +import numpy as np + +from larray.core.axis import Axis +from larray.core.array import LArray, get_axes, ndtest, zeros, zeros_like, sequence, aslarray +from larray.util.misc import float_error_handler_factory, is_interactive_interpreter, renamed_to, inverseop +from larray.inout.session import check_pattern, handler_classes, ext_default_engine + + +# XXX: inherit from OrderedDict or LArray? +class Session(object): + """ + Groups several array objects together. + + Parameters + ---------- + args : str or dict of str, array or iterable of tuples (str, array) + Name of file to load or dictionary containing couples (name, array). + kwargs : dict of str, array + List of arrays to add written as 'name'=array, ... + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) + + create a Session by passing a list of pairs (name, array) + + >>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)]) + + create a Session using keyword arguments (but you lose order on Python < 3.6) + + >>> s = Session(arr1=arr1, arr2=arr2, arr3=arr3) + + create a Session by passing a dictionary (but you lose order on Python < 3.6) + + >>> s = Session({'arr1': arr1, 'arr2': arr2, 'arr3': arr3}) + + load Session from file + + >>> s = Session('my_session.h5') # doctest: +SKIP + """ + def __init__(self, *args, **kwargs): + object.__setattr__(self, '_objects', OrderedDict()) + + if len(args) == 1: + a0 = args[0] + if isinstance(a0, str): + # assume a0 is a filename + self.load(a0) + else: + items = a0.items() if isinstance(a0, dict) else a0 + # assume we have an iterable of tuples + for k, v in items: + self[k] = v + else: + self.add(*args, **kwargs) + + # XXX: behave like a dict and return keys instead? + def __iter__(self): + return iter(self.values()) + + def add(self, *args, **kwargs): + """ + Adds objects to the current session. + + Parameters + ---------- + args : array + List of objects to add. Objects must have an attribute 'name'. + kwargs : dict of str, array + List of objects to add written as 'name'=array, ... + + Examples + -------- + >>> s = Session() + >>> axis1, axis2 = Axis('x=x0..x2'), Axis('y=y0..y2') + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) + >>> s.add(axis1, axis2, arr1=arr1, arr2=arr2, arr3=arr3) + >>> # print item's names in sorted order + >>> s.names + ['arr1', 'arr2', 'arr3', 'x', 'y'] + """ + for arg in args: + self[arg.name] = arg + for k, v in kwargs.items(): + self[k] = v + + def _ipython_key_completions_(self): + return list(self.keys()) + + def __getitem__(self, key): + if isinstance(key, int): + keys = list(self.keys()) + return self._objects[keys[key]] + elif isinstance(key, LArray): + assert np.issubdtype(key.dtype, np.bool_) + assert key.ndim == 1 + # only keep True values + truenames = key[key].axes[0].labels + return Session([(name, self[name]) for name in truenames]) + elif isinstance(key, (tuple, list)): + assert all(isinstance(k, str) for k in key) + return Session([(k, self[k]) for k in key]) + else: + return self._objects[key] + + def get(self, key, default=None): + """ + Returns the array object corresponding to the key. + If the key doesn't correspond to any array object, a default one can be returned. + + Parameters + ---------- + key : str + Name of the array. + default : array, optional + Returned array if the key doesn't correspond to any array of the current session. + + Returns + ------- + LArray + Array corresponding to the given key or a default one if not found. + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) + >>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)]) + >>> arr = s.get('arr1') + >>> arr + a\\b b0 b1 + a0 0 1 + a1 2 3 + >>> arr = s.get('arr4', zeros('a=a0,a1;b=b0,b1', dtype=int)) + >>> arr + a\\b b0 b1 + a0 0 0 + a1 0 0 + """ + try: + return self[key] + except KeyError: + return default + + def __setitem__(self, key, value): + self._objects[key] = value + + def __delitem__(self, key): + del self._objects[key] + + def __getattr__(self, key): + if key in self._objects: + return self._objects[key] + else: + raise AttributeError("'{}' object has no attribute '{}'".format(self.__class__.__name__, key)) + + def __setattr__(self, key, value): + self._objects[key] = value + + def __delattr__(self, key): + del self._objects[key] + + def __dir__(self): + return list(set(dir(self.__class__)) | set(self.keys())) + + # needed to make *un*pickling work (because otherwise, __getattr__ is called before ._objects exists, which leads to + # an infinite recursion) + def __getstate__(self): + return self.__dict__ + + def __setstate__(self, d): + # equivalent to self.__dict__ = d (we need this form because __setattr__ is overridden) + object.__setattr__(self, '__dict__', d) + + def load(self, fname, names=None, engine='auto', display=False, **kwargs): + """ + Loads array objects from a file, or several .csv files. + + WARNING: never load a file using the pickle engine (.pkl or .pickle) from an untrusted source, as it can lead + to arbitrary code execution. + + Parameters + ---------- + fname : str + This can be either the path to a single file, a path to a directory containing .csv files or a pattern + representing several .csv files. + names : list of str, optional + List of arrays to load. If `fname` is None, list of paths to CSV files. + Defaults to all valid objects present in the file/directory. + engine : {'auto', 'pandas_csv', 'pandas_hdf', 'pandas_excel', 'xlwings_excel', 'pickle'}, optional + Load using `engine`. Defaults to 'auto' (use default engine for the format guessed from the file extension). + display : bool, optional + Whether or not to display which file is being worked on. Defaults to False. + + Examples + -------- + In one module + + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) # doctest: +SKIP + >>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)]) # doctest: +SKIP + >>> s.save('input.h5') # doctest: +SKIP + + In another module + + >>> s = Session() # doctest: +SKIP + >>> s.load('input.h5', ['arr1', 'arr2', 'arr3']) # doctest: +SKIP + >>> arr1, arr2, arr3 = s['arr1', 'arr2', 'arr3'] # doctest: +SKIP + >>> # only if you know the order of arrays stored in session + >>> arr1, arr2, arr3 = s.values() # doctest: +SKIP + + Using .csv files (assuming the same session as above) + + >>> s.save('data') # doctest: +SKIP + >>> s = Session() # doctest: +SKIP + >>> # load all .csv files starting with "output" in the data directory + >>> s.load('data') # doctest: +SKIP + >>> # or equivalently in this case + >>> s.load('data/arr*.csv') # doctest: +SKIP + """ + if display: + print("opening", fname) + if fname is None: + if all([os.path.splitext(name)[1] == '.csv' for name in names]): + engine = ext_default_engine['csv'] + else: + raise ValueError("List of paths to only CSV files expected. Got {}".format(names)) + if engine == 'auto': + _, ext = os.path.splitext(fname) + ext = ext.strip('.') if '.' in ext else 'csv' + engine = ext_default_engine[ext] + handler_cls = handler_classes[engine] + handler = handler_cls(fname) + arrays = handler.read_arrays(names, display=display, **kwargs) + for k, v in arrays.items(): + self[k] = v + + def save(self, fname, names=None, engine='auto', overwrite=True, display=False, **kwargs): + """ + Dumps all array objects from the current session to a file. + + Parameters + ---------- + fname : str + Path for the dump. + names : list of str or None, optional + List of names of objects to dump. If `fname` is None, list of paths to CSV files. + Defaults to all objects present in the Session. + engine : {'auto', 'pandas_csv', 'pandas_hdf', 'pandas_excel', 'xlwings_excel', 'pickle'}, optional + Dump using `engine`. Defaults to 'auto' (use default engine for the format guessed from the file extension). + overwrite: bool, optional + Whether or not to overwrite an existing file, if any. Ignored for CSV files. If False, file is updated. + Defaults to True. + display : bool, optional + Whether or not to display which file is being worked on. Defaults to False. + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) # doctest: +SKIP + >>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)]) # doctest: +SKIP + + Save all arrays + + >>> s.save('output.h5') # doctest: +SKIP + + Save only some arrays + + >>> s.save('output.h5', ['arr1', 'arr3']) # doctest: +SKIP + + Update file + + >>> arr1, arr4 = ndtest((3, 3)), ndtest((2, 3)) # doctest: +SKIP + >>> s2 = Session([('arr1', arr1), ('arr4', arr4)]) # doctest: +SKIP + >>> # replace arr1 and add arr4 in file output.h5 + >>> s2.save('output.h5', overwrite=False) # doctest: +SKIP + """ + if engine == 'auto': + _, ext = os.path.splitext(fname) + ext = ext.strip('.') if '.' in ext else 'csv' + engine = ext_default_engine[ext] + handler_cls = handler_classes[engine] + handler = handler_cls(fname, overwrite) + items = self.filter(kind=LArray).items() + if names is not None: + names_set = set(names) + items = [(k, v) for k, v in items if k in names_set] + handler.dump_arrays(items, display=display, **kwargs) + + def to_globals(self, names=None, depth=0, warn=True, inplace=False): + """ + Create global variables out of objects in the session. + + Parameters + ---------- + names : list of str or None, optional + List of names of objects to convert to globals. Defaults to all objects present in the Session. + depth : int, optional + depth of call stack where to create the variables. 0 is where to_globals was called, 1 the caller of + to_globals, etc. Defaults to 0. + warn : bool, optional + Whether or not to warn the user that this method should only be used in an interactive console (see below). + Defaults to True. + inplace : bool, optional + If True, to_globals will assume all arrays already exist and have the same axes and will replace their + content instead of creating new variables. Non array variables in the session will be ignored. + Defaults to False. + + Notes + ----- + This method should usually only be used in an interactive console and not in a script. Code editors are + confused by this kind of manipulation and will likely consider as invalid the code using variables created in + this way. Additionally, when using this method auto-completion, "show definition", "go to declaration" and + other similar code editor features will probably not work for the variables created in this way and any + variable derived from them. + + Examples + -------- + >>> s = Session(arr1=ndtest(3), arr2=ndtest((2, 2))) + >>> s.to_globals() + >>> arr1 + a a0 a1 a2 + 0 1 2 + >>> arr2 + a\\b b0 b1 + a0 0 1 + a1 2 3 + """ + # noinspection PyProtectedMember + if warn and not is_interactive_interpreter(): + warnings.warn("Session.to_globals should usually only be used in interactive consoles and not in scripts. " + "Use warn=False to deactivate this warning.", + RuntimeWarning, stacklevel=2) + d = sys._getframe(depth + 1).f_globals + items = self.items() + if names is not None: + names_set = set(names) + items = [(k, v) for k, v in items if k in names_set] + if inplace: + for k, v in items: + if k not in d: + raise ValueError("'{}' not found in current namespace. Session.to_globals(inplace=True) requires " + "all arrays to already exist.".format(k)) + if not isinstance(v, LArray): + continue + if not d[k].axes == v.axes: + raise ValueError("Session.to_globals(inplace=True) requires the existing (destination) arrays " + "to have the same axes than those stored in the session and this is not the case " + "for '{}'.\nexisting: {}\nsession: {}".format(k, d[k].info, v.info)) + d[k][:] = v + else: + for k, v in items: + d[k] = v + + def to_pickle(self, fname, names=None, overwrite=True, display=False, **kwargs): + """ + Dumps all array objects from the current session to a file using pickle. + + WARNING: never load a pickle file (.pkl or .pickle) from an untrusted source, as it can lead to arbitrary code + execution. + + Parameters + ---------- + fname : str + Path for the dump. + names : list of str or None, optional + List of names of objects to dump. Defaults to all objects present in the Session. + overwrite: bool, optional + Whether or not to overwrite an existing file, if any. + If False, file is updated. Defaults to True. + display : bool, optional + Whether or not to display which file is being worked on. Defaults to False. + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) # doctest: +SKIP + >>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)]) # doctest: +SKIP + + Save all arrays + + >>> s.to_pickle('output.pkl') # doctest: +SKIP + + Save only some arrays + + >>> s.to_pickle('output.pkl', ['arr1', 'arr3']) # doctest: +SKIP + """ + self.save(fname, names, ext_default_engine['pkl'], overwrite, display, **kwargs) + + dump = renamed_to(save, 'dump') + + def to_hdf(self, fname, names=None, overwrite=True, display=False, **kwargs): + """ + Dumps all array objects from the current session to an HDF file. + + Parameters + ---------- + fname : str + Path for the dump. + names : list of str or None, optional + List of names of objects to dump. Defaults to all objects present in the Session. + overwrite: bool, optional + Whether or not to overwrite an existing file, if any. + If False, file is updated. Defaults to True. + display : bool, optional + Whether or not to display which file is being worked on. Defaults to False. + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) # doctest: +SKIP + >>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)]) # doctest: +SKIP + + Save all arrays + + >>> s.to_hdf('output.h5') # doctest: +SKIP + + Save only some arrays + + >>> s.to_hdf('output.h5', ['arr1', 'arr3']) # doctest: +SKIP + """ + self.save(fname, names, ext_default_engine['hdf'], overwrite, display, **kwargs) + + dump_hdf = renamed_to(to_hdf, 'dump_hdf') + + def to_excel(self, fname, names=None, overwrite=True, display=False, **kwargs): + """ + Dumps all array objects from the current session to an Excel file. + + Parameters + ---------- + fname : str + Path for the dump. + names : list of str or None, optional + List of names of objects to dump. Defaults to all objects present in the Session. + overwrite: bool, optional + Whether or not to overwrite an existing file, if any. If False, file is updated. Defaults to True. + display : bool, optional + Whether or not to display which file is being worked on. Defaults to False. + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) # doctest: +SKIP + >>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)]) # doctest: +SKIP + + Save all arrays + + >>> s.to_excel('output.xlsx') # doctest: +SKIP + + Save only some arrays + + >>> s.to_excel('output.xlsx', ['arr1', 'arr3']) # doctest: +SKIP + """ + self.save(fname, names, ext_default_engine['xlsx'], overwrite, display, **kwargs) + + dump_excel = renamed_to(to_excel, 'dump_excel') + + def to_csv(self, fname, names=None, display=False, **kwargs): + """ + Dumps all array objects from the current session to CSV files. + + Parameters + ---------- + fname : str + Path for the directory that will contain CSV files. + names : list of str or None, optional + List of names of objects to dump. Defaults to all objects present in the Session. + display : bool, optional + Whether or not to display which file is being worked on. Defaults to False. + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) # doctest: +SKIP + >>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)]) # doctest: +SKIP + + Save all arrays + + >>> s.to_csv('./Output') # doctest: +SKIP + + Save only some arrays + + >>> s.to_csv('./Output', ['arr1', 'arr3']) # doctest: +SKIP + """ + self.save(fname, names, ext_default_engine['csv'], display=display, **kwargs) + + dump_csv = renamed_to(to_csv, 'dump_csv') + + def filter(self, pattern=None, kind=None): + """ + Returns a new session with array objects which match some criteria. + + Parameters + ---------- + pattern : str, optional + Only keep arrays whose key match `pattern`. + kind : type, optional + Only keep arrays which are instances of type `kind`. + + Returns + ------- + Session + The filtered session. + + Examples + -------- + >>> axis = Axis('a=a0..a2') + >>> test1, test2, zero1 = ndtest((2, 2)), ndtest(4), zeros((3, 2)) + >>> s = Session([('test1', test1), ('test2', test2), ('zero1', zero1), ('axis', axis)]) + + Filter using a pattern argument + + >>> s.filter(pattern='test').names + ['test1', 'test2'] + + Filter using kind argument + + >>> s.filter(kind=Axis).names + ['axis'] + """ + items = self._objects.items() + if pattern is not None: + items = [(k, v) for k, v in items if check_pattern(k, pattern)] + if kind is not None: + items = [(k, v) for k, v in items if isinstance(v, kind)] + return Session(items) + + @property + def names(self): + """ + Returns the list of names of the array objects in the session. + The list is sorted alphabetically and does not follow the internal order. + + Returns + ------- + list of str + + See Also + -------- + Session.keys + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) + >>> s = Session([('arr2', arr2), ('arr1', arr1), ('arr3', arr3)]) + >>> # print array's names in the alphabetical order + >>> s.names + ['arr1', 'arr2', 'arr3'] + + >>> # keys() follows the internal order + >>> list(s.keys()) + ['arr2', 'arr1', 'arr3'] + """ + return sorted(self._objects.keys()) + + def copy(self): + """Returns a copy of the session. + """ + # this actually *does* a copy of the internal mapping (the mapping is not reused-as is) + return Session(self._objects) + + def keys(self): + """ + Returns a view on the session's keys. + + Returns + ------- + View on the session's keys. + + See Also + -------- + Session.names + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) + >>> s = Session([('arr2', arr2), ('arr1', arr1), ('arr3', arr3)]) + >>> # similar to names by follows the internal order + >>> list(s.keys()) + ['arr2', 'arr1', 'arr3'] + + >>> # gives the names of arrays in alphabetical order + >>> s.names + ['arr1', 'arr2', 'arr3'] + """ + return self._objects.keys() + + def values(self): + """ + Returns a view on the session's values. + + Returns + ------- + View on the session's values. + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) + >>> s = Session([('arr2', arr2), ('arr1', arr1), ('arr3', arr3)]) + >>> # assuming you know the order of arrays stored in the session + >>> arr2, arr1, arr3 = s.values() + >>> # otherwise, prefer the following syntax + >>> arr1, arr2, arr3 = s['arr1', 'arr2', 'arr3'] + >>> arr1 + a\\b b0 b1 + a0 0 1 + a1 2 3 + """ + return self._objects.values() + + def items(self): + """ + Returns a view of the session’s items ((key, value) pairs). + + Returns + ------- + View on the session's items. + + Examples + -------- + >>> arr1, arr2, arr3 = ndtest((2, 2)), ndtest(4), ndtest((3, 2)) + >>> # make the test pass on both Windows and Linux + >>> arr1, arr2, arr3 = arr1.astype(np.int64), arr2.astype(np.int64), arr3.astype(np.int64) + >>> s = Session([('arr2', arr2), ('arr1', arr1), ('arr3', arr3)]) + >>> for k, v in s.items(): + ... print("{}: {}".format(k, v.info)) + arr2: 4 + a [4]: 'a0' 'a1' 'a2' 'a3' + dtype: int64 + memory used: 32 bytes + arr1: 2 x 2 + a [2]: 'a0' 'a1' + b [2]: 'b0' 'b1' + dtype: int64 + memory used: 32 bytes + arr3: 3 x 2 + a [3]: 'a0' 'a1' 'a2' + b [2]: 'b0' 'b1' + dtype: int64 + memory used: 48 bytes + """ + return self._objects.items() + + def __repr__(self): + return 'Session({})'.format(', '.join(self.keys())) + + def __len__(self): + return len(self._objects) + + # binary operations are dispatched element-wise to all arrays (we consider Session as an array-like) + def _binop(opname): + opfullname = '__%s__' % opname + + def opmethod(self, other): + self_keys = set(self.keys()) + all_keys = list(self.keys()) + if hasattr(other, 'keys'): + all_keys += [n for n in other.keys() if n not in self_keys] + with np.errstate(call=_session_float_error_handler): + res = [] + for name in all_keys: + self_array = self.get(name, np.nan) + other_operand = other.get(name, np.nan) if hasattr(other, 'get') else other + try: + res_array = getattr(self_array, opfullname)(other_operand) + # TypeError for str arrays, ValueError for incompatible axes, ... + except Exception: + res_array = np.nan + # this should only ever happen when self_array is a non Array (eg. nan) + if res_array is NotImplemented: + try: + res_array = getattr(other_operand, '__%s__' % inverseop(opname))(self_array) + # TypeError for str arrays, ValueError for incompatible axes, ... + except Exception: + res_array = np.nan + res.append((name, res_array)) + return Session(res) + opmethod.__name__ = opfullname + return opmethod + + __add__ = _binop('add') + __radd__ = _binop('radd') + __sub__ = _binop('sub') + __rsub__ = _binop('rsub') + __mul__ = _binop('mul') + __rmul__ = _binop('rmul') + __truediv__ = _binop('truediv') + __rtruediv__ = _binop('rtruediv') + + __eq__ = _binop('eq') + __ne__ = _binop('ne') + + # element-wise method factory + # unary operations are (also) dispatched element-wise to all arrays + def _unaryop(opname): + opfullname = '__%s__' % opname + + def opmethod(self): + with np.errstate(call=_session_float_error_handler): + res = [] + for k, v in self.items(): + try: + res_array = getattr(v, opfullname)() + except Exception: + res_array = np.nan + res.append((k, res_array)) + return Session(res) + opmethod.__name__ = opfullname + return opmethod + + __neg__ = _unaryop('neg') + __pos__ = _unaryop('pos') + __abs__ = _unaryop('abs') + __invert__ = _unaryop('invert') + + def array_equals(self, other): + """Test if arrays of the current session are equal to those of another session. + + Equivalent to apply :py:meth:`LArray.equals` with flag nan_equals=True to all arrays from two sessions. + + Parameters + ---------- + other : Session + Session to compare with. + + Returns + ------- + Boolean LArray + + See Also + -------- + Session.equals + + Examples + -------- + >>> s1 = Session([('arr1', ndtest(2)), ('arr2', ndtest((2, 2)))]) + >>> s2 = Session([('arr1', ndtest(2)), ('arr2', ndtest((2, 2)))]) + >>> s1.array_equals(s2) + name arr1 arr2 + True True + + Different value(s) + + >>> s2.arr1['a1'] = 0 + >>> s1.array_equals(s2) + name arr1 arr2 + False True + + Different label(s) + + >>> s2.arr2 = ndtest("b=b0,b1; a=a0,a1") + >>> s1.array_equals(s2) + name arr1 arr2 + False False + + Extra/missing array(s) + + >>> s2.arr3 = ndtest((3, 3)) + >>> s1.array_equals(s2) + name arr1 arr2 arr3 + False False False + """ + self_keys = set(self.keys()) + all_keys = list(self.keys()) + [n for n in other.keys() if n not in self_keys] + def larray_nan_equal(a1, a2): + try: + a1 = aslarray(a1) + except Exception: + return False + return a1.equals(a2, nan_equals=True) + res = [larray_nan_equal(self.get(key), other.get(key)) for key in all_keys] + return LArray(res, [Axis(all_keys, 'name')]) + + def equals(self, other): + """Test if all arrays of the current session are equal to those of another session. + + Parameters + ---------- + other : Session + Session to compare with. + + Returns + ------- + True if arrays of both sessions are all equal, False otherwise. + + See Also + -------- + Session.array_equals + + Examples + -------- + >>> s1 = Session([('arr1', ndtest(2)), ('arr2', ndtest((2, 2)))]) + >>> s2 = Session([('arr1', ndtest(2)), ('arr2', ndtest((2, 2)))]) + >>> s1.equals(s2) + True + + Different value(s) + + >>> s2.arr1['a1'] = 0 + >>> s1.equals(s2) + False + + Different label(s) + + >>> s2 = s1.copy() + >>> s2.arr2 = ndtest("b=b0,b1; a=a0,a1") + >>> s1.equals(s2) + False + + Extra/missing array(s) + + >>> s2 = s1.copy() + >>> s2.arr3 = ndtest((3, 3)) + >>> s1.equals(s2) + False + """ + return all(self.array_equals(other)) + + def transpose(self, *args): + """Reorder axes of arrays in session, ignoring missing axes for each array. + + Parameters + ---------- + *args + Accepts either a tuple of axes specs or axes specs as `*args`. Omitted axes keep their order. + Use ... to avoid specifying intermediate axes. Axes missing in an array are ignored. + + Returns + ------- + Session + Session with each array with reordered axes where appropriate. + + See Also + -------- + LArray.transpose + + Examples + -------- + Let us create a test session and a small helper function to display sessions as a short summary. + + >>> arr1 = ndtest((2, 2, 2)) + >>> arr2 = ndtest((2, 2)) + >>> sess = Session([('arr1', arr1), ('arr2', arr2)]) + >>> def print_summary(s): + ... print(s.summary("{name} -> {axes_names}")) + >>> print_summary(sess) + arr1 -> a, b, c + arr2 -> a, b + + Put 'b' axis in front of all arrays + + >>> print_summary(sess.transpose('b')) + arr1 -> b, a, c + arr2 -> b, a + + Axes missing on an array are ignored ('c' for arr2 in this case) + + >>> print_summary(sess.transpose('c', 'b')) + arr1 -> c, b, a + arr2 -> b, a + + Use ... to move axes to the end + + >>> print_summary(sess.transpose(..., 'a')) # doctest: +SKIP + arr1 -> b, c, a + arr2 -> b, a + """ + def lenient_transpose(v, axes): + # filter out axes not in arr.axes + return v.transpose([a for a in axes if a in v.axes or a is Ellipsis]) + return self.apply(lenient_transpose, args) + + def compact(self, display=False): + """ + Detects and removes "useless" axes (ie axes for which values are constant over the whole axis) for all array + objects in session + + Parameters + ---------- + display : bool, optional + Whether or not to display a message for each array that is compacted + + Returns + ------- + Session + A new session containing all compacted arrays + + Examples + -------- + >>> arr1 = sequence('b=b0..b2', ndtest(3), zeros_like(ndtest(3))) + >>> arr1 + a\\b b0 b1 b2 + a0 0 0 0 + a1 1 1 1 + a2 2 2 2 + >>> compact_ses = Session(arr1=arr1).compact(display=True) + arr1 was constant over {b} + >>> compact_ses.arr1 + a a0 a1 a2 + 0 1 2 + """ + new_items = [] + for k, v in self._objects.items(): + compacted = v.compact() + if compacted is not v and display: + print(k, "was constant over", get_axes(v) - get_axes(compacted)) + new_items.append((k, compacted)) + return Session(new_items) + + def apply(self, func, *args, **kwargs): + """ + Apply function `func` on elements of the session and return a new session. + + Parameters + ---------- + func : function + Function to apply to each element of the session. It should take a single `element` argument and return + a single value. + *args : any + Any extra arguments are passed to the function + kind : type or tuple of types, optional + Type(s) of elements `func` will be applied to. Other elements will be left intact. Use ´kind=object´ to + apply to all kinds of objects. Defaults to LArray. + **kwargs : any + Any extra keyword arguments are passed to the function + + Returns + ------- + Session + A new session containing all processed elements + + Examples + -------- + >>> arr1 = ndtest(2) + >>> arr1 + a a0 a1 + 0 1 + >>> arr2 = ndtest(3) + >>> arr2 + a a0 a1 a2 + 0 1 2 + >>> sess1 = Session([('arr1', arr1), ('arr2', arr2)]) + >>> sess1 + Session(arr1, arr2) + >>> def increment(array): + ... return array + 1 + >>> sess2 = sess1.apply(increment) + >>> sess2.arr1 + a a0 a1 + 1 2 + >>> sess2.arr2 + a a0 a1 a2 + 1 2 3 + + You may also pass extra arguments or keyword arguments to the function + + >>> def change(array, increment=1, multiplier=1): + ... return (array + increment) * multiplier + >>> sess2 = sess1.apply(change, 2, 2) + >>> sess2 = sess1.apply(change, 2, multiplier=2) + >>> sess2.arr1 + a a0 a1 + 4 6 + >>> sess2.arr2 + a a0 a1 a2 + 4 6 8 + """ + kind = kwargs.pop('kind', LArray) + return Session([(k, func(v, *args, **kwargs) if isinstance(v, kind) else v) for k, v in self.items()]) + + def summary(self, template=None): + """ + Returns a summary of the content of the session. + + Parameters + ---------- + template: str + Template describing how items are summarized (see examples). + Available arguments are 'name', 'axes_names' and 'title' + + Returns + ------- + str + Short representation of the content of the session. +. + Examples + -------- + >>> arr1 = ndtest((2, 2), title='array 1') + >>> arr2 = ndtest(4, title='array 2') + >>> arr3 = ndtest((3, 2), title='array 3') + >>> s = Session([('arr1', arr1), ('arr2', arr2), ('arr3', arr3)]) + >>> print(s.summary()) # doctest: +NORMALIZE_WHITESPACE + arr1: a, b + array 1 + arr2: a + array 2 + arr3: a, b + array 3 + >>> print(s.summary("{name} -> {axes_names}")) + arr1 -> a, b + arr2 -> a + arr3 -> a, b + """ + if template is None: + template = "{name}: {axes_names}\n {title}\n" + templ_kwargs = [{'name': k, + 'axes_names': ', '.join(v.axes.display_names), + 'title': v.title} for k, v in self.items()] + return '\n'.join(template.format(**kwargs) for kwargs in templ_kwargs) + + +def _exclude_private_vars(vars_dict): + return {k: v for k, v in vars_dict.items() if not k.startswith('_')} + + +def local_arrays(depth=0, include_private=False): + """ + Returns a session containing all local arrays sorted in alphabetical order. + + Parameters + ---------- + depth: int + depth of call frame to inspect. 0 is where `local_arrays` was called, 1 the caller of `local_arrays`, etc. + include_private: boolean, optional + Whether or not to include private local arrays (i.e. arrays starting with `_`). Defaults to False. + + Returns + ------- + Session + """ + # noinspection PyProtectedMember + d = sys._getframe(depth + 1).f_locals + if not include_private: + d = _exclude_private_vars(d) + return Session((k, d[k]) for k in sorted(d.keys()) if isinstance(d[k], LArray)) + + +def global_arrays(depth=0, include_private=False): + """ + Returns a session containing all global arrays sorted in alphabetical order. + + Parameters + ---------- + depth: int + depth of call frame to inspect. 0 is where `global_arrays` was called, 1 the caller of `global_arrays`, etc. + include_private: boolean, optional + Whether or not to include private globals arrays (i.e. arrays starting with `_`). Defaults to False. + + Returns + ------- + Session + """ + # noinspection PyProtectedMember + d = sys._getframe(depth + 1).f_globals + if not include_private: + d = _exclude_private_vars(d) + return Session((k, d[k]) for k in sorted(d.keys()) if isinstance(d[k], LArray)) + + +def arrays(depth=0, include_private=False): + """ + Returns a session containing all available arrays (whether they are defined in local or global variables) sorted in + alphabetical order. Local arrays take precedence over global ones (if a name corresponds to both a local + and a global variable, the local array will be returned). + + Parameters + ---------- + depth: int + depth of call frame to inspect. 0 is where `arrays` was called, 1 the caller of `arrays`, etc. + include_private: boolean, optional + Whether or not to include private arrays (i.e. arrays starting with `_`). Defaults to False. + + Returns + ------- + Session + """ + # noinspection PyProtectedMember + caller_frame = sys._getframe(depth + 1) + global_vars = caller_frame.f_globals + local_vars = caller_frame.f_locals + + if not include_private: + global_vars = _exclude_private_vars(global_vars) + local_vars = _exclude_private_vars(local_vars) + + # We must first get all variables *then* filter by type, otherwise we could return a global array which is not + # currently available because it is shadowed by a local non-array variable. + all_keys = sorted(set(global_vars.keys()) | set(local_vars.keys())) + combined_vars = [(k, local_vars[k] if k in local_vars else global_vars[k]) + for k in all_keys] + return Session((k, v) for k, v in combined_vars if isinstance(v, LArray)) + + +_session_float_error_handler = float_error_handler_factory(4) diff --git a/larray/core/ufuncs.py b/larray/core/ufuncs.py new file mode 100644 index 000000000..9b211846e --- /dev/null +++ b/larray/core/ufuncs.py @@ -0,0 +1,205 @@ +# numpy ufuncs +# http://docs.scipy.org/doc/numpy/reference/routines.math.html + +import numpy as np + +from larray.core.array import LArray, make_numpy_broadcastable + +__all__ = [ + # Trigonometric functions + 'sin', 'cos', 'tan', 'arcsin', 'arccos', 'arctan', 'hypot', 'arctan2', 'degrees', 'radians', 'unwrap', + # 'deg2rad', 'rad2deg', + + # Hyperbolic functions + 'sinh', 'cosh', 'tanh', 'arcsinh', 'arccosh', 'arctanh', + + # Rounding + 'round', 'around', 'round_', 'rint', 'fix', 'floor', 'ceil', 'trunc', + + # Sums, products, differences + # 'prod', 'sum', 'nansum', 'cumprod', 'cumsum', + + # cannot use a simple wrapped ufunc because those ufuncs do not preserve shape or dimensions so labels are wrong + # 'diff', 'ediff1d', 'gradient', 'cross', 'trapz', + + # Exponents and logarithms + 'exp', 'expm1', 'exp2', 'log', 'log10', 'log2', 'log1p', 'logaddexp', 'logaddexp2', + + # Other special functions + 'i0', 'sinc', + + # Floating point routines + 'signbit', 'copysign', 'frexp', 'ldexp', + + # Arithmetic operations + # 'add', 'reciprocal', 'negative', 'multiply', 'divide', 'power', 'subtract', 'true_divide', 'floor_divide', + # 'fmod', 'mod', 'modf', 'remainder', + + # Handling complex numbers + 'angle', 'real', 'imag', 'conj', + + # Miscellaneous + 'convolve', 'clip', 'sqrt', + # 'square', + 'absolute', 'fabs', 'sign', 'maximum', 'minimum', 'fmax', 'fmin', 'nan_to_num', 'real_if_close', + 'interp', 'where', 'isnan', 'isinf', + 'inverse', +] + + +def broadcastify(func): + # intentionally not using functools.wraps, because it does not work for wrapping a function from another module + def wrapper(*args, **kwargs): + # TODO: normalize args/kwargs like in LIAM2 so that we can also broadcast if args are given via kwargs + # (eg out=) + args, combined_axes = make_numpy_broadcastable(args) + + # We pass only raw numpy arrays to the ufuncs even though numpy is normally meant to handle those case itself + # via __array_wrap__ + + # There is a problem with np.clip though (and possibly other ufuncs): np.clip is roughly equivalent to + # np.maximum(np.minimum(np.asarray(la), high), low) + # the np.asarray(la) is problematic because it lose original labels + # and then tries to get them back from high, where they are possibly + # incomplete if broadcasting happened + + # It fails on "np.minimum(ndarray, LArray)" because it calls __array_wrap__(high, result) which cannot work if + # there was broadcasting involved (high has potentially less labels than result). + # it does this because numpy calls __array_wrap__ on the argument with the highest __array_priority__ + raw_args = [np.asarray(a) if isinstance(a, LArray) else a + for a in args] + res_data = func(*raw_args, **kwargs) + if combined_axes: + return LArray(res_data, combined_axes) + else: + return res_data + # copy meaningful attributes (numpy ufuncs do not have __annotations__ nor __qualname__) + wrapper.__name__ = func.__name__ + wrapper.__doc__ = func.__doc__ + # set __qualname__ explicitly (all these functions are supposed to be top-level function in the ufuncs module) + wrapper.__qualname__ = func.__name__ + # we should not copy __module__ + return wrapper + + +# Trigonometric functions + +sin = broadcastify(np.sin) +cos = broadcastify(np.cos) +tan = broadcastify(np.tan) +arcsin = broadcastify(np.arcsin) +arccos = broadcastify(np.arccos) +arctan = broadcastify(np.arctan) +hypot = broadcastify(np.hypot) +arctan2 = broadcastify(np.arctan2) +degrees = broadcastify(np.degrees) +radians = broadcastify(np.radians) +unwrap = broadcastify(np.unwrap) +# deg2rad = broadcastify(np.deg2rad) +# rad2deg = broadcastify(np.rad2deg) + +# Hyperbolic functions + +sinh = broadcastify(np.sinh) +cosh = broadcastify(np.cosh) +tanh = broadcastify(np.tanh) +arcsinh = broadcastify(np.arcsinh) +arccosh = broadcastify(np.arccosh) +arctanh = broadcastify(np.arctanh) + +# Rounding + +# all 3 are equivalent, I am unsure I should support around and round_ +round = broadcastify(np.round) +around = broadcastify(np.around) +round_ = broadcastify(np.round_) +rint = broadcastify(np.rint) +fix = broadcastify(np.fix) +floor = broadcastify(np.floor) +ceil = broadcastify(np.ceil) +trunc = broadcastify(np.trunc) + +# Sums, products, differences + +# prod = broadcastify(np.prod) +# sum = broadcastify(np.sum) +# nansum = broadcastify(np.nansum) +# cumprod = broadcastify(np.cumprod) +# cumsum = broadcastify(np.cumsum) + +# cannot use a simple wrapped ufunc because those ufuncs do not preserve +# shape or dimensions so labels are wrong +# diff = broadcastify(np.diff) +# ediff1d = broadcastify(np.ediff1d) +# gradient = broadcastify(np.gradient) +# cross = broadcastify(np.cross) +# trapz = broadcastify(np.trapz) + +# Exponents and logarithms + +exp = broadcastify(np.exp) +expm1 = broadcastify(np.expm1) +exp2 = broadcastify(np.exp2) +log = broadcastify(np.log) +log10 = broadcastify(np.log10) +log2 = broadcastify(np.log2) +log1p = broadcastify(np.log1p) +logaddexp = broadcastify(np.logaddexp) +logaddexp2 = broadcastify(np.logaddexp2) + +# Other special functions + +i0 = broadcastify(np.i0) +sinc = broadcastify(np.sinc) + +# Floating point routines + +signbit = broadcastify(np.signbit) +copysign = broadcastify(np.copysign) +frexp = broadcastify(np.frexp) +ldexp = broadcastify(np.ldexp) + +# Arithmetic operations + +# add = broadcastify(np.add) +# reciprocal = broadcastify(np.reciprocal) +# negative = broadcastify(np.negative) +# multiply = broadcastify(np.multiply) +# divide = broadcastify(np.divide) +# power = broadcastify(np.power) +# subtract = broadcastify(np.subtract) +# true_divide = broadcastify(np.true_divide) +# floor_divide = broadcastify(np.floor_divide) +# fmod = broadcastify(np.fmod) +# mod = broadcastify(np.mod) +# modf = broadcastify(np.modf) +# remainder = broadcastify(np.remainder) + +# Handling complex numbers + +angle = broadcastify(np.angle) +real = broadcastify(np.real) +imag = broadcastify(np.imag) +conj = broadcastify(np.conj) + +# Miscellaneous + +convolve = broadcastify(np.convolve) +clip = broadcastify(np.clip) +sqrt = broadcastify(np.sqrt) +# square = broadcastify(np.square) +absolute = broadcastify(np.absolute) +fabs = broadcastify(np.fabs) +sign = broadcastify(np.sign) +maximum = broadcastify(np.maximum) +minimum = broadcastify(np.minimum) +fmax = broadcastify(np.fmax) +fmin = broadcastify(np.fmin) +nan_to_num = broadcastify(np.nan_to_num) +real_if_close = broadcastify(np.real_if_close) +interp = broadcastify(np.interp) +where = broadcastify(np.where) +isnan = broadcastify(np.isnan) +isinf = broadcastify(np.isinf) + +inverse = broadcastify(np.linalg.inv) diff --git a/larray/example.py b/larray/example.py new file mode 100644 index 000000000..cf533f4df --- /dev/null +++ b/larray/example.py @@ -0,0 +1,51 @@ +import os +import larray as la + +__all__ = ['EXAMPLE_FILES_DIR', 'load_example_data'] + +EXAMPLE_FILES_DIR = os.path.dirname(__file__) + '/tests/data/' +AVAILABLE_EXAMPLE_DATA = { + 'demography' : os.path.join(EXAMPLE_FILES_DIR, 'demography.h5') +} + + +def load_example_data(name): + """Load arrays used in the tutorial so that all examples in it can be reproduced. + + Parameters + ---------- + name : str + Example data to load. Available example datasets are: + + - demography + + Returns + ------- + Session + Session containing one or several arrays + + Examples + -------- + >>> demo = load_example_data('demography') + >>> demo.pop.info # doctest: +SKIP + 26 x 3 x 121 x 2 x 2 + time [26]: 1991 1992 1993 ... 2014 2015 2016 + geo [3]: 'BruCap' 'Fla' 'Wal' + age [121]: 0 1 2 ... 118 119 120 + sex [2]: 'M' 'F' + nat [2]: 'BE' 'FO' + >>> demo.qx.info # doctest: +SKIP + 26 x 3 x 121 x 2 x 2 + time [26]: 1991 1992 1993 ... 2014 2015 2016 + geo [3]: 'BruCap' 'Fla' 'Wal' + age [121]: 0 1 2 ... 118 119 120 + sex [2]: 'M' 'F' + nat [2]: 'BE' 'FO' + """ + if name is None: + name = 'demography' + if not isinstance(name, str): + raise TypeError("Expected string for argument example_data") + if name not in AVAILABLE_EXAMPLE_DATA.keys(): + raise ValueError("example_data must be chosen from list {}".format(list(AVAILABLE_EXAMPLE_DATA.keys()))) + return la.Session(AVAILABLE_EXAMPLE_DATA[name]) diff --git a/larray/extra/__init__.py b/larray/extra/__init__.py new file mode 100644 index 000000000..19c879ffd --- /dev/null +++ b/larray/extra/__init__.py @@ -0,0 +1,3 @@ +from __future__ import absolute_import + +from larray.extra.ipfp import * diff --git a/larray/extra/ipfp.py b/larray/extra/ipfp.py new file mode 100644 index 000000000..446f1abfd --- /dev/null +++ b/larray/extra/ipfp.py @@ -0,0 +1,299 @@ +import math +from collections import deque + +from larray.core.array import LArray, aslarray, ones, any +import numpy as np + +__all__ = ['ipfp'] + + +def badvalues(a, bad_filter): + bad_values = a[bad_filter] + assert bad_values.ndim == 1 + return '\n'.join('{}: {}'.format(k, v) for k, v in zip(bad_values.axes[0], bad_values)) + + +def f2str(f, threshold=2): + """Return string representation of floating point number f. + Use scientific notation if f would have more than threshold decimal digits, otherwise use threshold as precision. + + Parameters + ---------- + f : float + Number to represent. + threshold : int, optional + Precision (number of decimal digits displayed). If the number needs more digits, scientific notation will be + used. + + Examples + -------- + >>> f2str(55.1) + '55.10' + >>> f2str(1.234) + '1.23' + >>> f2str(0.002) + '2.00e-03' + """ + kind = "e" if f and math.log10(1 / abs(f)) > threshold else "f" + return "{:.{}{}}".format(f, threshold, kind) + + +def warn_or_raise(what, msg): + if what == 'raise': + raise ValueError(msg) + else: + print("WARNING: {}".format(msg)) + + +def ipfp(target_sums, a=None, axes=None, maxiter=1000, threshold=0.5, stepstoabort=10, nzvzs='raise', + no_convergence='raise', display_progress=False): + """Apply Iterative Proportional Fitting Procedure (also known as bi-proportional fitting in statistics, + RAS algorithm in economics) to array a, with target_sums as targets. + + Parameters + ---------- + target_sums : tuple/list of array-like + Target sums to achieve. + First element must be the sum to achieve along axis 0, the second the sum along axis 1, ... + a : array-like, optional + Starting values to fit, if not given starts with an array filled with 1. + axes : list/tuple of axes, optional + Axes on which the fitting procedure should be applied. Defaults to all axes. + maxiter : int, optional + Maximum number of iteration, defaults to 1000. + threshold : float, optional + Threshold below which the result is deemed acceptable, defaults to 0.5. + stepstoabort : int, optional + Number of consecutive steps with no improvement after which to abort. Defaults to 10. + nzvzs : 'fix', 'warn' or 'raise', optional + Behavior when detecting non zero values where the sum is zero + 'fix': set to zero (silently) + 'warn': set to zero and print a warning + 'raise': raise an exception (default) + no_convergence : 'ignore', 'warn' or 'raise, optional + Behavior when the algorithm does not seem to converge. This condition is triggered both when the maximum number + of iteration is reached or when the maximum absolute difference between the target and the current sums does + not improve for `stepstoabort` iterations. + 'ignore': return values computed up to that point (silently) + 'warn': return values computed up to that point and print a warning + 'raise': raise an exception (default) + display_progress : False, True or 'condensed', optional + Whether or not to display progress. Defaults to False. + If 'condensed' will display progress using a denser template (using one line per iteration). + + Returns + ------- + LArray + + Examples + -------- + >>> from larray import * + >>> a = Axis('a=a0,a1') + >>> b = Axis('b=b0,b1') + >>> initial = LArray([[2, 1], [1, 2]], [a, b]) + >>> initial + a\\b b0 b1 + a0 2 1 + a1 1 2 + >>> target_sum_along_a = LArray([2, 1], b) + >>> target_sum_along_a + b b0 b1 + 2 1 + >>> target_sum_along_b = LArray([1, 2], a) + >>> target_sum_along_b + a a0 a1 + 1 2 + >>> result = ipfp([target_sum_along_a, target_sum_along_b], initial, threshold=0.01) + >>> # round result so that its display is nicer + ... round(result, 2) + a\\b b0 b1 + a0 0.85 0.15 + a1 1.15 0.85 + + Now let us assume you have a 3D array like this: + + >>> year = Axis('year=2014..2016') + >>> initial = ndtest([a, b, year]) + >>> initial + a b\year 2014 2015 2016 + a0 b0 0 1 2 + a0 b1 3 4 5 + a1 b0 6 7 8 + a1 b1 9 10 11 + + and some targets for each year: + + >>> btargets = initial.sum(X.a) + 1 + >>> btargets + b\year 2014 2015 2016 + b0 7 9 11 + b1 13 15 17 + >>> atargets = initial.sum(X.b) + 1 + >>> atargets + a\year 2014 2015 2016 + a0 4 6 8 + a1 16 18 20 + + You want to apply a 2D fitting procedure for each value of that year axis. You could call ipfp within a loop on + the year axis, but you can also apply the procedure for all years at once by using the axes argument. This is + *much* faster than an explicit loop. + + >>> result = ipfp([btargets, atargets], initial, axes=(X.a, X.b)) + """ + assert nzvzs in {'fix', 'warn', 'raise'} + assert no_convergence in {'ignore', 'warn', 'raise'} + assert isinstance(display_progress, bool) or display_progress == 'condensed' + + target_sums = [aslarray(ts) for ts in target_sums] + + n = len(target_sums) + + if axes is None: + axes = list(range(n)) + + def has_anonymous_axes(a): + return any(axis.name is None for axis in a.axes) + + if any(has_anonymous_axes(ts) for ts in target_sums): + if any(not isinstance(axis, int) for axis in axes): + raise ValueError("ipfp does not support target sums with anonymous axes when using the axes argument with" + "non-integer (positional) axis references") + + names_for_missing_axes = ['axis{}'.format(i) for i in axes] + new_target_sums = [] + for i, target_sum in zip(axes, target_sums): + ts_axes_names = names_for_missing_axes[:i] + names_for_missing_axes[i + 1:] + new_ts = target_sum.rename({axis: name + for axis, name in zip(target_sum.axes, ts_axes_names) + if axis.name is None}) + new_target_sums.append(new_ts) + target_sums = new_target_sums + + if a is None: + # reconstruct all axes from target_sums axes + # assuming shape is the total shape of a + # >>> shape = (3, 4, 5) + # target_sums axes would be: + # >>> shapes = [shape[:i] + shape[i+1:] for i in range(len(shape))] + # >>> shapes + # [(4, 5), (3, 5), (3, 4)] + # >>> (shapes[1][0],) + shapes[0] + # (3, 4, 5) + # so, to reconstruct a.axes from target_sum axes, we need to take the first axis of the second target_sum and + # all axes from the first target_sum: + first_axis = target_sums[1].axes[0] + other_axes = target_sums[0].axes + all_axes = first_axis + other_axes + a = ones(all_axes, dtype=np.float64) + else: + # TODO: only make a copy if there are actually any bad values, but I am unsure we should make a copy at all. + # Either way, this should be documented. + if nzvzs in {'warn', 'fix'} and isinstance(a, LArray): + a = a.copy() + else: + a = aslarray(a) + # TODO: this should be a builtin op + a = a.rename({i: name if name is not None else 'axis{}'.format(i) + for i, name in enumerate(a.axes.names)}) + + axes = a.axes[axes] + + # this test should only ever fail if the user passed larray for a and target sums + for axis, axis_target_sum in zip(axes, target_sums): + expected_axes = a.axes - axis + if axis_target_sum.axes != expected_axes: + raise ValueError("axes of target sum along {} (axis {}) do not match corresponding array axes: " + "got {} but expected {}. Are the target sums in the correct order?" + .format(axis.name, a.axes.index(axis), axis_target_sum.axes, expected_axes)) + + axis0_total = target_sums[0].sum() + for axis, axis_target_sum in zip(axes[1:], target_sums[1:]): + axis_total = axis_target_sum.sum() + if str(axis_total) != str(axis0_total): + raise ValueError("target sum along {} (axis {}) is different than target sum along {} (axis {}): {} vs {}" + .format(axis, a.axes.index(axis), axes[0], a.axes.index(axes[0]), axis_total, axis0_total)) + + negative = a < 0 + if any(negative): + raise ValueError("negative value(s) found:\n{}".format(badvalues(a, negative))) + + for axis, axis_target_sum in zip(axes, target_sums): + axis_idx = a.axes.index(axis) + axis_sum = a.sum(axis) + bad = (axis_sum == 0) & (axis_target_sum != 0) + if any(bad): + raise ValueError("found all zero values sum along {} (axis {}) but non zero target sum:\n{}" + .format(axis.name, axis_idx, badvalues(axis_target_sum, bad))) + + bad = (axis_sum != 0) & (axis_target_sum == 0) + if any(bad): + if nzvzs in {'warn', 'raise'}: + msg = "found Non Zero Values but Zero target Sum (nzvzs) along {} (axis {})".format(axis.name, axis_idx) + if nzvzs == 'raise': + raise ValueError("{}, use nzvzs='warn' or 'fix' to set them to zero automatically:\n{}" + .format(msg, badvalues(axis_sum, bad))) + else: + print("WARNING: {}, setting them to zero:\n{}".format(msg, badvalues(axis_sum, bad))) + + a[bad] = 0 + # verify we did fix the problem + assert not any((a.sum(axis) != 0) & (axis_target_sum == 0)) + + r = a + lastdiffs = deque([float('nan')], maxlen=stepstoabort) + + # Here is the nice version of the algorithm + + # for i in range(maxiter): + # startr = r + # for axis, axis_target in zip(axes, target_sums): + # r = r * axis_target.divnot0(r.sum(axis)) + # max_sum_diff = max(abs(r.sum(axis) - axis_target).max() + # for axis, axis_target in zip(axes, target_sums)) + # step_sum_improvement = ... + + # Here is the ugly optimized version which avoids computing the sum for the first axis twice per iteration + # (saves ~10-15% running time). + axis0_sum = r.sum(axes[0]) + for i in range(maxiter): + startr = r + r = r * target_sums[0].divnot0(axis0_sum) + for axis, axis_target in zip(axes[1:], target_sums[1:]): + r = r * axis_target.divnot0(r.sum(axis)) + + axes_sum = [r.sum(axis) for axis in axes] + max_sum_diff = max(abs(axis_sum - axis_target).max() + for axis_sum, axis_target in zip(axes_sum, target_sums)) + axis0_sum = axes_sum[0] + + step_sum_improvement = lastdiffs[-1] - max_sum_diff + stepcelldiff = abs(r - startr).max() + + if display_progress: + if display_progress == "condensed": + template = "it {} max cell diff {} max diff to target {} ({})" + else: + template = """iteration {} + * max(abs(prev_cell - cell)): {} + * max(abs(sum - target_sum)): {} + \- change since last iteration: {} +""" + print(template.format(i, f2str(stepcelldiff), f2str(max_sum_diff), f2str(step_sum_improvement))) + + if np.all(np.array(lastdiffs) == max_sum_diff): + if no_convergence in {'warn', 'raise'}: + warn_or_raise(no_convergence, "does not seem to converge (no improvement for {} consecutive steps), " + "stopping here.".format(stepstoabort)) + return r + + if max_sum_diff < threshold: + if display_progress: + print("acceptable max(abs(sum - target_sum)) found at iteration {}: {} < threshold ({})" + .format(i, f2str(max_sum_diff), threshold)) + return r + + lastdiffs.append(max_sum_diff) + + if no_convergence in {'warn', 'raise'}: + warn_or_raise(no_convergence, "maximum iteration reached ({})".format(maxiter)) + return r diff --git a/larray/inout/__init__.py b/larray/inout/__init__.py new file mode 100644 index 000000000..ad1239606 --- /dev/null +++ b/larray/inout/__init__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import, division, print_function + +from larray.inout.excel import * +from larray.inout.array import * +from larray.inout.session import * diff --git a/larray/inout/array.py b/larray/inout/array.py new file mode 100644 index 000000000..a609fecdb --- /dev/null +++ b/larray/inout/array.py @@ -0,0 +1,770 @@ +from __future__ import absolute_import, print_function + +import os +import csv +import numpy as np +import pandas as pd +import warnings +from itertools import product + +from larray.core.axis import Axis +from larray.core.array import LArray, ndtest +from larray.core.group import _translate_sheet_name, _translate_key_hdf +from larray.util.misc import (basestring, skip_comment_cells, strip_rows, csv_open, StringIO, decode, unique, + deprecate_kwarg) + +try: + import xlwings as xw +except ImportError: + xw = None + +__all__ = ['from_frame', 'read_csv', 'read_tsv', 'read_eurostat', 'read_hdf', 'read_excel', 'read_sas', + 'from_lists', 'from_string'] + + +def parse(s): + """ + Used to parse the "folded" axis ticks (usually periods). + """ + # parameters can be strings or numbers + if isinstance(s, basestring): + s = s.strip() + low = s.lower() + if low == 'true': + return True + elif low == 'false': + return False + elif s.isdigit(): + return int(s) + else: + try: + return float(s) + except ValueError: + return s + else: + return s + + +def df_labels(df, sort=True): + """ + Returns unique labels for each dimension. + """ + idx = df.index + if isinstance(idx, pd.core.index.MultiIndex): + if sort: + return list(idx.levels) + else: + return [list(unique(idx.get_level_values(l))) for l in idx.names] + else: + assert isinstance(idx, pd.core.index.Index) + # use .values if needed + return [idx] + + +def cartesian_product_df(df, sort_rows=False, sort_columns=False, **kwargs): + labels = df_labels(df, sort=sort_rows) + if sort_rows: + new_index = pd.MultiIndex.from_product(labels) + else: + new_index = pd.MultiIndex.from_tuples(list(product(*labels))) + columns = sorted(df.columns) if sort_columns else list(df.columns) + # the prodlen test is meant to avoid the more expensive array_equal test + prodlen = np.prod([len(axis_labels) for axis_labels in labels]) + if prodlen == len(df) and columns == list(df.columns) and np.array_equal(df.index.values, new_index.values): + return df, labels + return df.reindex(new_index, columns, **kwargs), labels + + +def from_series(s, sort_rows=False): + """ + Converts Pandas Series into 1D LArray. + + Parameters + ---------- + s : Pandas Series + Input Pandas Series. + sort_rows : bool, optional + Whether or not to sort the rows alphabetically. Defaults to False. + + Returns + ------- + LArray + """ + name = s.name if s.name is not None else s.index.name + if name is not None: + name = str(name) + if sort_rows: + s = s.sort_index() + return LArray(s.values, Axis(s.index.values, name)) + + +def from_frame(df, sort_rows=False, sort_columns=False, parse_header=False, unfold_last_axis_name=False, **kwargs): + """ + Converts Pandas DataFrame into LArray. + + Parameters + ---------- + df : pandas.DataFrame + Input dataframe. By default, name and labels of the last axis are defined by the name and labels of the + columns Index of the dataframe unless argument unfold_last_axis_name is set to True. + sort_rows : bool, optional + Whether or not to sort the rows alphabetically (sorting is more efficient than not sorting). Defaults to False. + sort_columns : bool, optional + Whether or not to sort the columns alphabetically (sorting is more efficient than not sorting). + Defaults to False. + parse_header : bool, optional + Whether or not to parse columns labels. Pandas treats column labels as strings. + If True, column labels are converted into int, float or boolean when possible. Defaults to False. + unfold_last_axis_name : bool, optional + Whether or not to extract the names of the last two axes by splitting the name of the last index column of the + dataframe using ``\\``. Defaults to False. + + Returns + ------- + LArray + + See Also + -------- + LArray.to_frame + + Examples + -------- + >>> df = ndtest((2, 2, 2)).to_frame() + >>> df # doctest: +NORMALIZE_WHITESPACE + c c0 c1 + a b + a0 b0 0 1 + b1 2 3 + a1 b0 4 5 + b1 6 7 + >>> from_frame(df) + a b\\c c0 c1 + a0 b0 0 1 + a0 b1 2 3 + a1 b0 4 5 + a1 b1 6 7 + + Names of the last two axes written as ``before_last_axis_name\\last_axis_name`` + + >>> df = ndtest((2, 2, 2)).to_frame(fold_last_axis_name=True) + >>> df # doctest: +NORMALIZE_WHITESPACE + c0 c1 + a b\\c + a0 b0 0 1 + b1 2 3 + a1 b0 4 5 + b1 6 7 + >>> from_frame(df, unfold_last_axis_name=True) + a b\\c c0 c1 + a0 b0 0 1 + a0 b1 2 3 + a1 b0 4 5 + a1 b1 6 7 + """ + axes_names = [decode(name, 'utf8') for name in df.index.names] + + # handle 2 or more dimensions with the last axis name given using \ + if unfold_last_axis_name: + if isinstance(axes_names[-1], basestring) and '\\' in axes_names[-1]: + last_axes = [name.strip() for name in axes_names[-1].split('\\')] + axes_names = axes_names[:-1] + last_axes + else: + axes_names += [None] + else: + axes_names += [df.columns.name] + + df, axes_labels = cartesian_product_df(df, sort_rows=sort_rows, sort_columns=sort_columns, **kwargs) + + # Pandas treats column labels as column names (strings) so we need to convert them to values + last_axis_labels = [parse(cell) for cell in df.columns.values] if parse_header else list(df.columns.values) + axes_labels.append(last_axis_labels) + axes_names = [str(name) if name is not None else name + for name in axes_names] + + axes = [Axis(labels, name) for labels, name in zip(axes_labels, axes_names)] + data = df.values.reshape([len(axis) for axis in axes]) + return LArray(data, axes) + + +def df_aslarray(df, sort_rows=False, sort_columns=False, raw=False, parse_header=True, wide=True, **kwargs): + """ + Prepare Pandas DataFrame and then convert it into LArray. + + Parameters + ---------- + df : Pandas DataFrame + Input dataframe. + sort_rows : bool, optional + Whether or not to sort the rows alphabetically (sorting is more efficient than not sorting). Defaults to False. + sort_columns : bool, optional + Whether or not to sort the columns alphabetically (sorting is more efficient than not sorting). + Defaults to False. + raw : bool, optional + Whether or not to consider the input dataframe as a raw dataframe, i.e. read without index at all. + If True, build the first N-1 axes of the output array from the first N-1 dataframe columns. Defaults to False. + parse_header : bool, optional + Whether or not to parse columns labels. Pandas treats column labels as strings. + If True, column labels are converted into int, float or boolean when possible. Defaults to True. + wide : bool, optional + Whether or not to assume the array is stored in "wide" format. + If False, the array is assumed to be stored in "narrow" format: one column per axis plus one value column. + Defaults to True. + + Returns + ------- + LArray + """ + # we could inline df_aslarray into the functions that use it, so that the original (non-cartesian) df is freed from + # memory at this point, but it would be much uglier and would not lower the peak memory usage which happens during + # cartesian_product_df.reindex + + # raw = True: the dataframe was read without index at all (ie 2D dataframe), + # irrespective of the actual data dimensionality + if raw: + columns = df.columns.values.tolist() + if wide: + try: + # take the first column which contains '\' + pos_last = next(i for i, v in enumerate(columns) if isinstance(v, basestring) and '\\' in v) + except StopIteration: + # we assume first column will not contain data + pos_last = 0 + + # This is required to handle int column names (otherwise we can simply use column positions in set_index). + # This is NOT the same as df.columns[list(range(...))] ! + index_columns = [df.columns[i] for i in range(pos_last + 1)] + df.set_index(index_columns, inplace=True) + else: + index_columns = [df.columns[i] for i in range(len(df.columns) - 1)] + df.set_index(index_columns, inplace=True) + series = df[df.columns[-1]] + if isinstance(series.index, pd.core.index.MultiIndex): + fill_value = kwargs.get('fill_value', np.nan) + # TODO: use argument sort=False when it will be available + # (see https://github.com/pandas-dev/pandas/issues/15105) + df = series.unstack(level=-1, fill_value=fill_value) + # pandas (un)stack and pivot(_table) methods return a Dataframe/Series with sorted index and columns + labels = df_labels(series, sort=False) + index = pd.MultiIndex.from_tuples(list(product(*labels[:-1])), names=series.index.names[:-1]) + columns = labels[-1] + df = df.reindex(index=index, columns=columns, fill_value=fill_value) + else: + series.name = series.index.name + if sort_rows: + raise ValueError('sort_rows=True is not valid for 1D arrays. Please use sort_columns instead.') + return from_series(series, sort_rows=sort_columns) + + # handle 1D + if len(df) == 1 and (pd.isnull(df.index.values[0]) or + (isinstance(df.index.values[0], basestring) and df.index.values[0].strip() == '')): + if parse_header: + df.columns = pd.Index([parse(cell) for cell in df.columns.values], name=df.columns.name) + series = df.iloc[0] + series.name = df.index.name + if sort_rows: + raise ValueError('sort_rows=True is not valid for 1D arrays. Please use sort_columns instead.') + return from_series(series, sort_rows=sort_columns) + else: + axes_names = [decode(name, 'utf8') for name in df.index.names] + unfold_last_axis_name = isinstance(axes_names[-1], basestring) and '\\' in axes_names[-1] + return from_frame(df, sort_rows=sort_rows, sort_columns=sort_columns, parse_header=parse_header, + unfold_last_axis_name=unfold_last_axis_name, **kwargs) + + +def _get_index_col(nb_axes=None, index_col=None, wide=True): + if not wide: + if nb_axes is not None or index_col is not None: + raise ValueError("`nb_axes` or `index_col` argument cannot be used when `wide` argument is False") + + if nb_axes is not None and index_col is not None: + raise ValueError("cannot specify both `nb_axes` and `index_col`") + elif nb_axes is not None: + index_col = list(range(nb_axes - 1)) + elif isinstance(index_col, int): + index_col = [index_col] + + return index_col + + +@deprecate_kwarg('nb_index', 'nb_axes', arg_converter=lambda x: x + 1) +def read_csv(filepath_or_buffer, nb_axes=None, index_col=None, sep=',', headersep=None, fill_value=np.nan, + na=np.nan, sort_rows=False, sort_columns=False, wide=True, dialect='larray', **kwargs): + """ + Reads csv file and returns an array with the contents. + + Notes + ----- + csv file format: + arr,ages,sex,nat\time,1991,1992,1993 + A1,BI,H,BE,1,0,0 + A1,BI,H,FO,2,0,0 + A1,BI,F,BE,0,0,1 + A1,BI,F,FO,0,0,0 + A1,A0,H,BE,0,0,0 + + Parameters + ---------- + filepath_or_buffer : str or any file-like object + Path where the csv file has to be read or a file handle. + nb_axes : int, optional + Number of axes of output array. The first `nb_axes` - 1 columns and the header of the CSV file will be used + to set the axes of the output array. If not specified, the number of axes is given by the position of the + column header including the character `\` plus one. If no column header includes the character `\`, the array + is assumed to have one axis. Defaults to None. + index_col : list, optional + Positions of columns for the n-1 first axes (ex. [0, 1, 2, 3]). Defaults to None (see nb_axes above). + sep : str, optional + Separator. + headersep : str or None, optional + Separator for headers. + fill_value : scalar or LArray, optional + Value used to fill cells corresponding to label combinations which are not present in the input. + Defaults to NaN. + sort_rows : bool, optional + Whether or not to sort the rows alphabetically (sorting is more efficient than not sorting). Defaults to False. + sort_columns : bool, optional + Whether or not to sort the columns alphabetically (sorting is more efficient than not sorting). + Defaults to False. + wide : bool, optional + Whether or not to assume the array is stored in "wide" format. + If False, the array is assumed to be stored in "narrow" format: one column per axis plus one value column. + Defaults to True. + dialect : 'classic' | 'larray' | 'liam2', optional + Name of dialect. Defaults to 'larray'. + **kwargs + + Returns + ------- + LArray + + Examples + -------- + >>> tmpdir = getfixture('tmpdir') + >>> fname = os.path.join(tmpdir.strpath, 'test.csv') + >>> a = ndtest('nat=BE,FO;sex=M,F') + >>> a + nat\\sex M F + BE 0 1 + FO 2 3 + >>> a.to_csv(fname) + >>> with open(fname) as f: + ... print(f.read().strip()) + nat\\sex,M,F + BE,0,1 + FO,2,3 + >>> read_csv(fname) + nat\\sex M F + BE 0 1 + FO 2 3 + + Sort columns + + >>> read_csv(fname, sort_columns=True) + nat\\sex F M + BE 1 0 + FO 3 2 + + Read array saved in "narrow" format (wide=False) + + >>> a.to_csv(fname, wide=False) + >>> with open(fname) as f: + ... print(f.read().strip()) + nat,sex,value + BE,M,0 + BE,F,1 + FO,M,2 + FO,F,3 + >>> read_csv(fname, wide=False) + nat\\sex M F + BE 0 1 + FO 2 3 + + Specify the number of axes of the output array (useful when the name of the last axis is implicit) + + >>> a.to_csv(fname, dialect='classic') + >>> with open(fname) as f: + ... print(f.read().strip()) + nat,M,F + BE,0,1 + FO,2,3 + >>> read_csv(fname, nb_axes=2) + nat\\{1} M F + BE 0 1 + FO 2 3 + """ + if not np.isnan(na): + fill_value = na + warnings.warn("read_csv `na` argument has been renamed to `fill_value`. Please use that instead.", + FutureWarning, stacklevel=2) + + if dialect == 'liam2': + # read axes names. This needs to be done separately instead of reading the whole file with Pandas then + # manipulating the dataframe because the header line must be ignored for the column types to be inferred + # correctly. Note that to read one line, this is faster than using Pandas reader. + with csv_open(filepath_or_buffer) as f: + reader = csv.reader(f, delimiter=sep) + line_stream = skip_comment_cells(strip_rows(reader)) + axes_names = next(line_stream) + + if nb_axes is not None or index_col is not None: + raise ValueError("nb_axes and index_col are not compatible with dialect='liam2'") + if len(axes_names) > 1: + nb_axes = len(axes_names) + # use the second data line for column headers (excludes comments and blank lines before counting) + kwargs['header'] = 1 + kwargs['comment'] = '#' + + index_col = _get_index_col(nb_axes, index_col, wide) + + if headersep is not None: + if index_col is None: + index_col = [0] + + df = pd.read_csv(filepath_or_buffer, index_col=index_col, sep=sep, **kwargs) + if dialect == 'liam2': + if len(df) == 1: + df.set_index([[np.nan]], inplace=True) + if len(axes_names) > 1: + df.index.names = axes_names[:-1] + df.columns.name = axes_names[-1] + raw = False + else: + raw = index_col is None + + if headersep is not None: + combined_axes_names = df.index.name + df.index = df.index.str.split(headersep, expand=True) + df.index.names = combined_axes_names.split(headersep) + raw = False + + return df_aslarray(df, sort_rows=sort_rows, sort_columns=sort_columns, fill_value=fill_value, raw=raw, wide=wide) + + +def read_tsv(filepath_or_buffer, **kwargs): + return read_csv(filepath_or_buffer, sep='\t', **kwargs) + + +def read_eurostat(filepath_or_buffer, **kwargs): + """Reads EUROSTAT TSV (tab-separated) file into an array. + + EUROSTAT TSV files are special because they use tabs as data separators but comas to separate headers. + + Parameters + ---------- + filepath_or_buffer : str or any file-like object + Path where the tsv file has to be read or a file handle. + kwargs + Arbitrary keyword arguments are passed through to read_csv. + + Returns + ------- + LArray + """ + return read_csv(filepath_or_buffer, sep='\t', headersep=',', **kwargs) + + +def read_hdf(filepath_or_buffer, key, fill_value=np.nan, na=np.nan, sort_rows=False, sort_columns=False, **kwargs): + """Reads an array named key from a HDF5 file in filepath (path+name) + + Parameters + ---------- + filepath_or_buffer : str or pandas.HDFStore + Path and name where the HDF5 file is stored or a HDFStore object. + key : str or Group + Name of the array. + fill_value : scalar or LArray, optional + Value used to fill cells corresponding to label combinations which are not present in the input. + Defaults to NaN. + sort_rows : bool, optional + Whether or not to sort the rows alphabetically (sorting is more efficient than not sorting). Defaults to False. + sort_columns : bool, optional + Whether or not to sort the columns alphabetically (sorting is more efficient than not sorting). + Defaults to False. + + Returns + ------- + LArray + """ + if not np.isnan(na): + fill_value = na + warnings.warn("read_hdf `na` argument has been renamed to `fill_value`. Please use that instead.", + FutureWarning, stacklevel=2) + + key = _translate_key_hdf(key) + df = pd.read_hdf(filepath_or_buffer, key, **kwargs) + return df_aslarray(df, sort_rows=sort_rows, sort_columns=sort_columns, fill_value=fill_value, parse_header=False) + + +@deprecate_kwarg('nb_index', 'nb_axes', arg_converter=lambda x: x + 1) +@deprecate_kwarg('sheetname', 'sheet') +def read_excel(filepath, sheet=0, nb_axes=None, index_col=None, fill_value=np.nan, na=np.nan, + sort_rows=False, sort_columns=False, wide=True, engine=None, **kwargs): + """ + Reads excel file from sheet name and returns an LArray with the contents + + Parameters + ---------- + filepath : str + Path where the Excel file has to be read. + sheet : str, Group or int, optional + Name or index of the Excel sheet containing the array to be read. + By default the array is read from the first sheet. + nb_axes : int, optional + Number of axes of output array. The first `nb_axes` - 1 columns and the header of the Excel sheet will be used + to set the axes of the output array. If not specified, the number of axes is given by the position of the + column header including the character `\` plus one. If no column header includes the character `\`, the array + is assumed to have one axis. Defaults to None. + index_col : list, optional + Positions of columns for the n-1 first axes (ex. [0, 1, 2, 3]). Defaults to None (see nb_axes above). + fill_value : scalar or LArray, optional + Value used to fill cells corresponding to label combinations which are not present in the input. + Defaults to NaN. + sort_rows : bool, optional + Whether or not to sort the rows alphabetically (sorting is more efficient than not sorting). Defaults to False. + sort_columns : bool, optional + Whether or not to sort the columns alphabetically (sorting is more efficient than not sorting). + Defaults to False. + wide : bool, optional + Whether or not to assume the array is stored in "wide" format. + If False, the array is assumed to be stored in "narrow" format: one column per axis plus one value column. + Defaults to True. + engine : {'xlrd', 'xlwings'}, optional + Engine to use to read the Excel file. If None (default), it will use 'xlwings' by default if the module is + installed and relies on Pandas default reader otherwise. + **kwargs + """ + if not np.isnan(na): + fill_value = na + warnings.warn("read_excel `na` argument has been renamed to `fill_value`. Please use that instead.", + FutureWarning, stacklevel=2) + + sheet = _translate_sheet_name(sheet) + + if engine is None: + engine = 'xlwings' if xw is not None else None + + index_col = _get_index_col(nb_axes, index_col, wide) + + if engine == 'xlwings': + if kwargs: + raise TypeError("'{}' is an invalid keyword argument for this function when using the xlwings backend" + .format(list(kwargs.keys())[0])) + from larray.inout.excel import open_excel + with open_excel(filepath) as wb: + return wb[sheet].load(index_col=index_col, fill_value=fill_value, sort_rows=sort_rows, + sort_columns=sort_columns, wide=wide) + else: + df = pd.read_excel(filepath, sheet, index_col=index_col, engine=engine, **kwargs) + return df_aslarray(df, sort_rows=sort_rows, sort_columns=sort_columns, raw=index_col is None, + fill_value=fill_value, wide=wide) + + +@deprecate_kwarg('nb_index', 'nb_axes', arg_converter=lambda x: x + 1) +def read_sas(filepath, nb_axes=None, index_col=None, fill_value=np.nan, na=np.nan, sort_rows=False, sort_columns=False, + **kwargs): + """ + Reads sas file and returns an LArray with the contents + nb_axes: number of axes of the output array + or + index_col: Positions of columns for the n-1 first axes (ex. [0, 1, 2, 3]) + """ + if not np.isnan(na): + fill_value = na + warnings.warn("read_sas `na` argument has been renamed to `fill_value`. Please use that instead.", + FutureWarning, stacklevel=2) + + if nb_axes is not None and index_col is not None: + raise ValueError("cannot specify both nb_axes and index_col") + elif nb_axes is not None: + index_col = list(range(nb_axes - 1)) + elif isinstance(index_col, int): + index_col = [index_col] + + df = pd.read_sas(filepath, index=index_col, **kwargs) + return df_aslarray(df, sort_rows=sort_rows, sort_columns=sort_columns, fill_value=fill_value) + + +@deprecate_kwarg('nb_index', 'nb_axes', arg_converter=lambda x: x + 1) +def from_lists(data, nb_axes=None, index_col=None, fill_value=np.nan, sort_rows=False, sort_columns=False, wide=True): + """ + initialize array from a list of lists (lines) + + Parameters + ---------- + data : sequence (tuple, list, ...) + Input data. All data is supposed to already have the correct type (e.g. strings are not parsed). + nb_axes : int, optional + Number of axes of output array. The first `nb_axes` - 1 columns and the header will be used + to set the axes of the output array. If not specified, the number of axes is given by the position of the + column header including the character `\` plus one. If no column header includes the character `\`, the array + is assumed to have one axis. Defaults to None. + index_col : list, optional + Positions of columns for the n-1 first axes (ex. [0, 1, 2, 3]). Defaults to None (see nb_axes above). + fill_value : scalar or LArray, optional + Value used to fill cells corresponding to label combinations which are not present in the input. + Defaults to NaN. + sort_rows : bool, optional + Whether or not to sort the rows alphabetically (sorting is more efficient than not sorting). Defaults to False. + sort_columns : bool, optional + Whether or not to sort the columns alphabetically (sorting is more efficient than not sorting). + Defaults to False. + wide : bool, optional + Whether or not to assume the array is stored in "wide" format. + If False, the array is assumed to be stored in "narrow" format: one column per axis plus one value column. + Defaults to True. + + Returns + ------- + LArray + + Examples + -------- + >>> from_lists([['sex', 'M', 'F'], + ... ['', 0, 1]]) + sex M F + 0 1 + >>> from_lists([['sex\\\\year', 1991, 1992, 1993], + ... [ 'M', 0, 1, 2], + ... [ 'F', 3, 4, 5]]) + sex\\year 1991 1992 1993 + M 0 1 2 + F 3 4 5 + + Read array with missing values + `fill_value` argument + + >>> from_lists([['sex', 'nat\\\\year', 1991, 1992, 1993], + ... [ 'M', 'BE', 1, 0, 0], + ... [ 'M', 'FO', 2, 0, 0], + ... [ 'F', 'BE', 0, 0, 1]]) + sex nat\\year 1991 1992 1993 + M BE 1.0 0.0 0.0 + M FO 2.0 0.0 0.0 + F BE 0.0 0.0 1.0 + F FO nan nan nan + + >>> from_lists([['sex', 'nat\\\\year', 1991, 1992, 1993], + ... [ 'M', 'BE', 1, 0, 0], + ... [ 'M', 'FO', 2, 0, 0], + ... [ 'F', 'BE', 0, 0, 1]], fill_value=42) + sex nat\\year 1991 1992 1993 + M BE 1 0 0 + M FO 2 0 0 + F BE 0 0 1 + F FO 42 42 42 + + Specify the number of axes of the array to be read + + >>> from_lists([['sex', 'nat', 1991, 1992, 1993], + ... [ 'M', 'BE', 1, 0, 0], + ... [ 'M', 'FO', 2, 0, 0], + ... [ 'F', 'BE', 0, 0, 1]], nb_axes=3) + sex nat\\{2} 1991 1992 1993 + M BE 1.0 0.0 0.0 + M FO 2.0 0.0 0.0 + F BE 0.0 0.0 1.0 + F FO nan nan nan + + Read array saved in "narrow" format (wide=False) + + >>> from_lists([['sex', 'nat', 'year', 'value'], + ... [ 'M', 'BE', 1991, 1 ], + ... [ 'M', 'BE', 1992, 0 ], + ... [ 'M', 'BE', 1993, 0 ], + ... [ 'M', 'FO', 1991, 2 ], + ... [ 'M', 'FO', 1992, 0 ], + ... [ 'M', 'FO', 1993, 0 ], + ... [ 'F', 'BE', 1991, 0 ], + ... [ 'F', 'BE', 1992, 0 ], + ... [ 'F', 'BE', 1993, 1 ]], wide=False) + sex nat\\year 1991 1992 1993 + M BE 1.0 0.0 0.0 + M FO 2.0 0.0 0.0 + F BE 0.0 0.0 1.0 + F FO nan nan nan + """ + index_col = _get_index_col(nb_axes, index_col, wide) + + df = pd.DataFrame(data[1:], columns=data[0]) + if index_col is not None: + df.set_index([df.columns[c] for c in index_col], inplace=True) + + return df_aslarray(df, raw=index_col is None, parse_header=False, sort_rows=sort_rows, sort_columns=sort_columns, + fill_value=fill_value, wide=wide) + + +@deprecate_kwarg('nb_index', 'nb_axes', arg_converter=lambda x: x + 1) +def from_string(s, nb_axes=None, index_col=None, sep=' ', wide=True, **kwargs): + """Create an array from a multi-line string. + + Parameters + ---------- + s : str + input string. + nb_axes : int, optional + Number of axes of output array. The first `nb_axes` - 1 columns and the header will be used + to set the axes of the output array. If not specified, the number of axes is given by the position of the + column header including the character `\` plus one. If no column header includes the character `\`, the array + is assumed to have one axis. Defaults to None. + index_col : list, optional + Positions of columns for the n-1 first axes (ex. [0, 1, 2, 3]). Defaults to None (see nb_axes above). + sep : str + delimiter used to split each line into cells. + wide : bool, optional + Whether or not to assume the array is stored in "wide" format. + If False, the array is assumed to be stored in "narrow" format: one column per axis plus one value column. + Defaults to True. + \**kwargs + See arguments of Pandas read_csv function. + + Returns + ------- + LArray + + Examples + -------- + >>> # to create a 1D array using the default separator ' ', a tabulation character \t must be added in front + >>> # of the data line + >>> from_string("sex M F\\n\\t 0 1") + sex M F + 0 1 + >>> from_string("nat\\\\sex M F\\nBE 0 1\\nFO 2 3") + nat\sex M F + BE 0 1 + FO 2 3 + >>> from_string("period a b\\n2010 0 1\\n2011 2 3") + period\{1} a b + 2010 0 1 + 2011 2 3 + + Each label is stripped of leading and trailing whitespace, so this is valid too: + + >>> from_string('''nat\\\\sex M F + ... BE 0 1 + ... FO 2 3''') + nat\sex M F + BE 0 1 + FO 2 3 + >>> from_string('''age nat\\\\sex M F + ... 0 BE 0 1 + ... 0 FO 2 3 + ... 1 BE 4 5 + ... 1 FO 6 7''') + age nat\sex M F + 0 BE 0 1 + 0 FO 2 3 + 1 BE 4 5 + 1 FO 6 7 + + Empty lines at the beginning or end are ignored, so one can also format the string like this: + + >>> from_string(''' + ... nat\\\\sex M F + ... BE 0 1 + ... FO 2 3 + ... ''') + nat\sex M F + BE 0 1 + FO 2 3 + """ + return read_csv(StringIO(s), nb_axes=nb_axes, index_col=index_col, sep=sep, skipinitialspace=True, + wide=wide, **kwargs) diff --git a/larray/inout/excel.py b/larray/inout/excel.py new file mode 100644 index 000000000..7c69f4205 --- /dev/null +++ b/larray/inout/excel.py @@ -0,0 +1,701 @@ +# -*- coding: utf8 -*- +from __future__ import absolute_import, print_function + +__all__ = ['open_excel', 'Workbook'] + + +import os +import atexit + +import numpy as np +try: + import xlwings as xw +except ImportError: + xw = None + +from larray.core.group import _translate_sheet_name +from larray.core.axis import Axis +from larray.core.array import LArray, ndtest +from larray.inout.array import df_aslarray, from_lists +from larray.util.misc import PY2 + +string_types = (str,) + + +if xw is not None: + from xlwings.conversion.pandas_conv import PandasDataFrameConverter + + global_app = None + + def is_app_alive(app): + try: + app.books + return True + except Exception: + return False + + + def kill_global_app(): + global global_app + + if global_app is not None: + if is_app_alive(global_app): + try: + global_app.kill() + except Exception: + pass + del global_app + global_app = None + + + class LArrayConverter(PandasDataFrameConverter): + writes_types = LArray + + @classmethod + def read_value(cls, value, options): + df = PandasDataFrameConverter.read_value(value, options) + return df_aslarray(df) + + @classmethod + def write_value(cls, value, options): + df = value.to_frame(fold_last_axis_name=True) + return PandasDataFrameConverter.write_value(df, options) + + LArrayConverter.register(LArray) + + # TODO: replace overwrite_file by mode='r'|'w'|'a' the day xlwings will support a read-only mode + class Workbook(object): + def __init__(self, filepath=None, overwrite_file=False, visible=None, silent=None, app=None): + global global_app + + xw_wkb = None + self.delayed_filepath = None + self.filepath = None + self.new_workbook = False + + if filepath is None: + self.new_workbook = True + + if isinstance(filepath, str): + basename, ext = os.path.splitext(filepath) + if ext: + # XXX: we might want to be more precise than .xl* because I am unsure writing .xls + # (or anything other than .xlsx and .xlsm) would work + if not ext.startswith('.xl'): + raise ValueError("'%s' is not a supported file extension" % ext) + if not os.path.isfile(filepath) and not overwrite_file: + raise ValueError("File {} does not exist. Please give the path to an existing file or set " + "overwrite_file argument to True".format(filepath)) + if os.path.isfile(filepath) and overwrite_file: + self.filepath = filepath + # we create a temporary file to work on. In case of crash, the original is not destroyed. + # the temporary file is renamed as the original file at close. + filepath = basename + '~' + ext + if not os.path.isfile(filepath): + self.new_workbook = True + else: + # try to target an open but unsaved workbook. We cannot use the same code path as for other options + # because we do not know which Excel instance has that book + xw_wkb = xw.Book(filepath) + app = xw_wkb.app + + # active workbook use active app by default + if filepath == -1 and app not in {None, "active"}: + raise ValueError("to connect to the active workbook, one must use the 'active' Excel instance " + "(app='active' or app=None)") + + # unless explicitly set, app is set to visible for brand new or active book. + # For unsaved_book it is left intact. + if visible is None: + if filepath is None or filepath == -1: + visible = True + elif xw_wkb is None: + # filepath is not None but we don't target an unsaved book + visible = False + + if app is None: + if filepath == -1: + app = "active" + elif visible: + app = "new" + else: + app = "global" + + if app == "new": + app = xw.App(visible=visible, add_book=False) + elif app == "active": + app = xw.apps.active + elif app == "global": + if global_app is None: + atexit.register(kill_global_app) + if global_app is None or not is_app_alive(global_app): + global_app = xw.App(visible=visible, add_book=False) + app = global_app + assert isinstance(app, xw.App) + + if visible: + app.visible = visible + + if silent is None: + silent = not visible + + update_links_backup = app.api.AskToUpdateLinks + display_alerts_backup = app.display_alerts + if silent: + # try to update links silently instead of asking: "Update", "Don't Update", "Help" + app.api.AskToUpdateLinks = False + + # in case some links cannot be updated, continue instead of asking: "Continue" or "Edit Links..." + app.display_alerts = False + + if filepath is None: + # creates a new/blank Book + xw_wkb = app.books.add() + elif filepath == -1: + xw_wkb = app.books.active + elif xw_wkb is None: + # file already exists (and is a file) + if os.path.isfile(filepath): + xw_wkb = app.books.open(filepath) + else: + # let us remember the path + self.delayed_filepath = filepath + xw_wkb = app.books.add() + + if silent: + app.api.AskToUpdateLinks = update_links_backup + app.display_alerts = display_alerts_backup + + self.xw_wkb = xw_wkb + + def __contains__(self, key): + if isinstance(key, int): + length = len(self) + return -length <= key < length + else: + # I would like to use: "return key in wb.sheets" but as of xlwings 0.10 wb.sheets.__contains__ does not + # work for sheet names (it works with Sheet objects I think) + return key in self.sheet_names() + + def _ipython_key_completions_(self): + return list(self.sheet_names()) + + def __getitem__(self, key): + key = _translate_sheet_name(key) + if key in self: + return Sheet(self, key) + else: + raise KeyError('Workbook has no sheet named {}'.format(key)) + + def __setitem__(self, key, value): + key = _translate_sheet_name(key) + if self.new_workbook: + self.xw_wkb.sheets[0].name = key + self.new_workbook = False + key_in_self = key in self + if isinstance(value, Sheet): + if value.xw_sheet.book.app != self.xw_wkb.app: + raise ValueError("cannot copy a sheet from one instance of Excel to another") + + # xlwings index is 1-based + # TODO: implement Workbook.index(key) + target_idx = self[key].xw_sheet.index - 1 if key_in_self else -1 + target_sheet = self[target_idx].xw_sheet + # add new sheet after target sheet. The new sheet will be named something like "value.name (1)" but I + # do not think there is anything we can do about this, except rename it afterwards because Copy has no + # name argument. See https://msdn.microsoft.com/en-us/library/office/ff837784.aspx + value.xw_sheet.api.Copy(None, target_sheet.api) + if key_in_self: + target_sheet.delete() + # rename the new sheet + self[target_idx].name = key + return + if key_in_self: + sheet = self[key] + sheet.clear() + else: + xw_sheet = self.xw_wkb.sheets.add(key, after=self[-1].xw_sheet) + sheet = Sheet(None, None, xw_sheet=xw_sheet) + sheet["A1"] = value + + def __delitem__(self, key): + self[key].delete() + + def sheet_names(self): + return [s.name for s in self] + + def save(self, path=None): + # saved_path = self.xw_wkb.api.Path + # was_saved = saved_path != '' + if path is None and self.delayed_filepath is not None: + path = self.delayed_filepath + self.xw_wkb.save(path=path) + + def close(self): + # Close the workbook in Excel. + # This will not quit the Excel instance, even if this was the last workbook of that Excel instance. + if self.filepath is not None and os.path.isfile(self.xw_wkb.fullname): + tmp_file = self.xw_wkb.fullname + self.xw_wkb.close() + os.remove(self.filepath) + os.rename(tmp_file, self.filepath) + else: + self.xw_wkb.close() + + def __iter__(self): + return iter([Sheet(None, None, xw_sheet) + for xw_sheet in self.xw_wkb.sheets]) + + def __len__(self): + return len(self.xw_wkb.sheets) + + def __dir__(self): + return list(set(dir(self.__class__)) | set(dir(self.xw_wkb))) + + def __getattr__(self, key): + return getattr(self.xw_wkb, key) + + def __enter__(self): + return self + + def __exit__(self, type_, value, traceback): + self.close() + + def __repr__(self): + cls = self.__class__ + return '<{}.{} [{}]>'.format(cls.__module__, cls.__name__, self.name) + + + def _fill_slice(s, length): + """ + replaces a slice None bounds by actual bounds. + + Parameters + ---------- + s : slice + slice to replace + length : int + length of sequence + + Returns + ------- + slice + """ + return slice(s.start if s.start is not None else 0, s.stop if s.stop is not None else length, s.step) + + + def _concrete_key(key, obj, ndim=2): + """Expand key to ndim and replace None in slices start/stop bounds by 0 or obj.shape[corresponding_dim] + respectively. + + Parameters + ---------- + key : scalar, slice or tuple + input key + obj : object + any object with a 'shape' attribute. + ndim : int + number of dimensions to expand to. We could use len(obj.shape) instead but we avoid it to not trigger + obj.shape, which can be expensive in the case of a sheet with blank cells after the data. + """ + if not isinstance(key, tuple): + key = (key,) + + if len(key) < ndim: + key = key + (slice(None),) * (ndim - len(key)) + + # only compute shape if necessary because it can be expensive in some cases + if any(isinstance(k, slice) and k.stop is None for k in key): + shape = obj.shape + else: + shape = (None, None) + + # We use _fill_slice instead of slice(*k.indices(length)) because the later also clips bounds which exceed + # the length and we do NOT want to do that in this case (see issue #273). + return [_fill_slice(k, length) if isinstance(k, slice) else k + for k, length in zip(key, shape)] + + + class Sheet(object): + def __init__(self, workbook, key, xw_sheet=None): + if xw_sheet is None: + xw_sheet = workbook.xw_wkb.sheets[key] + object.__setattr__(self, 'xw_sheet', xw_sheet) + + # TODO: we can probably scrap this for xlwings 0.9+. We need to have + # a unit test for this though. + def __getitem__(self, key): + if isinstance(key, string_types): + return Range(self, key) + + row, col = _concrete_key(key, self) + if isinstance(row, slice) or isinstance(col, slice): + row1, row2 = (row.start, row.stop) if isinstance(row, slice) else (row, row + 1) + col1, col2 = (col.start, col.stop) if isinstance(col, slice) else (col, col + 1) + return Range(self, (row1 + 1, col1 + 1), (row2, col2)) + else: + return Range(self, (row + 1, col + 1)) + + def __setitem__(self, key, value): + if isinstance(value, LArray): + value = value.dump(header=False) + self[key].xw_range.value = value + + @property + def shape(self): + """ + shape of sheet including top-left empty rows/columns but excluding bottom-right ones. + """ + from xlwings.constants import Direction as xldir + + sheet = self.xw_sheet.api + used = sheet.UsedRange + first_row = used.Row + first_col = used.Column + last_row = first_row + used.Rows.Count - 1 + last_col = first_col + used.Columns.Count - 1 + last_cell = sheet.Cells(last_row, last_col) + + # fast path for sheets with a non blank bottom-right value + if last_cell.Value is not None: + return last_row, last_col + + last_row_used = last_cell.End(xldir.xlToLeft).Value is not None + last_col_used = last_cell.End(xldir.xlUp).Value is not None + + # fast path for sheets where last row and last col are not entirely blank + if last_row_used and last_col_used: + return last_row, last_col + else: + LEFT, UP = xldir.xlToLeft, xldir.xlUp + + def line_length(row, col, direction): + last_cell = sheet.Cells(row, col) + if last_cell.Value is not None: + return col if direction is LEFT else row + first_cell = last_cell.End(direction) + pos = first_cell.Column if direction is LEFT else first_cell.Row + return pos - 1 if first_cell.Value is None else pos + + if last_row < last_col: + if last_row_used or last_row == 1: + max_row = last_row + else: + for max_row in range(last_row - 1, first_row - 1, -1): + if line_length(max_row, last_col, LEFT) > 0: + break + if last_col_used or last_col == 1: + max_col = last_col + else: + max_col = max(line_length(row, last_col, LEFT) for row in range(first_row, max_row + 1)) + else: + if last_col_used or last_col == 1: + max_col = last_col + else: + for max_col in range(last_col - 1, first_col - 1, -1): + if line_length(last_row, max_col, UP) > 0: + break + if last_row_used or last_row == 1: + max_row = last_row + else: + max_row = max(line_length(last_row, col, UP) for col in range(first_col, max_col + 1)) + return max_row, max_col + + @property + def ndim(self): + return 2 + + def __array__(self, dtype=None): + return np.asarray(self[:], dtype=dtype) + + def __dir__(self): + return list(set(dir(self.__class__)) | set(dir(self.xw_sheet))) + + def __getattr__(self, key): + return getattr(self.xw_sheet, key) + + def __setattr__(self, key, value): + setattr(self.xw_sheet, key, value) + + def load(self, header=True, convert_float=True, nb_index=None, index_col=None, fill_value=np.nan, + sort_rows=False, sort_columns=False, wide=True): + return self[:].load(header=header, convert_float=convert_float, nb_index=nb_index, index_col=index_col, + fill_value=fill_value, sort_rows=sort_rows, sort_columns=sort_columns, wide=wide) + + # TODO: generalize to more than 2 dimensions or scrap it + def array(self, data, row_labels=None, column_labels=None, names=None): + """ + + Parameters + ---------- + data : str + range for data + row_labels : str, optional + range for row labels + column_labels : str, optional + range for column labels + names : list of str, optional + + Returns + ------- + LArray + """ + if row_labels is not None: + row_labels = np.asarray(self[row_labels]) + if column_labels is not None: + column_labels = np.asarray(self[column_labels]) + if names is not None: + labels = (row_labels, column_labels) + axes = [Axis(axis_labels, name) for axis_labels, name in zip(labels, names)] + else: + axes = (row_labels, column_labels) + # _converted_value is used implicitly via Range.__array__ + return LArray(np.asarray(self[data]), axes) + + def __repr__(self): + cls = self.__class__ + xw_sheet = self.xw_sheet + return '<{}.{} [{}]{}>'.format(cls.__module__, cls.__name__, xw_sheet.book.name, xw_sheet.name) + + + class Range(object): + def __init__(self, sheet, *args): + xw_range = sheet.xw_sheet.range(*args) + + object.__setattr__(self, 'sheet', sheet) + object.__setattr__(self, 'xw_range', xw_range) + + def _range_key_to_sheet_key(self, key): + # string keys does not make sense in this case + assert not isinstance(key, string_types) + row_offset = self.xw_range.row1 - 1 + col_offset = self.xw_range.col1 - 1 + row, col = _concrete_key(key, self.xw_range) + row = slice(row.start + row_offset, row.stop + row_offset) if isinstance(row, slice) else row + row_offset + col = slice(col.start + col_offset, col.stop + col_offset) if isinstance(col, slice) else col + col_offset + return row, col + + # TODO: we can probably scrap this for xlwings 0.9+. We need to have + # a unit test for this though. + def __getitem__(self, key): + return self.sheet[self._range_key_to_sheet_key(key)] + + def __setitem__(self, key, value): + self.sheet[self._range_key_to_sheet_key(key)] = value + + def _converted_value(self, convert_float=True): + list_data = self.xw_range.value + + # As of version 0.7.2 of xlwings, there is no built-in converter for + # this. The builtin .options(numbers=int) converter converts all + # values to int, whether that would loose information or not, but + # this is not what we want. + if convert_float: + # Excel 'numbers' are always floats + def convert(value): + if isinstance(value, float): + int_val = int(value) + if int_val == value: + return int_val + return value + elif isinstance(value, list): + return [convert(v) for v in value] + else: + return value + return convert(list_data) + return list_data + + def __float__(self): + # no need to use _converted_value because we will convert back to a float anyway + return float(self.xw_range.value) + + def __int__(self): + # no need to use _converted_value because we will convert to an int anyway + return int(self.xw_range.value) + + def __index__(self): + v = self._converted_value() + if hasattr(v, '__index__'): + return v.__index__() + else: + raise TypeError("only integer scalars can be converted to a scalar index") + + def __array__(self, dtype=None): + return np.array(self._converted_value(), dtype=dtype) + + def __larray__(self): + return LArray(self._converted_value()) + + def __dir__(self): + return list(set(dir(self.__class__)) | set(dir(self.xw_range))) + + def __getattr__(self, key): + if hasattr(LArray, key): + return getattr(self.__larray__(), key) + else: + return getattr(self.xw_range, key) + + def __setattr__(self, key, value): + setattr(self.xw_range, key, value) + + # TODO: implement all binops + # def __mul__(self, other): + # return self.__larray__() * other + + def __str__(self): + return str(self.__larray__()) + __repr__ = __str__ + + def load(self, header=True, convert_float=True, nb_index=None, index_col=None, fill_value=np.nan, + sort_rows=False, sort_columns=False, wide=True): + if not self.ndim: + return LArray([]) + + list_data = self._converted_value(convert_float=convert_float) + + if header: + return from_lists(list_data, nb_index=nb_index, index_col=index_col, fill_value=fill_value, + sort_rows=sort_rows, sort_columns=sort_columns, wide=wide) + else: + return LArray(list_data) + + # XXX: deprecate this function? + def open_excel(filepath=None, overwrite_file=False, visible=None, silent=None, app=None): + return Workbook(filepath, overwrite_file, visible, silent, app) +else: + class Workbook(object): + def __init__(self, filepath=None, overwrite_file=False, visible=None, silent=None, app=None): + raise Exception("Workbook class cannot be instanciated because xlwings is not installed") + + def sheet_names(self): + raise Exception() + + def save(self, path=None): + raise Exception() + + def close(self): + raise Exception() + + def open_excel(filepath=None, overwrite_file=False, visible=None, silent=None, app=None): + raise Exception("open_excel() is not available because xlwings is not installed") + + +# We define Workbook and open_excel documentation here since Readthedocs runs on Linux +if not PY2: + Workbook.__doc__ = """ +Excel Workbook. + +See Also +-------- +open_excel +""" + + Workbook.sheet_names.__doc__ = """ +Returns the names of the Excel sheets. + +Examples +-------- +>>> arr, arr2, arr3 = ndtest((3, 3)), ndtest((2, 2)), ndtest(4) +>>> with open_excel('excel_file.xlsx', overwrite_file=True) as wb: # doctest: +SKIP +... wb['arr'] = arr.dump() +... wb['arr2'] = arr2.dump() +... wb['arr3'] = arr3.dump() +... wb.save() +... +... wb.sheet_names() +['arr', 'arr2', 'arr3'] +""" + + Workbook.save.__doc__ = """ +Saves the Workbook. + +If a path is being provided, this works like SaveAs() in Excel. +If no path is specified and if the file hasn’t been saved previously, +it’s being saved in the current working directory with the current filename. +Existing files are overwritten without prompting. + +Parameters +---------- +path : str, optional + Full path to the workbook. Defaults to None. + +Examples +-------- +>>> arr, arr2, arr3 = ndtest((3, 3)), ndtest((2, 2)), ndtest(4) +>>> with open_excel('excel_file.xlsx', overwrite_file=True) as wb: # doctest: +SKIP +... wb['arr'] = arr.dump() +... wb['arr2'] = arr2.dump() +... wb['arr3'] = arr3.dump() +... wb.save() +""" + + Workbook.close.__doc__ = """ +Close the workbook in Excel. + +Need to be called if the workbook has been opened without the `with` statement. + +Examples +-------- +>>> arr, arr2, arr3 = ndtest((3, 3)), ndtest((2, 2)), ndtest(4) # doctest: +SKIP +>>> wb = open_excel('excel_file.xlsx', overwrite_file=True) # doctest: +SKIP +>>> wb['arr'] = arr.dump() # doctest: +SKIP +>>> wb['arr2'] = arr2.dump() # doctest: +SKIP +>>> wb['arr3'] = arr3.dump() # doctest: +SKIP +>>> wb.save() # doctest: +SKIP +>>> wb.close() # doctest: +SKIP +""" + +open_excel.__doc__ = """ +Open an Excel workbook + +Parameters +---------- +filepath : None, int or str, optional + path to the Excel file. The file must exist if overwrite_file is False. Use None for a new blank workbook, + -1 for the last active workbook. Defaults to None. +overwrite_file : bool, optional + whether or not to overwrite an existing file, if any. Defaults to False. +visible : None or bool, optional + whether or not Excel should be visible. Defaults to False for files, True for new/active workbooks and to None + ("unchanged") for existing unsaved workbooks. +silent : None or bool, optional + whether or not to show dialog boxes for updating links or when some links cannot be updated. + Defaults to False if visible, True otherwise. +app : None, "new", "active", "global" or xlwings.App, optional + use "new" for opening a new Excel instance, "active" for the last active instance (including ones opened by the + user) and "global" to (re)use the same instance for all workbooks of a program. None is equivalent to "active" if + filepath is -1, "new" if visible is True and "global" otherwise. Defaults to None. + + The "global" instance is a specific Excel instance for all input from/output to Excel from within a single Python + program (and should not interact with instances manually opened by the user or another program). + +Returns +------- +Excel workbook. + +Examples +-------- +>>> arr = ndtest((3, 3)) +>>> arr +a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + a2 6 7 8 + +create a new Excel file and save an array + +>>> # to create a new Excel file, argument overwrite_file must be set to True +>>> with open_excel('excel_file.xlsx', overwrite_file=True) as wb: # doctest: +SKIP +... wb['arr'] = arr.dump() +... wb.save() + +read array from an Excel file + +>>> with open_excel('excel_file.xlsx') as wb: # doctest: +SKIP +... arr2 = wb['arr'].load() +>>> arr2 # doctest: +SKIP +a\\b b0 b1 b2 + a0 0 1 2 + a1 3 4 5 + a2 6 7 8 +""" diff --git a/larray/inout/session.py b/larray/inout/session.py new file mode 100644 index 000000000..d799af343 --- /dev/null +++ b/larray/inout/session.py @@ -0,0 +1,323 @@ +from __future__ import absolute_import, division, print_function + +import os +from glob import glob +from collections import OrderedDict +from pandas import ExcelWriter, ExcelFile, HDFStore + +from larray.core.abstractbases import ABCLArray +from larray.util.misc import pickle +from larray.inout.excel import open_excel +from larray.inout.array import df_aslarray, read_csv, read_hdf + +try: + import xlwings as xw +except ImportError: + xw = None + + +def check_pattern(k, pattern): + return k.startswith(pattern) + + +class FileHandler(object): + """ + Abstract class defining the methods for "file handler" subclasses. + + Parameters + ---------- + fname : str + Filename. + + Attributes + ---------- + fname : str + Filename. + """ + def __init__(self, fname, overwrite_file=False): + self.fname = fname + self.original_file_name = None + self.overwrite_file = overwrite_file + + def _open_for_read(self): + raise NotImplementedError() + + def _open_for_write(self): + raise NotImplementedError() + + def list(self): + """ + Returns the list of arrays' names. + """ + raise NotImplementedError() + + def _read_array(self, key, *args, **kwargs): + raise NotImplementedError() + + def _dump(self, key, value, *args, **kwargs): + raise NotImplementedError() + + def save(self): + """ + Saves arrays in file. + """ + pass + + def close(self): + """ + Closes file. + """ + raise NotImplementedError() + + def _get_original_file_name(self): + if self.overwrite_file and os.path.isfile(self.fname): + self.original_file_name = self.fname + self.fname = '{}~{}'.format(*os.path.splitext(self.fname)) + + def _update_original_file(self): + if self.original_file_name is not None and os.path.isfile(self.fname): + os.remove(self.original_file_name) + os.rename(self.fname, self.original_file_name) + + def read_arrays(self, keys, *args, **kwargs): + """ + Reads file content (HDF, Excel, CSV, ...) and returns a dictionary containing loaded arrays. + + Parameters + ---------- + keys : list of str + List of arrays' names. + *args : any + Any other argument is passed through to the underlying read function. + display : bool, optional + Whether or not the function should display a message when starting and ending to load each array. + Defaults to False. + ignore_exceptions : bool, optional + Whether or not an exception should stop the function or be ignored. Defaults to False. + **kwargs : any + Any other keyword argument is passed through to the underlying read function. + + Returns + ------- + OrderedDict(str, LArray) + Dictionary containing the loaded arrays. + """ + display = kwargs.pop('display', False) + ignore_exceptions = kwargs.pop('ignore_exceptions', False) + self._open_for_read() + res = OrderedDict() + if keys is None: + keys = self.list() + for key in keys: + if display: + print("loading", key, "...", end=' ') + try: + res[key] = self._read_array(key, *args, **kwargs) + except Exception: + if not ignore_exceptions: + raise + if display: + print("done") + self.close() + return res + + def dump_arrays(self, key_values, *args, **kwargs): + """ + Dumps arrays corresponds to keys in file in HDF, Excel, CSV, ... format + + Parameters + ---------- + key_values : list of (str, LArray) pairs + Name and data of arrays to dump. + kwargs : + * display: whether or not to display when the dump of each array is started/done. + """ + display = kwargs.pop('display', False) + self._get_original_file_name() + self._open_for_write() + for key, value in key_values: + if isinstance(value, ABCLArray) and value.ndim == 0: + if display: + print('Cannot dump {}. Dumping 0D arrays is currently not supported.'.format(key)) + continue + if display: + print("dumping", key, "...", end=' ') + self._dump(key, value, *args, **kwargs) + if display: + print("done") + self.save() + self.close() + self._update_original_file() + + +class PandasHDFHandler(FileHandler): + """ + Handler for HDF5 files using Pandas. + """ + def _open_for_read(self): + self.handle = HDFStore(self.fname, mode='r') + + def _open_for_write(self): + self.handle = HDFStore(self.fname) + + def list(self): + return [key.strip('/') for key in self.handle.keys()] + + def _to_hdf_key(self, key): + return '/' + key + + def _read_array(self, key, *args, **kwargs): + return read_hdf(self.handle, self._to_hdf_key(key), *args, **kwargs) + + def _dump(self, key, value, *args, **kwargs): + value.to_hdf(self.handle, self._to_hdf_key(key), *args, **kwargs) + + def close(self): + self.handle.close() + + +class PandasExcelHandler(FileHandler): + """ + Handler for Excel files using Pandas. + """ + def _open_for_read(self): + self.handle = ExcelFile(self.fname) + + def _open_for_write(self): + self.handle = ExcelWriter(self.fname) + + def list(self): + return self.handle.sheet_names + + def _read_array(self, key, *args, **kwargs): + df = self.handle.parse(key, *args, **kwargs) + return df_aslarray(df, raw=True) + + def _dump(self, key, value, *args, **kwargs): + kwargs['engine'] = 'xlsxwriter' + value.to_excel(self.handle, key, *args, **kwargs) + + def close(self): + self.handle.close() + + +class XLWingsHandler(FileHandler): + """ + Handler for Excel files using XLWings. + """ + def _get_original_file_name(self): + # for XLWingsHandler, no need to create a temporary file, the job is already done in the Workbook class + pass + + def _open_for_read(self): + self.handle = open_excel(self.fname) + + def _open_for_write(self): + self.handle = open_excel(self.fname, overwrite_file=self.overwrite_file) + + def list(self): + return self.handle.sheet_names() + + def _read_array(self, key, *args, **kwargs): + return self.handle[key].load(*args, **kwargs) + + def _dump(self, key, value, *args, **kwargs): + self.handle[key] = value.dump(*args, **kwargs) + + def save(self): + self.handle.save() + + def close(self): + self.handle.close() + + +class PandasCSVHandler(FileHandler): + def __init__(self, fname, overwrite_file=False): + super(PandasCSVHandler, self).__init__(fname, overwrite_file) + if fname is None: + self.pattern = None + self.directory = None + elif '.csv' in fname or '*' in fname or '?' in fname: + self.pattern = fname + self.directory = os.path.dirname(fname) + else: + # assume fname is a directory. + # Not testing for os.path.isdir(fname) here because when writing, the directory might not exist. + self.pattern = os.path.join(fname, '*.csv') + self.directory = fname + + def _get_original_file_name(self): + pass + + def _open_for_read(self): + if self.directory and not os.path.isdir(self.directory): + raise ValueError("Directory '{}' does not exist".format(self.directory)) + + def _open_for_write(self): + if self.directory is not None: + try: + os.makedirs(self.directory) + except OSError: + if not os.path.isdir(self.directory): + raise ValueError("Path {} must represent a directory".format(self.directory)) + + def list(self): + fnames = glob(self.pattern) if self.pattern is not None else [] + # drop directory + fnames = [os.path.basename(fname) for fname in fnames] + # strip extension from files + # XXX: unsure we should use sorted here + return sorted([os.path.splitext(fname)[0] for fname in fnames]) + + def _to_filepath(self, key): + if self.directory is not None: + return os.path.join(self.directory, '{}.csv'.format(key)) + else: + return key + + def _read_array(self, key, *args, **kwargs): + return read_csv(self._to_filepath(key), *args, **kwargs) + + def _dump(self, key, value, *args, **kwargs): + value.to_csv(self._to_filepath(key), *args, **kwargs) + + def close(self): + pass + + +class PickleHandler(FileHandler): + def _open_for_read(self): + with open(self.fname, 'rb') as f: + self.data = pickle.load(f) + + def _open_for_write(self): + self.data = OrderedDict() + + def list(self): + return self.data.keys() + + def _read_array(self, key): + return self.data[key] + + def _dump(self, key, value): + self.data[key] = value + + def close(self): + with open(self.fname, 'wb') as f: + pickle.dump(self.data, f) + + +handler_classes = { + 'pickle': PickleHandler, + 'pandas_csv': PandasCSVHandler, + 'pandas_hdf': PandasHDFHandler, + 'pandas_excel': PandasExcelHandler, + 'xlwings_excel': XLWingsHandler, +} + +ext_default_engine = { + 'csv': 'pandas_csv', + 'h5': 'pandas_hdf', 'hdf': 'pandas_hdf', + 'pkl': 'pickle', 'pickle': 'pickle', + 'xls': 'xlwings_excel', 'xlsx': 'xlwings_excel', +} diff --git a/larray/ipfp/__init__.py b/larray/ipfp/__init__.py new file mode 100644 index 000000000..953093522 --- /dev/null +++ b/larray/ipfp/__init__.py @@ -0,0 +1,8 @@ +from __future__ import absolute_import + +import warnings + +import larray.extra.ipfp as ipfp + +warnings.warn('ipfp function should be imported as "from larray import ipfp" or not imported explicitly at all if you ' + 'use "from larray import *"', FutureWarning, stacklevel=2) diff --git a/larray/session.py b/larray/session.py deleted file mode 100644 index 362fe6dda..000000000 --- a/larray/session.py +++ /dev/null @@ -1,366 +0,0 @@ -from __future__ import absolute_import, division, print_function - -import os -import sys - -import numpy as np -from pandas import ExcelWriter, ExcelFile, HDFStore -from larray.core import LArray, Axis, read_csv, read_hdf, df_aslarray, \ - larray_equal - - -def check_pattern(k, pattern): - return k.startswith(pattern) - - -class FileHandler(object): - def __init__(self, fname): - self.fname = fname - - def _open_for_read(self): - raise NotImplementedError() - - def _open_for_write(self): - raise NotImplementedError() - - def list(self): - raise NotImplementedError() - - def _read_array(self, key, *args, **kwargs): - raise NotImplementedError() - - def _dump(self, key, value, *args, **kwargs): - raise NotImplementedError() - - def close(self): - raise NotImplementedError() - - def read_arrays(self, keys, *args, **kwargs): - display = kwargs.pop('display', False) - self._open_for_read() - res = {} - if keys is None: - keys = self.list() - for key in keys: - if display: - print("loading", key, "...", end=' ') - dest_key = key.strip('/') - res[dest_key] = self._read_array(key, *args, **kwargs) - if display: - print("done") - self.close() - return res - - def dump_arrays(self, key_values, *args, **kwargs): - display = kwargs.pop('display', False) - self._open_for_write() - for key, value in key_values: - if display: - print("dumping", key, "...", end=' ') - self._dump(key, value, *args, **kwargs) - if display: - print("done") - self.close() - - -class HDFHandler(FileHandler): - def _open_for_read(self): - self.handle = HDFStore(self.fname, mode='r') - - def _open_for_write(self): - self.handle = HDFStore(self.fname) - - def list(self): - return self.handle.keys() - - def _read_array(self, key, *args, **kwargs): - return read_hdf(self.handle, key, *args, **kwargs) - - def _dump(self, key, value, *args, **kwargs): - value.to_hdf(self.handle, key, *args, **kwargs) - - def close(self): - self.handle.close() - - -class ExcelHandler(FileHandler): - def _open_for_read(self): - self.handle = ExcelFile(self.fname) - - def _open_for_write(self): - self.handle = ExcelWriter(self.fname) - - def list(self): - return self.handle.sheet_names - - def _read_array(self, key, *args, **kwargs): - df = self.handle.parse(key, *args, **kwargs) - return df_aslarray(df) - - def _dump(self, key, value, *args, **kwargs): - kwargs['engine'] = 'xlsxwriter' - value.to_excel(self.handle, key, *args, **kwargs) - - def close(self): - self.handle.close() - - -class CSVHandler(FileHandler): - def _open_for_read(self): - pass - - def _open_for_write(self): - try: - os.makedirs(self.fname) - except OSError: - if not os.path.isdir(self.fname): - raise - - def list(self): - # strip extension from files - # FIXME: only take .csv files - # TODO: also support fname pattern, eg. "dump_*.csv" - return [os.path.splitext(fname)[0] for fname in os.listdir(self.fname)] - - def _read_array(self, key, *args, **kwargs): - fpath = os.path.join(self.fname, '{}.csv'.format(key)) - return read_csv(fpath, *args, **kwargs) - - def _dump(self, key, value, *args, **kwargs): - value.to_csv(os.path.join(self.fname, '{}.csv'.format(key)), *args, - **kwargs) - - def close(self): - pass - - -ext_classes = {'h5': HDFHandler, 'hdf': HDFHandler, - 'xls': ExcelHandler, 'xlsx': ExcelHandler, - 'csv': CSVHandler} - - -class Session(object): - def __init__(self, *args, **kwargs): - # self._objects = {} - object.__setattr__(self, '_objects', {}) - - if len(args) == 1: - a0 = args[0] - if isinstance(a0, dict): - self.add(**a0) - elif isinstance(a0, str): - # assume a0 is a filename - self.load(a0) - else: - # assume we have an iterable of tuples - for k, v in a0: - self[k] = v - else: - self.add(*args, **kwargs) - - # XXX: behave like a dict and return keys instead or return unsorted? - def __iter__(self): - return iter(self._objects[k] for k in self.names) - - def add(self, *args, **kwargs): - for arg in args: - self[arg.name] = arg - for k, v in kwargs.items(): - self[k] = v - - def __getitem__(self, key): - if isinstance(key, int): - return self._objects[self.names[key]] - elif isinstance(key, LArray): - assert np.issubdtype(key.dtype, np.bool_) - assert key.ndim == 1 - # only keep True values - truenames = key[key].axes[0].labels - return Session({name: self[name] for name in truenames}) - elif isinstance(key, (tuple, list)): - assert all(isinstance(k, str) for k in key) - return Session({k: self[k] for k in key}) - else: - return self._objects[key] - - def get(self, key, default=None): - try: - return self[key] - except KeyError: - return default - - def __setitem__(self, key, value): - self._objects[key] = value - - def __getattr__(self, key): - return self._objects[key] - - def __setattr__(self, key, value): - self._objects[key] = value - - def load(self, fname, names=None, fmt='auto', display=False, **kwargs): - """Load LArray objects from a file. - - Parameters - ---------- - fname : str - Path to the file. - names : list of str, optional - List of arrays to load. Defaults to all valid objects present in - the file/directory. - fmt : str, optional - Dump to the `fmt` format. Defaults to 'auto' (guess from - filename). - display : bool, optional - whether or not to display which file is being worked on. Defaults - to False. - """ - if display: - print("opening", fname) - # TODO: support path + *.csv - if fmt == 'auto': - _, ext = os.path.splitext(fname) - fmt = ext.strip('.') - handler = ext_classes[fmt](fname) - arrays = handler.read_arrays(names, display=display, **kwargs) - for k, v in arrays.items(): - self[k] = v - - def dump(self, fname, names=None, fmt='auto', display=False, **kwargs): - """Dumps all LArray objects to a file. - - Parameters - ---------- - fname : str - Path for the dump. - names : list of str or None, optional - list of names of objects to dump. Defaults to all objects - present in the Session. - fmt : str, optional - Dump to the `fmt` format. Defaults to 'auto' (guess from - filename). - display : bool, optional - whether or not to display which file is being worked on. Defaults - to False. - """ - if fmt == 'auto': - _, ext = os.path.splitext(fname) - fmt = ext.strip('.') - handler = ext_classes[fmt](fname) - arrays = self.filter(kind=LArray).items() - if names is not None: - names_set = set(names) - arrays = [(k, v) for k, v in arrays if k in names_set] - handler.dump_arrays(arrays, display=display, **kwargs) - - def dump_hdf(self, fname, names=None, *args, **kwargs): - self.dump(fname, names, 'hdf', *args, **kwargs) - - def dump_excel(self, fname, names=None, *args, **kwargs): - self.dump(fname, names, 'xlsx', *args, **kwargs) - - def dump_csv(self, fname, names=None, *args, **kwargs): - self.dump(fname, names, 'csv', *args, **kwargs) - - def filter(self, pattern=None, kind=None): - """Return a new Session with objects which match some criteria. - - Parameters - ---------- - pattern : str, optional - Only keep objects whose key match `pattern`. - kind : type, optional - Only keep objects which are instances of type `kind`. - - Returns - ------- - Session - The filtered session. - """ - if pattern is not None: - items = [(k, self._objects[k]) for k in self._objects.keys() - if check_pattern(k, pattern)] - else: - items = self._objects.items() - if kind is not None: - return Session([(k, v) for k, v in items if isinstance(v, kind)]) - else: - return Session(items) - - # XXX: would having an option/another function for returning this unsorted - # be any useful? - @property - def names(self): - """Returns the list of names of the objects in the session - - Returns - ------- - list of str - """ - return sorted(self._objects.keys()) - - # XXX: sorted? - def values(self): - return self._objects.values() - - # XXX: sorted? - def items(self): - return self._objects.items() - - def __repr__(self): - return 'Session({})'.format(', '.join(self.names)) - - def __len__(self): - return len(self._objects) - - def __eq__(self, other): - self_names = set(self.names) - all_names = self.names + [n for n in other.names if n not in self_names] - res = [larray_equal(self.get(name), other.get(name)) - for name in all_names] - return LArray(res, [Axis('name', all_names)]) - - def __ne__(self, other): - return ~(self == other) - - # we could implement two(?) very different behavior: - # set-like behavior: combination of two Session, if same name, - # check that it is the same. a Session is more ordered-dict-like than - # set-like, so this might not make a lot of sense. an "update" method - # might make more sense. However most set-like operations do make sense. - - # intersection: check common are the same or take left? - # union: check common are the same or take left? - # difference - - # elementwise add: consider Session as an array-like and try to add the - # each array individually - def __add__(self, other): - self_names = set(self.names) - all_names = self.names + [n for n in other.names if n not in self_names] - return Session({name: self.get(name, np.nan) + other.get(name, np.nan) - for name in all_names}) - - def __sub__(self, other): - self_names = set(self.names) - all_names = self.names + [n for n in other.names if n not in self_names] - return Session({name: self.get(name, np.nan) - other.get(name, np.nan) - for name in all_names}) - - def __mul__(self, other): - self_names = set(self.names) - all_names = self.names + [n for n in other.names if n not in self_names] - return Session({name: self.get(name, np.nan) * other.get(name, np.nan) - for name in all_names}) - - def __truediv__(self, other): - self_names = set(self.names) - all_names = self.names + [n for n in other.names if n not in self_names] - return Session({name: self.get(name, np.nan) / other.get(name, np.nan) - for name in all_names}) - - -def local_arrays(): - # noinspection PyProtectedMember - d = sys._getframe(1).f_locals - return Session((k, v) for k, v in d.items() if isinstance(v, LArray)) diff --git a/larray/tests/common.py b/larray/tests/common.py new file mode 100644 index 000000000..bb55900d4 --- /dev/null +++ b/larray/tests/common.py @@ -0,0 +1,100 @@ +from __future__ import absolute_import, division, print_function + +import os +import numpy as np +from larray import LArray, isnan, aslarray + + +TESTDATADIR = os.path.dirname(__file__) + +def inputpath(relpath): + """ + Parameters + ---------- + relpath: str + path relative to current module + + Returns + ------- + absolute path to input data file + """ + return os.path.join(TESTDATADIR, 'data', relpath) + + +# XXX: maybe we should force value groups to use tuple and families (group of groups to use lists, or vice versa, so +# that we know which is which) or use a class, just for that? group(a, b, c) vs family(group(a), b, c) + + +def assert_equal_factory(test_func): + def assert_equal(a, b): + if isinstance(a, LArray) and isinstance(b, LArray) and a.axes != b.axes: + raise AssertionError("axes differ:\n%s\n\nvs\n\n%s" % (a.axes.info, b.axes.info)) + if not isinstance(a, (np.ndarray, LArray)): + a = np.asarray(a) + if not isinstance(b, (np.ndarray, LArray)): + b = np.asarray(b) + if a.shape != b.shape: + raise AssertionError("shapes differ: %s != %s" % (a.shape, b.shape)) + equal = test_func(a, b) + if not equal.all(): + # XXX: for some reason ndarray[bool_larray] does not work as we would like, so we cannot do b[~equal] + # directly. I should at least understand why this happens and fix this if possible. + notequal = np.asarray(~equal) + raise AssertionError("\ngot:\n\n%s\n\nexpected:\n\n%s" % (a[notequal], b[notequal])) + return assert_equal + + +def assert_larray_equal_factory(test_func, convert=True, check_axes=False): + def assert_equal(a, b): + if convert: + a = aslarray(a) + b = aslarray(b) + if check_axes and a.axes != b.axes: + raise AssertionError("axes differ:\n%s\n\nvs\n\n%s" % (a.axes.info, b.axes.info)) + equal = test_func(a, b) + if not equal.all(): + notequal = ~equal + raise AssertionError("\ngot:\n\n%s\n\nexpected:\n\n%s" % (a[notequal], b[notequal])) + return assert_equal + + +def assert_nparray_equal_factory(test_func, convert=True, check_shape=False): + def assert_equal(a, b): + if convert: + a = np.asarray(a) + b = np.asarray(b) + if check_shape and a.shape != b.shape: + raise AssertionError("shapes differ: %s != %s" % (a.shape, b.shape)) + equal = test_func(a, b) + if not equal.all(): + notequal = ~equal + raise AssertionError("\ngot:\n\n%s\n\nexpected:\n\n%s" % (a[notequal], b[notequal])) + return assert_equal + + +def equal(a, b): + return a == b + + +def nan_equal(a, b): + return (a == b) | (isnan(a) & isnan(b)) + + +# numpy.testing.assert_array_equal/assert_equal would work too but it does not (as of numpy 1.10) display specifically +# the non equal items +# TODO: this is defined for backward compatibility only (until we update all tests to use either assert_larray* or +# assert_nparray*) +assert_array_equal = assert_equal_factory(equal) +assert_array_nan_equal = assert_equal_factory(nan_equal) + +assert_larray_equal = assert_larray_equal_factory(equal, check_axes=True) +assert_larray_nan_equal = assert_larray_equal_factory(nan_equal, check_axes=True) + +assert_larray_equiv = assert_larray_equal_factory(equal) +assert_larray_nan_equiv = assert_larray_equal_factory(nan_equal) + +assert_nparray_equal = assert_nparray_equal_factory(equal, check_shape=True) +assert_nparray_nan_equal = assert_nparray_equal_factory(nan_equal, check_shape=True) + +assert_nparray_equiv = assert_nparray_equal_factory(equal) +assert_nparray_nan_equiv = assert_nparray_equal_factory(nan_equal) diff --git a/larray/tests/data/demography.h5 b/larray/tests/data/demography.h5 new file mode 100644 index 000000000..6dd9ddab6 Binary files /dev/null and b/larray/tests/data/demography.h5 differ diff --git a/larray/tests/data/demography.xlsx b/larray/tests/data/demography.xlsx new file mode 100644 index 000000000..ce4e2fc92 Binary files /dev/null and b/larray/tests/data/demography.xlsx differ diff --git a/larray/tests/data/hh.csv b/larray/tests/data/hh.csv new file mode 100644 index 000000000..ab62a8759 --- /dev/null +++ b/larray/tests/data/hh.csv @@ -0,0 +1,79 @@ +time,geo\hh_type,SING,'MAR0,MAR+,UNM0,UNM+,H1P,OTHR +1991,BruCap,246263,75989,98036,6121,5095,44054,6360 +1991,Fla,557046,554965,880325,38991,24785,147780,28348 +1991,Wal,384482,274117,450679,27521,26015,120647,18955 +1992,BruCap,242368,75046,96480,6719,5593,43537,6292 +1992,Fla,563347,562400,877519,42615,26940,149289,27148 +1992,Wal,389439,275071,448940,29187,28226,122574,19158 +1993,BruCap,243432,74417,95132,7484,6220,43637,6168 +1993,Fla,571006,567981,873498,46246,29187,152090,27866 +1993,Wal,394258,275726,446173,31171,30723,125291,19282 +1994,BruCap,238869,74416,94375,8781,6951,43691,5641 +1994,Fla,577013,571758,867501,51174,31857,154880,28184 +1994,Wal,394782,275362,442349,34259,33453,127738,19526 +1995,BruCap,236871,74317,94037,9585,7498,43642,5639 +1995,Fla,586122,577144,859552,56130,34398,158131,28513 +1995,Wal,397818,275882,437342,37157,35784,130434,19920 +1996,BruCap,235983,72847,92686,10182,7909,43668,5932 +1996,Fla,597123,581802,850463,60907,36853,161140,28698 +1996,Wal,403028,275803,430858,39458,37889,133585,20270 +1997,BruCap,236874,72071,91718,10700,8289,44464,6025 +1997,Fla,611451,586656,841282,65450,39382,164384,29022 +1997,Wal,410586,275931,424620,41240,40171,136981,20334 +1998,BruCap,237930,70893,90766,11536,8795,45099,6458 +1998,Fla,625826,590905,830165,70826,42273,168470,29068 +1998,Wal,419518,275988,417576,43316,42644,140665,20372 +1999,BruCap,237970,69516,89784,12432,9370,45856,6839 +1999,Fla,640206,593339,817812,77399,46642,172138,29455 +1999,Wal,428203,275535,410483,45942,45453,144085,20382 +2000,BruCap,237212,68579,89498,13375,10182,46395,7293 +2000,Fla,654357,594633,805047,83958,51549,175912,30292 +2000,Wal,436571,276074,402855,48529,49019,146948,20462 +2001,BruCap,237878,67903,88727,14247,10677,47349,8029 +2001,Fla,669236,596615,791174,90678,57339,179011,31812 +2001,Wal,446818,276193,394993,50123,52185,150934,21041 +2002,BruCap,241994,66859,88895,15052,11654,48715,8565 +2002,Fla,682478,597985,776911,98623,64448,183538,32679 +2002,Wal,458309,276194,386719,52118,55588,156090,21216 +2003,BruCap,244771,66376,88963,15918,12358,50079,9364 +2003,Fla,698383,599702,762360,105570,72208,188098,33825 +2003,Wal,469780,275540,378243,53974,59157,161381,21655 +2004,BruCap,245662,65926,89033,16242,12855,51306,10013 +2004,Fla,713852,601806,747516,111252,80062,193526,34329 +2004,Wal,482276,274733,369524,55848,62717,167570,22180 +2005,BruCap,245482,65300,89409,16706,13340,52311,10511 +2005,Fla,726291,604900,733954,116778,89365,197589,34969 +2005,Wal,492257,274475,361634,58156,67066,172212,22621 +2006,BruCap,246624,64828,90277,17477,13851,53669,11062 +2006,Fla,739877,608155,722117,121992,99184,201081,35578 +2006,Wal,500758,274230,354992,60383,71828,176318,23161 +2007,BruCap,247689,64029,91419,17912,14759,54734,11723 +2007,Fla,753495,612213,711025,126851,109064,203672,36459 +2007,Wal,509323,274184,349596,62621,77226,178787,23529 +2008,BruCap,250976,63523,92806,18792,15777,55418,12352 +2008,Fla,767023,617804,699971,132641,119503,205509,37598 +2008,Wal,516428,274261,344038,65646,83014,180111,24224 +2009,BruCap,251731,63515,94792,19836,17029,56063,12115 +2009,Fla,780581,621987,689481,137302,130429,208412,36884 +2009,Wal,521412,273784,337982,68558,89304,181927,23795 +2010,BruCap,254173,62709,96783,20842,18201,57186,12674 +2010,Fla,795387,623066,679864,140918,140770,212206,37523 +2010,Wal,529776,272816,332894,70960,95495,183862,24188 +2011,BruCap,256463,61907,99248,22270,20030,58502,13455 +2011,Fla,802915,626511,672723,145778,151813,214168,38385 +2011,Wal,531337,272906,329672,74287,102451,184299,24461 +2012,BruCap,258055,60646,101498,23126,20819,59616,14593 +2012,Fla,816111,627678,664850,148874,161246,216798,39642 +2012,Wal,536529,271704,325142,77192,108428,185708,25120 +2013,BruCap,257130,59587,103098,23850,21675,60506,15852 +2013,Fla,824952,629398,659316,150236,167367,219040,41109 +2013,Wal,538932,269923,321716,79038,114254,186052,25823 +2014,BruCap,252668,58001,103791,24843,22685,61867,16585 +2014,Fla,834322,628011,651116,154401,175772,221880,42221 +2014,Wal,542509,267088,316802,81420,120104,187677,26339 +2015,BruCap,252404,56694,104484,25463,23805,62690,17130 +2015,Fla,848714,631210,641297,160191,182845,223582,43480 +2015,Wal,545435,265425,311700,83982,125750,189343,26677 +2016,BruCap,251574,56041,105326,26263,25016,63328,17846 +2016,Fla,857368,631174,635007,164189,189901,225812,44568 +2016,Wal,548776,263777,306730,87366,131704,189463,26955 diff --git a/larray/tests/data/pop.csv b/larray/tests/data/pop.csv new file mode 100644 index 000000000..82eb2b69d --- /dev/null +++ b/larray/tests/data/pop.csv @@ -0,0 +1,18877 @@ +time,geo,age,sex\nat,BE,FO +1991,BruCap,0,M,4182,2377 +1991,BruCap,0,F,4052,2188 +1991,BruCap,1,M,3904,2316 +1991,BruCap,1,F,3769,2241 +1991,BruCap,2,M,3790,2365 +1991,BruCap,2,F,3500,2318 +1991,BruCap,3,M,3569,2296 +1991,BruCap,3,F,3360,2232 +1991,BruCap,4,M,3499,2284 +1991,BruCap,4,F,3225,2196 +1991,BruCap,5,M,3239,2280 +1991,BruCap,5,F,2995,2106 +1991,BruCap,6,M,3298,2283 +1991,BruCap,6,F,3105,2203 +1991,BruCap,7,M,3155,2274 +1991,BruCap,7,F,3101,2096 +1991,BruCap,8,M,3144,2349 +1991,BruCap,8,F,2999,2278 +1991,BruCap,9,M,3252,2489 +1991,BruCap,9,F,3112,2322 +1991,BruCap,10,M,3213,2411 +1991,BruCap,10,F,3142,2355 +1991,BruCap,11,M,3136,2450 +1991,BruCap,11,F,2963,2255 +1991,BruCap,12,M,2997,2339 +1991,BruCap,12,F,3033,2312 +1991,BruCap,13,M,2974,2305 +1991,BruCap,13,F,2944,2254 +1991,BruCap,14,M,2946,2244 +1991,BruCap,14,F,2913,2140 +1991,BruCap,15,M,3036,2191 +1991,BruCap,15,F,2986,1990 +1991,BruCap,16,M,3021,2262 +1991,BruCap,16,F,2966,2026 +1991,BruCap,17,M,3306,2177 +1991,BruCap,17,F,3251,2127 +1991,BruCap,18,M,3504,2285 +1991,BruCap,18,F,3421,2262 +1991,BruCap,19,M,3785,2334 +1991,BruCap,19,F,3682,2385 +1991,BruCap,20,M,3926,2493 +1991,BruCap,20,F,3953,2432 +1991,BruCap,21,M,3934,2540 +1991,BruCap,21,F,4040,2531 +1991,BruCap,22,M,4286,2593 +1991,BruCap,22,F,4335,2505 +1991,BruCap,23,M,4570,2575 +1991,BruCap,23,F,4826,2536 +1991,BruCap,24,M,4772,2859 +1991,BruCap,24,F,5208,2824 +1991,BruCap,25,M,5215,2965 +1991,BruCap,25,F,5440,2893 +1991,BruCap,26,M,5360,3099 +1991,BruCap,26,F,5761,2970 +1991,BruCap,27,M,5467,3023 +1991,BruCap,27,F,5503,2875 +1991,BruCap,28,M,5190,3170 +1991,BruCap,28,F,5275,2888 +1991,BruCap,29,M,5095,3040 +1991,BruCap,29,F,5377,2861 +1991,BruCap,30,M,5063,3108 +1991,BruCap,30,F,5292,2916 +1991,BruCap,31,M,5074,2915 +1991,BruCap,31,F,5148,2669 +1991,BruCap,32,M,4722,2874 +1991,BruCap,32,F,5101,2616 +1991,BruCap,33,M,4747,2653 +1991,BruCap,33,F,4929,2437 +1991,BruCap,34,M,4487,2736 +1991,BruCap,34,F,4891,2426 +1991,BruCap,35,M,4475,2609 +1991,BruCap,35,F,4713,2351 +1991,BruCap,36,M,4502,2485 +1991,BruCap,36,F,4692,2200 +1991,BruCap,37,M,4452,2408 +1991,BruCap,37,F,4752,2128 +1991,BruCap,38,M,4299,2497 +1991,BruCap,38,F,4746,2134 +1991,BruCap,39,M,4273,2166 +1991,BruCap,39,F,4697,1828 +1991,BruCap,40,M,4200,2257 +1991,BruCap,40,F,4729,1969 +1991,BruCap,41,M,4222,2015 +1991,BruCap,41,F,4709,1695 +1991,BruCap,42,M,4301,2031 +1991,BruCap,42,F,4792,1687 +1991,BruCap,43,M,4405,1962 +1991,BruCap,43,F,5009,1575 +1991,BruCap,44,M,4524,1824 +1991,BruCap,44,F,4953,1532 +1991,BruCap,45,M,3787,1591 +1991,BruCap,45,F,4293,1406 +1991,BruCap,46,M,4000,1666 +1991,BruCap,46,F,4541,1387 +1991,BruCap,47,M,3883,1549 +1991,BruCap,47,F,4305,1337 +1991,BruCap,48,M,3301,1558 +1991,BruCap,48,F,3729,1255 +1991,BruCap,49,M,2956,1342 +1991,BruCap,49,F,3421,1141 +1991,BruCap,50,M,3341,1666 +1991,BruCap,50,F,3739,1426 +1991,BruCap,51,M,3537,1485 +1991,BruCap,51,F,4138,1217 +1991,BruCap,52,M,3542,1539 +1991,BruCap,52,F,4101,1136 +1991,BruCap,53,M,3558,1387 +1991,BruCap,53,F,4091,1117 +1991,BruCap,54,M,3437,1428 +1991,BruCap,54,F,4051,1133 +1991,BruCap,55,M,3500,1275 +1991,BruCap,55,F,4151,1149 +1991,BruCap,56,M,3683,1264 +1991,BruCap,56,F,4253,1022 +1991,BruCap,57,M,3700,1209 +1991,BruCap,57,F,4438,907 +1991,BruCap,58,M,3976,1240 +1991,BruCap,58,F,4701,942 +1991,BruCap,59,M,3999,1035 +1991,BruCap,59,F,4828,866 +1991,BruCap,60,M,3951,1130 +1991,BruCap,60,F,5178,921 +1991,BruCap,61,M,3877,1003 +1991,BruCap,61,F,4934,726 +1991,BruCap,62,M,3811,927 +1991,BruCap,62,F,4892,740 +1991,BruCap,63,M,3744,840 +1991,BruCap,63,F,4929,637 +1991,BruCap,64,M,3845,779 +1991,BruCap,64,F,5097,645 +1991,BruCap,65,M,3875,711 +1991,BruCap,65,F,5261,581 +1991,BruCap,66,M,4014,553 +1991,BruCap,66,F,5404,517 +1991,BruCap,67,M,3832,593 +1991,BruCap,67,F,5638,525 +1991,BruCap,68,M,3838,497 +1991,BruCap,68,F,5615,471 +1991,BruCap,69,M,4026,463 +1991,BruCap,69,F,5757,411 +1991,BruCap,70,M,3920,426 +1991,BruCap,70,F,5894,478 +1991,BruCap,71,M,2889,264 +1991,BruCap,71,F,4254,313 +1991,BruCap,72,M,1792,217 +1991,BruCap,72,F,3136,247 +1991,BruCap,73,M,1772,217 +1991,BruCap,73,F,3080,241 +1991,BruCap,74,M,1892,167 +1991,BruCap,74,F,3292,220 +1991,BruCap,75,M,2242,173 +1991,BruCap,75,F,3986,230 +1991,BruCap,76,M,2527,207 +1991,BruCap,76,F,4739,236 +1991,BruCap,77,M,2353,179 +1991,BruCap,77,F,4603,230 +1991,BruCap,78,M,2140,140 +1991,BruCap,78,F,4489,250 +1991,BruCap,79,M,1960,138 +1991,BruCap,79,F,4108,203 +1991,BruCap,80,M,1748,122 +1991,BruCap,80,F,4059,216 +1991,BruCap,81,M,1542,99 +1991,BruCap,81,F,3600,187 +1991,BruCap,82,M,1365,111 +1991,BruCap,82,F,3558,150 +1991,BruCap,83,M,1166,102 +1991,BruCap,83,F,3161,159 +1991,BruCap,84,M,1036,81 +1991,BruCap,84,F,2867,149 +1991,BruCap,85,M,865,52 +1991,BruCap,85,F,2577,144 +1991,BruCap,86,M,707,67 +1991,BruCap,86,F,2225,116 +1991,BruCap,87,M,623,27 +1991,BruCap,87,F,1954,104 +1991,BruCap,88,M,466,38 +1991,BruCap,88,F,1714,73 +1991,BruCap,89,M,388,35 +1991,BruCap,89,F,1417,79 +1991,BruCap,90,M,279,30 +1991,BruCap,90,F,1104,75 +1991,BruCap,91,M,199,20 +1991,BruCap,91,F,868,43 +1991,BruCap,92,M,158,12 +1991,BruCap,92,F,642,45 +1991,BruCap,93,M,111,13 +1991,BruCap,93,F,497,32 +1991,BruCap,94,M,74,4 +1991,BruCap,94,F,345,21 +1991,BruCap,95,M,46,6 +1991,BruCap,95,F,265,20 +1991,BruCap,96,M,41,1 +1991,BruCap,96,F,201,14 +1991,BruCap,97,M,29,7 +1991,BruCap,97,F,121,6 +1991,BruCap,98,M,10,4 +1991,BruCap,98,F,88,8 +1991,BruCap,99,M,8,3 +1991,BruCap,99,F,47,6 +1991,BruCap,100,M,7,4 +1991,BruCap,100,F,32,3 +1991,BruCap,101,M,4,1 +1991,BruCap,101,F,21,2 +1991,BruCap,102,M,3,0 +1991,BruCap,102,F,14,0 +1991,BruCap,103,M,1,0 +1991,BruCap,103,F,5,1 +1991,BruCap,104,M,0,0 +1991,BruCap,104,F,3,1 +1991,BruCap,105,M,1,0 +1991,BruCap,105,F,3,1 +1991,BruCap,106,M,0,0 +1991,BruCap,106,F,1,3 +1991,BruCap,107,M,0,0 +1991,BruCap,107,F,0,0 +1991,BruCap,108,M,0,0 +1991,BruCap,108,F,0,0 +1991,BruCap,109,M,1,0 +1991,BruCap,109,F,0,0 +1991,BruCap,110,M,0,0 +1991,BruCap,110,F,0,0 +1991,BruCap,111,M,0,0 +1991,BruCap,111,F,0,0 +1991,BruCap,112,M,0,0 +1991,BruCap,112,F,0,0 +1991,BruCap,113,M,0,0 +1991,BruCap,113,F,0,0 +1991,BruCap,114,M,0,0 +1991,BruCap,114,F,0,0 +1991,BruCap,115,M,0,0 +1991,BruCap,115,F,0,0 +1991,BruCap,116,M,0,0 +1991,BruCap,116,F,0,0 +1991,BruCap,117,M,0,0 +1991,BruCap,117,F,0,0 +1991,BruCap,118,M,0,0 +1991,BruCap,118,F,0,0 +1991,BruCap,119,M,0,0 +1991,BruCap,119,F,0,0 +1991,BruCap,120,M,0,0 +1991,BruCap,120,F,0,0 +1991,Fla,0,M,33459,2139 +1991,Fla,0,F,31723,2128 +1991,Fla,1,M,32393,2156 +1991,Fla,1,F,30852,2117 +1991,Fla,2,M,32054,2261 +1991,Fla,2,F,30628,1997 +1991,Fla,3,M,31932,2178 +1991,Fla,3,F,30180,2074 +1991,Fla,4,M,32026,2143 +1991,Fla,4,F,30291,1945 +1991,Fla,5,M,31093,2143 +1991,Fla,5,F,29784,2015 +1991,Fla,6,M,31934,2179 +1991,Fla,6,F,30421,2058 +1991,Fla,7,M,32969,2084 +1991,Fla,7,F,31529,2102 +1991,Fla,8,M,33821,2215 +1991,Fla,8,F,31892,2226 +1991,Fla,9,M,35048,2256 +1991,Fla,9,F,32753,2294 +1991,Fla,10,M,34603,2453 +1991,Fla,10,F,33147,2269 +1991,Fla,11,M,35239,2317 +1991,Fla,11,F,33023,2181 +1991,Fla,12,M,34475,2118 +1991,Fla,12,F,32933,2155 +1991,Fla,13,M,33882,2081 +1991,Fla,13,F,32558,2101 +1991,Fla,14,M,33417,1984 +1991,Fla,14,F,31666,1972 +1991,Fla,15,M,32715,1841 +1991,Fla,15,F,30917,1829 +1991,Fla,16,M,34120,1859 +1991,Fla,16,F,32523,1921 +1991,Fla,17,M,35711,1882 +1991,Fla,17,F,33786,1916 +1991,Fla,18,M,37290,2077 +1991,Fla,18,F,35638,2030 +1991,Fla,19,M,38833,2179 +1991,Fla,19,F,37609,2125 +1991,Fla,20,M,40065,2187 +1991,Fla,20,F,38374,2222 +1991,Fla,21,M,40159,2306 +1991,Fla,21,F,38409,2268 +1991,Fla,22,M,40579,2269 +1991,Fla,22,F,38925,2181 +1991,Fla,23,M,42215,2281 +1991,Fla,23,F,39811,2164 +1991,Fla,24,M,43139,2723 +1991,Fla,24,F,41385,2477 +1991,Fla,25,M,44677,2809 +1991,Fla,25,F,42621,2370 +1991,Fla,26,M,46546,2977 +1991,Fla,26,F,44807,2481 +1991,Fla,27,M,46283,2861 +1991,Fla,27,F,44481,2309 +1991,Fla,28,M,45715,3017 +1991,Fla,28,F,43998,2238 +1991,Fla,29,M,45664,2789 +1991,Fla,29,F,44385,2033 +1991,Fla,30,M,44557,3024 +1991,Fla,30,F,43259,2254 +1991,Fla,31,M,45545,2796 +1991,Fla,31,F,44206,2064 +1991,Fla,32,M,44713,2961 +1991,Fla,32,F,43078,2011 +1991,Fla,33,M,44302,2753 +1991,Fla,33,F,42656,1812 +1991,Fla,34,M,43013,2725 +1991,Fla,34,F,42083,1915 +1991,Fla,35,M,42584,2798 +1991,Fla,35,F,41770,1822 +1991,Fla,36,M,41875,2562 +1991,Fla,36,F,40748,1700 +1991,Fla,37,M,41170,2286 +1991,Fla,37,F,39584,1577 +1991,Fla,38,M,41257,2416 +1991,Fla,38,F,39382,1539 +1991,Fla,39,M,39380,2279 +1991,Fla,39,F,38019,1411 +1991,Fla,40,M,38726,2506 +1991,Fla,40,F,37973,1527 +1991,Fla,41,M,39246,2420 +1991,Fla,41,F,37820,1496 +1991,Fla,42,M,39183,2283 +1991,Fla,42,F,38387,1366 +1991,Fla,43,M,39067,2183 +1991,Fla,43,F,37972,1391 +1991,Fla,44,M,40216,2081 +1991,Fla,44,F,38557,1260 +1991,Fla,45,M,35825,1836 +1991,Fla,45,F,34983,1146 +1991,Fla,46,M,35574,1802 +1991,Fla,46,F,34754,1165 +1991,Fla,47,M,34131,1812 +1991,Fla,47,F,33410,1107 +1991,Fla,48,M,29796,1661 +1991,Fla,48,F,29134,1110 +1991,Fla,49,M,26849,1627 +1991,Fla,49,F,26833,996 +1991,Fla,50,M,29716,1756 +1991,Fla,50,F,29779,1190 +1991,Fla,51,M,32601,1665 +1991,Fla,51,F,33477,988 +1991,Fla,52,M,33747,1626 +1991,Fla,52,F,34184,1061 +1991,Fla,53,M,32794,1488 +1991,Fla,53,F,33040,932 +1991,Fla,54,M,31909,1397 +1991,Fla,54,F,32573,863 +1991,Fla,55,M,31889,1332 +1991,Fla,55,F,32623,840 +1991,Fla,56,M,32066,1325 +1991,Fla,56,F,33363,887 +1991,Fla,57,M,32452,1288 +1991,Fla,57,F,33309,820 +1991,Fla,58,M,33150,1282 +1991,Fla,58,F,34821,782 +1991,Fla,59,M,33167,1121 +1991,Fla,59,F,35014,673 +1991,Fla,60,M,32675,1158 +1991,Fla,60,F,34936,745 +1991,Fla,61,M,30318,1013 +1991,Fla,61,F,32762,676 +1991,Fla,62,M,29589,942 +1991,Fla,62,F,32150,688 +1991,Fla,63,M,28558,897 +1991,Fla,63,F,31125,612 +1991,Fla,64,M,28114,836 +1991,Fla,64,F,31747,640 +1991,Fla,65,M,28150,823 +1991,Fla,65,F,31457,623 +1991,Fla,66,M,27131,810 +1991,Fla,66,F,30932,576 +1991,Fla,67,M,26533,801 +1991,Fla,67,F,30900,613 +1991,Fla,68,M,24733,681 +1991,Fla,68,F,29319,554 +1991,Fla,69,M,23981,681 +1991,Fla,69,F,29235,520 +1991,Fla,70,M,23241,591 +1991,Fla,70,F,28739,491 +1991,Fla,71,M,17467,477 +1991,Fla,71,F,21949,324 +1991,Fla,72,M,11355,365 +1991,Fla,72,F,15199,297 +1991,Fla,73,M,10771,351 +1991,Fla,73,F,14983,277 +1991,Fla,74,M,12126,298 +1991,Fla,74,F,16723,285 +1991,Fla,75,M,14053,308 +1991,Fla,75,F,19693,286 +1991,Fla,76,M,14972,319 +1991,Fla,76,F,22320,293 +1991,Fla,77,M,14027,266 +1991,Fla,77,F,21779,266 +1991,Fla,78,M,12901,237 +1991,Fla,78,F,20739,265 +1991,Fla,79,M,11054,204 +1991,Fla,79,F,18824,223 +1991,Fla,80,M,10212,141 +1991,Fla,80,F,18040,203 +1991,Fla,81,M,9054,172 +1991,Fla,81,F,16589,232 +1991,Fla,82,M,7813,145 +1991,Fla,82,F,15424,179 +1991,Fla,83,M,6973,125 +1991,Fla,83,F,13856,153 +1991,Fla,84,M,5727,102 +1991,Fla,84,F,12334,148 +1991,Fla,85,M,4700,88 +1991,Fla,85,F,10924,116 +1991,Fla,86,M,3963,76 +1991,Fla,86,F,9369,146 +1991,Fla,87,M,3204,49 +1991,Fla,87,F,7775,87 +1991,Fla,88,M,2526,29 +1991,Fla,88,F,6523,67 +1991,Fla,89,M,2013,32 +1991,Fla,89,F,5325,66 +1991,Fla,90,M,1454,30 +1991,Fla,90,F,4049,50 +1991,Fla,91,M,1151,22 +1991,Fla,91,F,3234,37 +1991,Fla,92,M,785,13 +1991,Fla,92,F,2336,39 +1991,Fla,93,M,609,20 +1991,Fla,93,F,1728,21 +1991,Fla,94,M,428,7 +1991,Fla,94,F,1222,17 +1991,Fla,95,M,294,4 +1991,Fla,95,F,864,13 +1991,Fla,96,M,159,2 +1991,Fla,96,F,588,9 +1991,Fla,97,M,120,5 +1991,Fla,97,F,369,5 +1991,Fla,98,M,69,1 +1991,Fla,98,F,217,2 +1991,Fla,99,M,33,2 +1991,Fla,99,F,139,2 +1991,Fla,100,M,25,0 +1991,Fla,100,F,83,0 +1991,Fla,101,M,20,0 +1991,Fla,101,F,56,5 +1991,Fla,102,M,5,0 +1991,Fla,102,F,35,0 +1991,Fla,103,M,5,0 +1991,Fla,103,F,21,1 +1991,Fla,104,M,3,0 +1991,Fla,104,F,10,1 +1991,Fla,105,M,2,0 +1991,Fla,105,F,4,1 +1991,Fla,106,M,0,0 +1991,Fla,106,F,1,0 +1991,Fla,107,M,0,0 +1991,Fla,107,F,2,0 +1991,Fla,108,M,0,0 +1991,Fla,108,F,1,0 +1991,Fla,109,M,0,0 +1991,Fla,109,F,0,0 +1991,Fla,110,M,0,0 +1991,Fla,110,F,0,0 +1991,Fla,111,M,0,0 +1991,Fla,111,F,0,0 +1991,Fla,112,M,0,0 +1991,Fla,112,F,0,0 +1991,Fla,113,M,0,0 +1991,Fla,113,F,0,0 +1991,Fla,114,M,0,0 +1991,Fla,114,F,0,0 +1991,Fla,115,M,0,0 +1991,Fla,115,F,0,0 +1991,Fla,116,M,0,0 +1991,Fla,116,F,0,0 +1991,Fla,117,M,0,0 +1991,Fla,117,F,0,0 +1991,Fla,118,M,0,0 +1991,Fla,118,F,0,0 +1991,Fla,119,M,0,0 +1991,Fla,119,F,0,0 +1991,Fla,120,M,0,0 +1991,Fla,120,F,0,0 +1991,Wal,0,M,19125,2070 +1991,Wal,0,F,18231,1997 +1991,Wal,1,M,19334,2160 +1991,Wal,1,F,18366,2064 +1991,Wal,2,M,19293,2240 +1991,Wal,2,F,18294,2159 +1991,Wal,3,M,18611,2274 +1991,Wal,3,F,17765,2155 +1991,Wal,4,M,18687,2341 +1991,Wal,4,F,17702,2156 +1991,Wal,5,M,18086,2247 +1991,Wal,5,F,17179,2148 +1991,Wal,6,M,17775,2303 +1991,Wal,6,F,17098,2259 +1991,Wal,7,M,17782,2353 +1991,Wal,7,F,16483,2212 +1991,Wal,8,M,17919,2497 +1991,Wal,8,F,17205,2379 +1991,Wal,9,M,18158,2528 +1991,Wal,9,F,17629,2452 +1991,Wal,10,M,18232,2604 +1991,Wal,10,F,17663,2458 +1991,Wal,11,M,18022,2579 +1991,Wal,11,F,17022,2455 +1991,Wal,12,M,17766,2600 +1991,Wal,12,F,17096,2432 +1991,Wal,13,M,18143,2580 +1991,Wal,13,F,17152,2574 +1991,Wal,14,M,18349,2575 +1991,Wal,14,F,17666,2452 +1991,Wal,15,M,18619,2587 +1991,Wal,15,F,17843,2457 +1991,Wal,16,M,19474,2747 +1991,Wal,16,F,18387,2554 +1991,Wal,17,M,20416,2825 +1991,Wal,17,F,19365,2749 +1991,Wal,18,M,20906,3140 +1991,Wal,18,F,19983,2933 +1991,Wal,19,M,21345,3128 +1991,Wal,19,F,20498,2967 +1991,Wal,20,M,20876,3145 +1991,Wal,20,F,19817,3024 +1991,Wal,21,M,20695,3200 +1991,Wal,21,F,19898,3046 +1991,Wal,22,M,20097,3257 +1991,Wal,22,F,19566,3035 +1991,Wal,23,M,20380,3224 +1991,Wal,23,F,19638,2931 +1991,Wal,24,M,20516,3859 +1991,Wal,24,F,19903,3362 +1991,Wal,25,M,21096,4021 +1991,Wal,25,F,20487,3314 +1991,Wal,26,M,21773,4025 +1991,Wal,26,F,21316,3319 +1991,Wal,27,M,21418,4017 +1991,Wal,27,F,21417,3170 +1991,Wal,28,M,20718,3971 +1991,Wal,28,F,20941,3051 +1991,Wal,29,M,21446,3952 +1991,Wal,29,F,21850,3047 +1991,Wal,30,M,21295,4271 +1991,Wal,30,F,21423,3040 +1991,Wal,31,M,21684,4075 +1991,Wal,31,F,22450,2981 +1991,Wal,32,M,21389,4137 +1991,Wal,32,F,22017,2951 +1991,Wal,33,M,21279,4095 +1991,Wal,33,F,21764,2845 +1991,Wal,34,M,20842,4210 +1991,Wal,34,F,21609,2880 +1991,Wal,35,M,20771,4020 +1991,Wal,35,F,21747,2844 +1991,Wal,36,M,20780,3965 +1991,Wal,36,F,21595,2694 +1991,Wal,37,M,20976,3695 +1991,Wal,37,F,21453,2456 +1991,Wal,38,M,20915,3608 +1991,Wal,38,F,21248,2443 +1991,Wal,39,M,20288,3329 +1991,Wal,39,F,21038,2399 +1991,Wal,40,M,21203,3468 +1991,Wal,40,F,21232,2495 +1991,Wal,41,M,21186,3271 +1991,Wal,41,F,21338,2309 +1991,Wal,42,M,21835,3261 +1991,Wal,42,F,22087,2403 +1991,Wal,43,M,21931,3175 +1991,Wal,43,F,21946,2180 +1991,Wal,44,M,21407,3012 +1991,Wal,44,F,21909,2071 +1991,Wal,45,M,15940,2434 +1991,Wal,45,F,16713,1733 +1991,Wal,46,M,16036,2374 +1991,Wal,46,F,16482,1809 +1991,Wal,47,M,15053,2148 +1991,Wal,47,F,15575,1648 +1991,Wal,48,M,13025,2083 +1991,Wal,48,F,13610,1621 +1991,Wal,49,M,12203,1998 +1991,Wal,49,F,12929,1554 +1991,Wal,50,M,13625,2371 +1991,Wal,50,F,14465,1823 +1991,Wal,51,M,14886,2189 +1991,Wal,51,F,16044,1816 +1991,Wal,52,M,15205,2060 +1991,Wal,52,F,16480,1834 +1991,Wal,53,M,14548,2089 +1991,Wal,53,F,15456,1677 +1991,Wal,54,M,14236,2028 +1991,Wal,54,F,15538,1720 +1991,Wal,55,M,14210,2037 +1991,Wal,55,F,15635,1742 +1991,Wal,56,M,14961,1979 +1991,Wal,56,F,16295,1753 +1991,Wal,57,M,15141,1977 +1991,Wal,57,F,16458,1780 +1991,Wal,58,M,16016,2117 +1991,Wal,58,F,17984,1748 +1991,Wal,59,M,16739,1903 +1991,Wal,59,F,18610,1719 +1991,Wal,60,M,16640,2062 +1991,Wal,60,F,18831,1792 +1991,Wal,61,M,15752,2002 +1991,Wal,61,F,18091,1723 +1991,Wal,62,M,15548,2021 +1991,Wal,62,F,18384,1632 +1991,Wal,63,M,15384,2049 +1991,Wal,63,F,18037,1703 +1991,Wal,64,M,15142,2088 +1991,Wal,64,F,18298,1686 +1991,Wal,65,M,15190,1946 +1991,Wal,65,F,18845,1653 +1991,Wal,66,M,14730,1911 +1991,Wal,66,F,18537,1587 +1991,Wal,67,M,14053,1817 +1991,Wal,67,F,18137,1484 +1991,Wal,68,M,13952,1613 +1991,Wal,68,F,18203,1417 +1991,Wal,69,M,13785,1422 +1991,Wal,69,F,18654,1334 +1991,Wal,70,M,13050,1258 +1991,Wal,70,F,18203,1228 +1991,Wal,71,M,9253,759 +1991,Wal,71,F,13199,844 +1991,Wal,72,M,6280,595 +1991,Wal,72,F,9259,560 +1991,Wal,73,M,5671,522 +1991,Wal,73,F,8975,513 +1991,Wal,74,M,6206,507 +1991,Wal,74,F,9317,615 +1991,Wal,75,M,6980,559 +1991,Wal,75,F,11243,678 +1991,Wal,76,M,7750,559 +1991,Wal,76,F,13100,733 +1991,Wal,77,M,7210,549 +1991,Wal,77,F,12437,692 +1991,Wal,78,M,6380,479 +1991,Wal,78,F,12209,646 +1991,Wal,79,M,5363,393 +1991,Wal,79,F,10947,590 +1991,Wal,80,M,5034,296 +1991,Wal,80,F,10571,526 +1991,Wal,81,M,4284,224 +1991,Wal,81,F,9818,498 +1991,Wal,82,M,3775,227 +1991,Wal,82,F,9201,437 +1991,Wal,83,M,3257,174 +1991,Wal,83,F,8657,372 +1991,Wal,84,M,2788,157 +1991,Wal,84,F,7476,316 +1991,Wal,85,M,2242,123 +1991,Wal,85,F,6246,297 +1991,Wal,86,M,1874,110 +1991,Wal,86,F,5649,261 +1991,Wal,87,M,1517,86 +1991,Wal,87,F,4705,170 +1991,Wal,88,M,1179,68 +1991,Wal,88,F,4028,182 +1991,Wal,89,M,932,45 +1991,Wal,89,F,3501,169 +1991,Wal,90,M,684,45 +1991,Wal,90,F,2580,124 +1991,Wal,91,M,523,23 +1991,Wal,91,F,1882,71 +1991,Wal,92,M,346,20 +1991,Wal,92,F,1437,65 +1991,Wal,93,M,224,19 +1991,Wal,93,F,1052,58 +1991,Wal,94,M,167,15 +1991,Wal,94,F,760,27 +1991,Wal,95,M,94,0 +1991,Wal,95,F,569,15 +1991,Wal,96,M,73,3 +1991,Wal,96,F,335,21 +1991,Wal,97,M,49,2 +1991,Wal,97,F,209,4 +1991,Wal,98,M,23,1 +1991,Wal,98,F,149,10 +1991,Wal,99,M,12,1 +1991,Wal,99,F,69,5 +1991,Wal,100,M,11,0 +1991,Wal,100,F,49,3 +1991,Wal,101,M,8,2 +1991,Wal,101,F,31,2 +1991,Wal,102,M,1,0 +1991,Wal,102,F,25,0 +1991,Wal,103,M,2,0 +1991,Wal,103,F,11,0 +1991,Wal,104,M,1,0 +1991,Wal,104,F,3,1 +1991,Wal,105,M,0,0 +1991,Wal,105,F,1,0 +1991,Wal,106,M,0,0 +1991,Wal,106,F,1,0 +1991,Wal,107,M,0,0 +1991,Wal,107,F,0,0 +1991,Wal,108,M,0,0 +1991,Wal,108,F,0,0 +1991,Wal,109,M,0,0 +1991,Wal,109,F,0,0 +1991,Wal,110,M,0,0 +1991,Wal,110,F,0,0 +1991,Wal,111,M,0,0 +1991,Wal,111,F,0,0 +1991,Wal,112,M,0,0 +1991,Wal,112,F,0,0 +1991,Wal,113,M,0,0 +1991,Wal,113,F,0,0 +1991,Wal,114,M,0,0 +1991,Wal,114,F,0,0 +1991,Wal,115,M,0,0 +1991,Wal,115,F,0,0 +1991,Wal,116,M,0,0 +1991,Wal,116,F,0,0 +1991,Wal,117,M,0,0 +1991,Wal,117,F,0,0 +1991,Wal,118,M,0,0 +1991,Wal,118,F,0,0 +1991,Wal,119,M,0,0 +1991,Wal,119,F,0,0 +1991,Wal,120,M,0,0 +1991,Wal,120,F,0,0 +1992,BruCap,0,M,4202,2269 +1992,BruCap,0,F,4014,2192 +1992,BruCap,1,M,3996,2427 +1992,BruCap,1,F,3829,2261 +1992,BruCap,2,M,3677,2344 +1992,BruCap,2,F,3590,2277 +1992,BruCap,3,M,3646,2337 +1992,BruCap,3,F,3369,2300 +1992,BruCap,4,M,3446,2280 +1992,BruCap,4,F,3260,2217 +1992,BruCap,5,M,3414,2250 +1992,BruCap,5,F,3140,2152 +1992,BruCap,6,M,3158,2253 +1992,BruCap,6,F,2953,2067 +1992,BruCap,7,M,3237,2244 +1992,BruCap,7,F,3051,2176 +1992,BruCap,8,M,3091,2244 +1992,BruCap,8,F,3044,2059 +1992,BruCap,9,M,3121,2320 +1992,BruCap,9,F,2957,2258 +1992,BruCap,10,M,3222,2447 +1992,BruCap,10,F,3058,2289 +1992,BruCap,11,M,3183,2352 +1992,BruCap,11,F,3082,2317 +1992,BruCap,12,M,3099,2392 +1992,BruCap,12,F,2943,2224 +1992,BruCap,13,M,2967,2283 +1992,BruCap,13,F,2998,2273 +1992,BruCap,14,M,2941,2258 +1992,BruCap,14,F,2919,2190 +1992,BruCap,15,M,2933,2210 +1992,BruCap,15,F,2897,2131 +1992,BruCap,16,M,3043,2133 +1992,BruCap,16,F,2957,1969 +1992,BruCap,17,M,3002,2222 +1992,BruCap,17,F,2955,2042 +1992,BruCap,18,M,3295,2224 +1992,BruCap,18,F,3279,2200 +1992,BruCap,19,M,3520,2372 +1992,BruCap,19,F,3499,2371 +1992,BruCap,20,M,3825,2401 +1992,BruCap,20,F,3795,2490 +1992,BruCap,21,M,3968,2611 +1992,BruCap,21,F,4082,2471 +1992,BruCap,22,M,4039,2655 +1992,BruCap,22,F,4204,2600 +1992,BruCap,23,M,4374,2701 +1992,BruCap,23,F,4513,2600 +1992,BruCap,24,M,4648,2685 +1992,BruCap,24,F,4986,2647 +1992,BruCap,25,M,4826,3016 +1992,BruCap,25,F,5229,2898 +1992,BruCap,26,M,5140,3141 +1992,BruCap,26,F,5376,2983 +1992,BruCap,27,M,5317,3177 +1992,BruCap,27,F,5559,3016 +1992,BruCap,28,M,5267,3083 +1992,BruCap,28,F,5327,2847 +1992,BruCap,29,M,4951,3173 +1992,BruCap,29,F,5084,2878 +1992,BruCap,30,M,4828,3095 +1992,BruCap,30,F,5190,2846 +1992,BruCap,31,M,4817,3099 +1992,BruCap,31,F,5113,2883 +1992,BruCap,32,M,4887,2861 +1992,BruCap,32,F,4912,2666 +1992,BruCap,33,M,4561,2868 +1992,BruCap,33,F,4954,2558 +1992,BruCap,34,M,4575,2638 +1992,BruCap,34,F,4786,2390 +1992,BruCap,35,M,4350,2712 +1992,BruCap,35,F,4741,2409 +1992,BruCap,36,M,4353,2607 +1992,BruCap,36,F,4636,2292 +1992,BruCap,37,M,4373,2394 +1992,BruCap,37,F,4563,2172 +1992,BruCap,38,M,4355,2365 +1992,BruCap,38,F,4694,2067 +1992,BruCap,39,M,4252,2381 +1992,BruCap,39,F,4669,2072 +1992,BruCap,40,M,4174,2076 +1992,BruCap,40,F,4592,1788 +1992,BruCap,41,M,4082,2187 +1992,BruCap,41,F,4648,1944 +1992,BruCap,42,M,4168,1968 +1992,BruCap,42,F,4667,1640 +1992,BruCap,43,M,4249,1963 +1992,BruCap,43,F,4724,1672 +1992,BruCap,44,M,4316,1891 +1992,BruCap,44,F,4930,1551 +1992,BruCap,45,M,4459,1786 +1992,BruCap,45,F,4884,1508 +1992,BruCap,46,M,3725,1577 +1992,BruCap,46,F,4226,1368 +1992,BruCap,47,M,3925,1595 +1992,BruCap,47,F,4482,1365 +1992,BruCap,48,M,3806,1499 +1992,BruCap,48,F,4253,1292 +1992,BruCap,49,M,3237,1528 +1992,BruCap,49,F,3692,1238 +1992,BruCap,50,M,2894,1319 +1992,BruCap,50,F,3373,1124 +1992,BruCap,51,M,3261,1630 +1992,BruCap,51,F,3665,1416 +1992,BruCap,52,M,3477,1457 +1992,BruCap,52,F,4088,1200 +1992,BruCap,53,M,3470,1504 +1992,BruCap,53,F,4033,1126 +1992,BruCap,54,M,3462,1355 +1992,BruCap,54,F,4044,1096 +1992,BruCap,55,M,3385,1372 +1992,BruCap,55,F,3982,1124 +1992,BruCap,56,M,3405,1247 +1992,BruCap,56,F,4086,1117 +1992,BruCap,57,M,3593,1237 +1992,BruCap,57,F,4173,990 +1992,BruCap,58,M,3600,1166 +1992,BruCap,58,F,4344,878 +1992,BruCap,59,M,3846,1197 +1992,BruCap,59,F,4591,918 +1992,BruCap,60,M,3864,997 +1992,BruCap,60,F,4727,836 +1992,BruCap,61,M,3837,1080 +1992,BruCap,61,F,5085,887 +1992,BruCap,62,M,3743,956 +1992,BruCap,62,F,4857,691 +1992,BruCap,63,M,3680,883 +1992,BruCap,63,F,4785,716 +1992,BruCap,64,M,3633,798 +1992,BruCap,64,F,4829,605 +1992,BruCap,65,M,3706,712 +1992,BruCap,65,F,5008,593 +1992,BruCap,66,M,3733,646 +1992,BruCap,66,F,5163,553 +1992,BruCap,67,M,3860,505 +1992,BruCap,67,F,5313,489 +1992,BruCap,68,M,3686,549 +1992,BruCap,68,F,5525,499 +1992,BruCap,69,M,3696,456 +1992,BruCap,69,F,5498,441 +1992,BruCap,70,M,3869,434 +1992,BruCap,70,F,5629,382 +1992,BruCap,71,M,3739,394 +1992,BruCap,71,F,5766,451 +1992,BruCap,72,M,2752,236 +1992,BruCap,72,F,4122,294 +1992,BruCap,73,M,1712,200 +1992,BruCap,73,F,3056,239 +1992,BruCap,74,M,1676,197 +1992,BruCap,74,F,2985,234 +1992,BruCap,75,M,1775,152 +1992,BruCap,75,F,3173,207 +1992,BruCap,76,M,2086,161 +1992,BruCap,76,F,3845,213 +1992,BruCap,77,M,2320,182 +1992,BruCap,77,F,4554,221 +1992,BruCap,78,M,2171,164 +1992,BruCap,78,F,4384,218 +1992,BruCap,79,M,1976,132 +1992,BruCap,79,F,4268,236 +1992,BruCap,80,M,1754,122 +1992,BruCap,80,F,3863,191 +1992,BruCap,81,M,1581,110 +1992,BruCap,81,F,3783,202 +1992,BruCap,82,M,1362,82 +1992,BruCap,82,F,3318,172 +1992,BruCap,83,M,1196,94 +1992,BruCap,83,F,3291,135 +1992,BruCap,84,M,1018,85 +1992,BruCap,84,F,2866,144 +1992,BruCap,85,M,875,63 +1992,BruCap,85,F,2590,132 +1992,BruCap,86,M,738,48 +1992,BruCap,86,F,2310,129 +1992,BruCap,87,M,588,57 +1992,BruCap,87,F,1956,102 +1992,BruCap,88,M,494,22 +1992,BruCap,88,F,1673,85 +1992,BruCap,89,M,379,29 +1992,BruCap,89,F,1448,55 +1992,BruCap,90,M,308,29 +1992,BruCap,90,F,1168,60 +1992,BruCap,91,M,206,22 +1992,BruCap,91,F,891,65 +1992,BruCap,92,M,153,15 +1992,BruCap,92,F,712,32 +1992,BruCap,93,M,120,9 +1992,BruCap,93,F,499,39 +1992,BruCap,94,M,85,8 +1992,BruCap,94,F,366,23 +1992,BruCap,95,M,55,4 +1992,BruCap,95,F,257,17 +1992,BruCap,96,M,30,4 +1992,BruCap,96,F,195,12 +1992,BruCap,97,M,27,0 +1992,BruCap,97,F,145,7 +1992,BruCap,98,M,20,3 +1992,BruCap,98,F,83,4 +1992,BruCap,99,M,6,3 +1992,BruCap,99,F,60,6 +1992,BruCap,100,M,4,2 +1992,BruCap,100,F,36,3 +1992,BruCap,101,M,2,2 +1992,BruCap,101,F,16,2 +1992,BruCap,102,M,1,1 +1992,BruCap,102,F,10,2 +1992,BruCap,103,M,1,0 +1992,BruCap,103,F,9,0 +1992,BruCap,104,M,0,0 +1992,BruCap,104,F,3,0 +1992,BruCap,105,M,0,0 +1992,BruCap,105,F,2,1 +1992,BruCap,106,M,0,0 +1992,BruCap,106,F,1,1 +1992,BruCap,107,M,0,0 +1992,BruCap,107,F,0,2 +1992,BruCap,108,M,0,0 +1992,BruCap,108,F,0,0 +1992,BruCap,109,M,0,0 +1992,BruCap,109,F,0,0 +1992,BruCap,110,M,1,0 +1992,BruCap,110,F,0,0 +1992,BruCap,111,M,0,0 +1992,BruCap,111,F,0,0 +1992,BruCap,112,M,0,0 +1992,BruCap,112,F,0,0 +1992,BruCap,113,M,0,0 +1992,BruCap,113,F,0,0 +1992,BruCap,114,M,0,0 +1992,BruCap,114,F,0,0 +1992,BruCap,115,M,0,0 +1992,BruCap,115,F,0,0 +1992,BruCap,116,M,0,0 +1992,BruCap,116,F,0,0 +1992,BruCap,117,M,0,0 +1992,BruCap,117,F,0,0 +1992,BruCap,118,M,0,0 +1992,BruCap,118,F,0,0 +1992,BruCap,119,M,0,0 +1992,BruCap,119,F,0,0 +1992,BruCap,120,M,0,0 +1992,BruCap,120,F,0,0 +1992,Fla,0,M,33838,2343 +1992,Fla,0,F,32110,2175 +1992,Fla,1,M,33565,2245 +1992,Fla,1,F,31893,2211 +1992,Fla,2,M,32577,2228 +1992,Fla,2,F,31013,2163 +1992,Fla,3,M,32148,2305 +1992,Fla,3,F,30750,2070 +1992,Fla,4,M,31991,2234 +1992,Fla,4,F,30245,2110 +1992,Fla,5,M,32083,2219 +1992,Fla,5,F,30357,1983 +1992,Fla,6,M,31168,2201 +1992,Fla,6,F,29847,2047 +1992,Fla,7,M,31989,2204 +1992,Fla,7,F,30456,2107 +1992,Fla,8,M,33002,2107 +1992,Fla,8,F,31622,2150 +1992,Fla,9,M,33869,2231 +1992,Fla,9,F,31945,2249 +1992,Fla,10,M,35118,2293 +1992,Fla,10,F,32808,2332 +1992,Fla,11,M,34667,2465 +1992,Fla,11,F,33205,2282 +1992,Fla,12,M,35285,2353 +1992,Fla,12,F,33074,2245 +1992,Fla,13,M,34513,2156 +1992,Fla,13,F,32978,2178 +1992,Fla,14,M,33906,2143 +1992,Fla,14,F,32607,2131 +1992,Fla,15,M,33440,2026 +1992,Fla,15,F,31692,2000 +1992,Fla,16,M,32731,1905 +1992,Fla,16,F,30932,1894 +1992,Fla,17,M,34119,1921 +1992,Fla,17,F,32520,1990 +1992,Fla,18,M,35653,2035 +1992,Fla,18,F,33790,2085 +1992,Fla,19,M,37244,2176 +1992,Fla,19,F,35649,2106 +1992,Fla,20,M,38825,2322 +1992,Fla,20,F,37666,2225 +1992,Fla,21,M,39989,2344 +1992,Fla,21,F,38336,2365 +1992,Fla,22,M,40052,2498 +1992,Fla,22,F,38354,2398 +1992,Fla,23,M,40453,2483 +1992,Fla,23,F,38855,2333 +1992,Fla,24,M,42061,2612 +1992,Fla,24,F,39688,2326 +1992,Fla,25,M,42926,2948 +1992,Fla,25,F,41324,2607 +1992,Fla,26,M,44552,3103 +1992,Fla,26,F,42540,2468 +1992,Fla,27,M,46381,3223 +1992,Fla,27,F,44785,2597 +1992,Fla,28,M,46230,3052 +1992,Fla,28,F,44492,2467 +1992,Fla,29,M,45672,3152 +1992,Fla,29,F,44012,2298 +1992,Fla,30,M,45630,2933 +1992,Fla,30,F,44397,2124 +1992,Fla,31,M,44574,3203 +1992,Fla,31,F,43321,2356 +1992,Fla,32,M,45528,2886 +1992,Fla,32,F,44267,2128 +1992,Fla,33,M,44714,3034 +1992,Fla,33,F,43108,2063 +1992,Fla,34,M,44305,2792 +1992,Fla,34,F,42684,1861 +1992,Fla,35,M,43017,2794 +1992,Fla,35,F,42107,1977 +1992,Fla,36,M,42542,2816 +1992,Fla,36,F,41800,1886 +1992,Fla,37,M,41882,2619 +1992,Fla,37,F,40810,1733 +1992,Fla,38,M,41158,2341 +1992,Fla,38,F,39599,1635 +1992,Fla,39,M,41210,2425 +1992,Fla,39,F,39420,1589 +1992,Fla,40,M,39321,2300 +1992,Fla,40,F,38009,1438 +1992,Fla,41,M,38677,2515 +1992,Fla,41,F,37933,1555 +1992,Fla,42,M,39152,2437 +1992,Fla,42,F,37780,1528 +1992,Fla,43,M,39126,2311 +1992,Fla,43,F,38350,1399 +1992,Fla,44,M,38970,2198 +1992,Fla,44,F,37966,1423 +1992,Fla,45,M,40116,2096 +1992,Fla,45,F,38538,1295 +1992,Fla,46,M,35704,1832 +1992,Fla,46,F,34932,1175 +1992,Fla,47,M,35443,1811 +1992,Fla,47,F,34718,1208 +1992,Fla,48,M,34024,1822 +1992,Fla,48,F,33346,1131 +1992,Fla,49,M,29690,1678 +1992,Fla,49,F,29074,1147 +1992,Fla,50,M,26745,1619 +1992,Fla,50,F,26789,1022 +1992,Fla,51,M,29583,1765 +1992,Fla,51,F,29738,1211 +1992,Fla,52,M,32428,1682 +1992,Fla,52,F,33389,1007 +1992,Fla,53,M,33593,1610 +1992,Fla,53,F,34099,1054 +1992,Fla,54,M,32640,1489 +1992,Fla,54,F,32947,954 +1992,Fla,55,M,31717,1409 +1992,Fla,55,F,32469,883 +1992,Fla,56,M,31675,1340 +1992,Fla,56,F,32528,853 +1992,Fla,57,M,31797,1327 +1992,Fla,57,F,33251,898 +1992,Fla,58,M,32145,1284 +1992,Fla,58,F,33187,840 +1992,Fla,59,M,32812,1266 +1992,Fla,59,F,34696,786 +1992,Fla,60,M,32828,1122 +1992,Fla,60,F,34822,657 +1992,Fla,61,M,32265,1152 +1992,Fla,61,F,34743,752 +1992,Fla,62,M,29912,992 +1992,Fla,62,F,32573,676 +1992,Fla,63,M,29142,926 +1992,Fla,63,F,31956,682 +1992,Fla,64,M,28078,891 +1992,Fla,64,F,30873,616 +1992,Fla,65,M,27552,824 +1992,Fla,65,F,31482,637 +1992,Fla,66,M,27523,816 +1992,Fla,66,F,31148,618 +1992,Fla,67,M,26516,798 +1992,Fla,67,F,30608,569 +1992,Fla,68,M,25813,770 +1992,Fla,68,F,30518,610 +1992,Fla,69,M,24015,668 +1992,Fla,69,F,28946,540 +1992,Fla,70,M,23236,658 +1992,Fla,70,F,28769,511 +1992,Fla,71,M,22396,576 +1992,Fla,71,F,28266,481 +1992,Fla,72,M,16773,453 +1992,Fla,72,F,21498,322 +1992,Fla,73,M,10830,352 +1992,Fla,73,F,14834,294 +1992,Fla,74,M,10250,337 +1992,Fla,74,F,14581,266 +1992,Fla,75,M,11445,279 +1992,Fla,75,F,16257,276 +1992,Fla,76,M,13195,287 +1992,Fla,76,F,19080,276 +1992,Fla,77,M,14018,292 +1992,Fla,77,F,21523,282 +1992,Fla,78,M,12985,252 +1992,Fla,78,F,20931,260 +1992,Fla,79,M,11831,228 +1992,Fla,79,F,19760,251 +1992,Fla,80,M,10127,192 +1992,Fla,80,F,17801,215 +1992,Fla,81,M,9248,134 +1992,Fla,81,F,16935,189 +1992,Fla,82,M,8056,151 +1992,Fla,82,F,15421,220 +1992,Fla,83,M,6865,117 +1992,Fla,83,F,14288,165 +1992,Fla,84,M,6097,102 +1992,Fla,84,F,12665,144 +1992,Fla,85,M,4931,81 +1992,Fla,85,F,11114,132 +1992,Fla,86,M,3974,75 +1992,Fla,86,F,9748,102 +1992,Fla,87,M,3301,63 +1992,Fla,87,F,8316,137 +1992,Fla,88,M,2631,43 +1992,Fla,88,F,6733,77 +1992,Fla,89,M,2039,23 +1992,Fla,89,F,5543,56 +1992,Fla,90,M,1621,24 +1992,Fla,90,F,4502,60 +1992,Fla,91,M,1125,21 +1992,Fla,91,F,3316,39 +1992,Fla,92,M,866,17 +1992,Fla,92,F,2578,35 +1992,Fla,93,M,620,9 +1992,Fla,93,F,1834,29 +1992,Fla,94,M,444,15 +1992,Fla,94,F,1323,19 +1992,Fla,95,M,313,5 +1992,Fla,95,F,906,14 +1992,Fla,96,M,200,3 +1992,Fla,96,F,627,10 +1992,Fla,97,M,106,1 +1992,Fla,97,F,411,6 +1992,Fla,98,M,79,3 +1992,Fla,98,F,255,2 +1992,Fla,99,M,40,1 +1992,Fla,99,F,152,1 +1992,Fla,100,M,24,2 +1992,Fla,100,F,90,2 +1992,Fla,101,M,16,0 +1992,Fla,101,F,47,0 +1992,Fla,102,M,11,0 +1992,Fla,102,F,29,1 +1992,Fla,103,M,2,0 +1992,Fla,103,F,25,0 +1992,Fla,104,M,2,0 +1992,Fla,104,F,12,1 +1992,Fla,105,M,3,0 +1992,Fla,105,F,6,0 +1992,Fla,106,M,1,0 +1992,Fla,106,F,1,1 +1992,Fla,107,M,0,0 +1992,Fla,107,F,1,1 +1992,Fla,108,M,0,0 +1992,Fla,108,F,1,0 +1992,Fla,109,M,0,0 +1992,Fla,109,F,1,0 +1992,Fla,110,M,0,0 +1992,Fla,110,F,0,0 +1992,Fla,111,M,0,0 +1992,Fla,111,F,0,0 +1992,Fla,112,M,0,0 +1992,Fla,112,F,0,0 +1992,Fla,113,M,0,0 +1992,Fla,113,F,0,0 +1992,Fla,114,M,0,0 +1992,Fla,114,F,0,0 +1992,Fla,115,M,0,0 +1992,Fla,115,F,0,0 +1992,Fla,116,M,0,0 +1992,Fla,116,F,0,0 +1992,Fla,117,M,0,0 +1992,Fla,117,F,0,0 +1992,Fla,118,M,0,0 +1992,Fla,118,F,0,0 +1992,Fla,119,M,0,0 +1992,Fla,119,F,0,0 +1992,Fla,120,M,0,0 +1992,Fla,120,F,0,0 +1992,Wal,0,M,19616,2021 +1992,Wal,0,F,18771,1994 +1992,Wal,1,M,19406,2139 +1992,Wal,1,F,18528,2081 +1992,Wal,2,M,19559,2213 +1992,Wal,2,F,18608,2084 +1992,Wal,3,M,19520,2305 +1992,Wal,3,F,18478,2210 +1992,Wal,4,M,18791,2330 +1992,Wal,4,F,17915,2192 +1992,Wal,5,M,18817,2388 +1992,Wal,5,F,17834,2184 +1992,Wal,6,M,18201,2286 +1992,Wal,6,F,17311,2144 +1992,Wal,7,M,17867,2351 +1992,Wal,7,F,17219,2260 +1992,Wal,8,M,17893,2349 +1992,Wal,8,F,16553,2223 +1992,Wal,9,M,18029,2515 +1992,Wal,9,F,17287,2407 +1992,Wal,10,M,18254,2520 +1992,Wal,10,F,17735,2445 +1992,Wal,11,M,18296,2614 +1992,Wal,11,F,17753,2450 +1992,Wal,12,M,18111,2622 +1992,Wal,12,F,17125,2449 +1992,Wal,13,M,17834,2636 +1992,Wal,13,F,17172,2429 +1992,Wal,14,M,18209,2592 +1992,Wal,14,F,17201,2588 +1992,Wal,15,M,18392,2594 +1992,Wal,15,F,17699,2462 +1992,Wal,16,M,18646,2620 +1992,Wal,16,F,17909,2478 +1992,Wal,17,M,19512,2792 +1992,Wal,17,F,18440,2633 +1992,Wal,18,M,20379,2986 +1992,Wal,18,F,19391,2866 +1992,Wal,19,M,20926,3145 +1992,Wal,19,F,20031,2953 +1992,Wal,20,M,21295,3211 +1992,Wal,20,F,20492,2990 +1992,Wal,21,M,20780,3285 +1992,Wal,21,F,19823,3030 +1992,Wal,22,M,20598,3317 +1992,Wal,22,F,19845,3059 +1992,Wal,23,M,19932,3439 +1992,Wal,23,F,19457,3118 +1992,Wal,24,M,20194,3416 +1992,Wal,24,F,19461,3058 +1992,Wal,25,M,20346,4062 +1992,Wal,25,F,19799,3404 +1992,Wal,26,M,20996,4162 +1992,Wal,26,F,20487,3385 +1992,Wal,27,M,21675,4130 +1992,Wal,27,F,21402,3364 +1992,Wal,28,M,21418,4143 +1992,Wal,28,F,21499,3199 +1992,Wal,29,M,20767,4096 +1992,Wal,29,F,21080,3090 +1992,Wal,30,M,21498,3974 +1992,Wal,30,F,21953,3111 +1992,Wal,31,M,21357,4374 +1992,Wal,31,F,21519,3102 +1992,Wal,32,M,21731,4133 +1992,Wal,32,F,22600,3003 +1992,Wal,33,M,21455,4170 +1992,Wal,33,F,22115,2989 +1992,Wal,34,M,21316,4120 +1992,Wal,34,F,21860,2827 +1992,Wal,35,M,20917,4227 +1992,Wal,35,F,21686,2900 +1992,Wal,36,M,20842,4012 +1992,Wal,36,F,21807,2857 +1992,Wal,37,M,20785,3951 +1992,Wal,37,F,21658,2695 +1992,Wal,38,M,20960,3695 +1992,Wal,38,F,21473,2517 +1992,Wal,39,M,20912,3583 +1992,Wal,39,F,21260,2468 +1992,Wal,40,M,20264,3339 +1992,Wal,40,F,21060,2368 +1992,Wal,41,M,21182,3494 +1992,Wal,41,F,21250,2497 +1992,Wal,42,M,21153,3271 +1992,Wal,42,F,21341,2305 +1992,Wal,43,M,21788,3243 +1992,Wal,43,F,22112,2390 +1992,Wal,44,M,21920,3196 +1992,Wal,44,F,21944,2194 +1992,Wal,45,M,21349,3010 +1992,Wal,45,F,21886,2047 +1992,Wal,46,M,15886,2398 +1992,Wal,46,F,16725,1731 +1992,Wal,47,M,15994,2374 +1992,Wal,47,F,16455,1809 +1992,Wal,48,M,14996,2134 +1992,Wal,48,F,15562,1654 +1992,Wal,49,M,12995,2064 +1992,Wal,49,F,13587,1619 +1992,Wal,50,M,12144,1985 +1992,Wal,50,F,12920,1543 +1992,Wal,51,M,13590,2359 +1992,Wal,51,F,14442,1818 +1992,Wal,52,M,14828,2169 +1992,Wal,52,F,16007,1808 +1992,Wal,53,M,15094,2039 +1992,Wal,53,F,16442,1809 +1992,Wal,54,M,14467,2066 +1992,Wal,54,F,15416,1680 +1992,Wal,55,M,14124,2016 +1992,Wal,55,F,15510,1716 +1992,Wal,56,M,14094,2013 +1992,Wal,56,F,15562,1731 +1992,Wal,57,M,14830,1945 +1992,Wal,57,F,16240,1757 +1992,Wal,58,M,14983,1936 +1992,Wal,58,F,16404,1760 +1992,Wal,59,M,15853,2074 +1992,Wal,59,F,17911,1723 +1992,Wal,60,M,16497,1864 +1992,Wal,60,F,18498,1703 +1992,Wal,61,M,16336,2035 +1992,Wal,61,F,18691,1747 +1992,Wal,62,M,15489,1958 +1992,Wal,62,F,17964,1697 +1992,Wal,63,M,15244,1976 +1992,Wal,63,F,18269,1611 +1992,Wal,64,M,15077,1992 +1992,Wal,64,F,17882,1683 +1992,Wal,65,M,14811,1993 +1992,Wal,65,F,18093,1663 +1992,Wal,66,M,14806,1857 +1992,Wal,66,F,18651,1640 +1992,Wal,67,M,14303,1826 +1992,Wal,67,F,18333,1554 +1992,Wal,68,M,13609,1755 +1992,Wal,68,F,17904,1462 +1992,Wal,69,M,13440,1534 +1992,Wal,69,F,17925,1379 +1992,Wal,70,M,13233,1347 +1992,Wal,70,F,18341,1318 +1992,Wal,71,M,12520,1203 +1992,Wal,71,F,17874,1195 +1992,Wal,72,M,8790,719 +1992,Wal,72,F,12918,826 +1992,Wal,73,M,5976,554 +1992,Wal,73,F,9030,556 +1992,Wal,74,M,5349,490 +1992,Wal,74,F,8694,499 +1992,Wal,75,M,5844,473 +1992,Wal,75,F,9046,589 +1992,Wal,76,M,6521,509 +1992,Wal,76,F,10858,661 +1992,Wal,77,M,7197,526 +1992,Wal,77,F,12630,704 +1992,Wal,78,M,6625,508 +1992,Wal,78,F,11899,659 +1992,Wal,79,M,5798,436 +1992,Wal,79,F,11577,613 +1992,Wal,80,M,4866,348 +1992,Wal,80,F,10308,550 +1992,Wal,81,M,4492,258 +1992,Wal,81,F,9941,481 +1992,Wal,82,M,3768,193 +1992,Wal,82,F,9105,463 +1992,Wal,83,M,3246,202 +1992,Wal,83,F,8477,402 +1992,Wal,84,M,2802,147 +1992,Wal,84,F,7885,340 +1992,Wal,85,M,2357,133 +1992,Wal,85,F,6710,290 +1992,Wal,86,M,1879,104 +1992,Wal,86,F,5518,267 +1992,Wal,87,M,1540,82 +1992,Wal,87,F,4982,245 +1992,Wal,88,M,1195,72 +1992,Wal,88,F,4063,154 +1992,Wal,89,M,933,49 +1992,Wal,89,F,3348,159 +1992,Wal,90,M,735,35 +1992,Wal,90,F,2897,139 +1992,Wal,91,M,507,32 +1992,Wal,91,F,2102,100 +1992,Wal,92,M,377,12 +1992,Wal,92,F,1473,55 +1992,Wal,93,M,254,19 +1992,Wal,93,F,1097,52 +1992,Wal,94,M,160,11 +1992,Wal,94,F,791,43 +1992,Wal,95,M,108,11 +1992,Wal,95,F,570,23 +1992,Wal,96,M,53,0 +1992,Wal,96,F,414,11 +1992,Wal,97,M,51,4 +1992,Wal,97,F,248,17 +1992,Wal,98,M,30,1 +1992,Wal,98,F,136,3 +1992,Wal,99,M,12,1 +1992,Wal,99,F,98,8 +1992,Wal,100,M,9,1 +1992,Wal,100,F,46,5 +1992,Wal,101,M,4,0 +1992,Wal,101,F,30,2 +1992,Wal,102,M,6,1 +1992,Wal,102,F,14,2 +1992,Wal,103,M,0,0 +1992,Wal,103,F,17,0 +1992,Wal,104,M,0,0 +1992,Wal,104,F,4,0 +1992,Wal,105,M,0,0 +1992,Wal,105,F,2,1 +1992,Wal,106,M,0,0 +1992,Wal,106,F,1,0 +1992,Wal,107,M,0,0 +1992,Wal,107,F,0,0 +1992,Wal,108,M,0,0 +1992,Wal,108,F,0,0 +1992,Wal,109,M,0,0 +1992,Wal,109,F,0,0 +1992,Wal,110,M,0,0 +1992,Wal,110,F,0,0 +1992,Wal,111,M,0,0 +1992,Wal,111,F,0,0 +1992,Wal,112,M,0,0 +1992,Wal,112,F,0,0 +1992,Wal,113,M,0,0 +1992,Wal,113,F,0,0 +1992,Wal,114,M,0,0 +1992,Wal,114,F,0,0 +1992,Wal,115,M,0,0 +1992,Wal,115,F,0,0 +1992,Wal,116,M,0,0 +1992,Wal,116,F,0,0 +1992,Wal,117,M,0,0 +1992,Wal,117,F,0,0 +1992,Wal,118,M,0,0 +1992,Wal,118,F,0,0 +1992,Wal,119,M,0,0 +1992,Wal,119,F,0,0 +1992,Wal,120,M,0,0 +1992,Wal,120,F,0,0 +1993,BruCap,0,M,4418,2065 +1993,BruCap,0,F,4344,1981 +1993,BruCap,1,M,4250,2062 +1993,BruCap,1,F,4063,1996 +1993,BruCap,2,M,4053,2209 +1993,BruCap,2,F,3902,2028 +1993,BruCap,3,M,3745,2121 +1993,BruCap,3,F,3650,2075 +1993,BruCap,4,M,3700,2161 +1993,BruCap,4,F,3464,2086 +1993,BruCap,5,M,3516,2149 +1993,BruCap,5,F,3356,2075 +1993,BruCap,6,M,3420,2137 +1993,BruCap,6,F,3199,2022 +1993,BruCap,7,M,3241,2118 +1993,BruCap,7,F,2976,1958 +1993,BruCap,8,M,3284,2123 +1993,BruCap,8,F,3113,2068 +1993,BruCap,9,M,3156,2106 +1993,BruCap,9,F,3075,1950 +1993,BruCap,10,M,3190,2198 +1993,BruCap,10,F,3021,2132 +1993,BruCap,11,M,3343,2292 +1993,BruCap,11,F,3148,2141 +1993,BruCap,12,M,3277,2220 +1993,BruCap,12,F,3173,2173 +1993,BruCap,13,M,3146,2310 +1993,BruCap,13,F,2961,2170 +1993,BruCap,14,M,3007,2180 +1993,BruCap,14,F,3041,2224 +1993,BruCap,15,M,2995,2175 +1993,BruCap,15,F,2946,2128 +1993,BruCap,16,M,2975,2158 +1993,BruCap,16,F,2925,2085 +1993,BruCap,17,M,3071,2109 +1993,BruCap,17,F,3000,1946 +1993,BruCap,18,M,3141,2110 +1993,BruCap,18,F,3172,1964 +1993,BruCap,19,M,3421,2202 +1993,BruCap,19,F,3562,2139 +1993,BruCap,20,M,3662,2369 +1993,BruCap,20,F,3804,2330 +1993,BruCap,21,M,3998,2412 +1993,BruCap,21,F,4086,2473 +1993,BruCap,22,M,4126,2680 +1993,BruCap,22,F,4390,2487 +1993,BruCap,23,M,4229,2775 +1993,BruCap,23,F,4501,2682 +1993,BruCap,24,M,4544,2890 +1993,BruCap,24,F,4799,2697 +1993,BruCap,25,M,4801,2897 +1993,BruCap,25,F,5160,2776 +1993,BruCap,26,M,4870,3225 +1993,BruCap,26,F,5163,3064 +1993,BruCap,27,M,5147,3331 +1993,BruCap,27,F,5274,3127 +1993,BruCap,28,M,5232,3399 +1993,BruCap,28,F,5291,3176 +1993,BruCap,29,M,5084,3269 +1993,BruCap,29,F,5102,2941 +1993,BruCap,30,M,4784,3317 +1993,BruCap,30,F,4893,2967 +1993,BruCap,31,M,4681,3196 +1993,BruCap,31,F,4970,2889 +1993,BruCap,32,M,4662,3194 +1993,BruCap,32,F,4918,2921 +1993,BruCap,33,M,4720,2917 +1993,BruCap,33,F,4766,2721 +1993,BruCap,34,M,4483,2909 +1993,BruCap,34,F,4793,2578 +1993,BruCap,35,M,4508,2670 +1993,BruCap,35,F,4694,2403 +1993,BruCap,36,M,4275,2717 +1993,BruCap,36,F,4642,2430 +1993,BruCap,37,M,4295,2581 +1993,BruCap,37,F,4570,2334 +1993,BruCap,38,M,4269,2412 +1993,BruCap,38,F,4457,2199 +1993,BruCap,39,M,4271,2359 +1993,BruCap,39,F,4622,2056 +1993,BruCap,40,M,4210,2401 +1993,BruCap,40,F,4578,2080 +1993,BruCap,41,M,4140,2086 +1993,BruCap,41,F,4526,1785 +1993,BruCap,42,M,4025,2181 +1993,BruCap,42,F,4582,1947 +1993,BruCap,43,M,4100,1955 +1993,BruCap,43,F,4610,1627 +1993,BruCap,44,M,4206,1968 +1993,BruCap,44,F,4659,1649 +1993,BruCap,45,M,4283,1900 +1993,BruCap,45,F,4894,1561 +1993,BruCap,46,M,4437,1760 +1993,BruCap,46,F,4837,1491 +1993,BruCap,47,M,3665,1573 +1993,BruCap,47,F,4158,1367 +1993,BruCap,48,M,3904,1602 +1993,BruCap,48,F,4451,1371 +1993,BruCap,49,M,3759,1485 +1993,BruCap,49,F,4204,1280 +1993,BruCap,50,M,3211,1536 +1993,BruCap,50,F,3648,1227 +1993,BruCap,51,M,2848,1312 +1993,BruCap,51,F,3335,1135 +1993,BruCap,52,M,3224,1608 +1993,BruCap,52,F,3615,1413 +1993,BruCap,53,M,3416,1433 +1993,BruCap,53,F,4037,1190 +1993,BruCap,54,M,3407,1469 +1993,BruCap,54,F,3972,1113 +1993,BruCap,55,M,3389,1346 +1993,BruCap,55,F,3965,1098 +1993,BruCap,56,M,3338,1366 +1993,BruCap,56,F,3925,1106 +1993,BruCap,57,M,3339,1220 +1993,BruCap,57,F,4013,1102 +1993,BruCap,58,M,3527,1215 +1993,BruCap,58,F,4086,978 +1993,BruCap,59,M,3524,1140 +1993,BruCap,59,F,4266,875 +1993,BruCap,60,M,3690,1168 +1993,BruCap,60,F,4487,890 +1993,BruCap,61,M,3747,969 +1993,BruCap,61,F,4647,817 +1993,BruCap,62,M,3715,1054 +1993,BruCap,62,F,4988,852 +1993,BruCap,63,M,3605,923 +1993,BruCap,63,F,4739,667 +1993,BruCap,64,M,3559,854 +1993,BruCap,64,F,4681,697 +1993,BruCap,65,M,3490,745 +1993,BruCap,65,F,4735,588 +1993,BruCap,66,M,3560,661 +1993,BruCap,66,F,4919,573 +1993,BruCap,67,M,3589,622 +1993,BruCap,67,F,5094,539 +1993,BruCap,68,M,3728,482 +1993,BruCap,68,F,5200,484 +1993,BruCap,69,M,3517,525 +1993,BruCap,69,F,5424,488 +1993,BruCap,70,M,3545,435 +1993,BruCap,70,F,5380,421 +1993,BruCap,71,M,3706,421 +1993,BruCap,71,F,5499,378 +1993,BruCap,72,M,3564,376 +1993,BruCap,72,F,5642,443 +1993,BruCap,73,M,2606,220 +1993,BruCap,73,F,4005,287 +1993,BruCap,74,M,1634,196 +1993,BruCap,74,F,2974,234 +1993,BruCap,75,M,1577,184 +1993,BruCap,75,F,2873,228 +1993,BruCap,76,M,1655,143 +1993,BruCap,76,F,3073,204 +1993,BruCap,77,M,1941,156 +1993,BruCap,77,F,3722,201 +1993,BruCap,78,M,2161,165 +1993,BruCap,78,F,4365,209 +1993,BruCap,79,M,1976,145 +1993,BruCap,79,F,4140,219 +1993,BruCap,80,M,1809,123 +1993,BruCap,80,F,4007,226 +1993,BruCap,81,M,1569,115 +1993,BruCap,81,F,3622,181 +1993,BruCap,82,M,1393,103 +1993,BruCap,82,F,3526,192 +1993,BruCap,83,M,1214,73 +1993,BruCap,83,F,3066,165 +1993,BruCap,84,M,1042,85 +1993,BruCap,84,F,2989,129 +1993,BruCap,85,M,886,75 +1993,BruCap,85,F,2620,130 +1993,BruCap,86,M,741,55 +1993,BruCap,86,F,2320,118 +1993,BruCap,87,M,611,39 +1993,BruCap,87,F,2063,116 +1993,BruCap,88,M,495,47 +1993,BruCap,88,F,1683,87 +1993,BruCap,89,M,406,15 +1993,BruCap,89,F,1400,71 +1993,BruCap,90,M,296,25 +1993,BruCap,90,F,1223,46 +1993,BruCap,91,M,237,24 +1993,BruCap,91,F,974,52 +1993,BruCap,92,M,163,21 +1993,BruCap,92,F,733,59 +1993,BruCap,93,M,119,12 +1993,BruCap,93,F,574,19 +1993,BruCap,94,M,85,9 +1993,BruCap,94,F,378,32 +1993,BruCap,95,M,61,6 +1993,BruCap,95,F,262,19 +1993,BruCap,96,M,44,1 +1993,BruCap,96,F,187,10 +1993,BruCap,97,M,15,3 +1993,BruCap,97,F,143,11 +1993,BruCap,98,M,18,0 +1993,BruCap,98,F,106,7 +1993,BruCap,99,M,13,3 +1993,BruCap,99,F,53,4 +1993,BruCap,100,M,4,3 +1993,BruCap,100,F,39,4 +1993,BruCap,101,M,2,1 +1993,BruCap,101,F,20,3 +1993,BruCap,102,M,1,1 +1993,BruCap,102,F,11,2 +1993,BruCap,103,M,1,0 +1993,BruCap,103,F,6,1 +1993,BruCap,104,M,1,0 +1993,BruCap,104,F,6,0 +1993,BruCap,105,M,0,0 +1993,BruCap,105,F,2,0 +1993,BruCap,106,M,0,0 +1993,BruCap,106,F,2,0 +1993,BruCap,107,M,0,0 +1993,BruCap,107,F,1,0 +1993,BruCap,108,M,0,0 +1993,BruCap,108,F,0,2 +1993,BruCap,109,M,0,0 +1993,BruCap,109,F,0,0 +1993,BruCap,110,M,0,0 +1993,BruCap,110,F,0,0 +1993,BruCap,111,M,1,0 +1993,BruCap,111,F,0,0 +1993,BruCap,112,M,0,0 +1993,BruCap,112,F,0,0 +1993,BruCap,113,M,0,0 +1993,BruCap,113,F,0,0 +1993,BruCap,114,M,0,0 +1993,BruCap,114,F,0,0 +1993,BruCap,115,M,0,0 +1993,BruCap,115,F,0,0 +1993,BruCap,116,M,0,0 +1993,BruCap,116,F,0,0 +1993,BruCap,117,M,0,0 +1993,BruCap,117,F,0,0 +1993,BruCap,118,M,0,0 +1993,BruCap,118,F,0,0 +1993,BruCap,119,M,0,0 +1993,BruCap,119,F,0,0 +1993,BruCap,120,M,0,0 +1993,BruCap,120,F,0,0 +1993,Fla,0,M,33780,2027 +1993,Fla,0,F,32225,2020 +1993,Fla,1,M,34314,2054 +1993,Fla,1,F,32587,1981 +1993,Fla,2,M,34016,2056 +1993,Fla,2,F,32304,2033 +1993,Fla,3,M,32956,2024 +1993,Fla,3,F,31373,1973 +1993,Fla,4,M,32518,2103 +1993,Fla,4,F,31056,1929 +1993,Fla,5,M,32321,2061 +1993,Fla,5,F,30520,1990 +1993,Fla,6,M,32402,2063 +1993,Fla,6,F,30648,1811 +1993,Fla,7,M,31494,2023 +1993,Fla,7,F,30136,1909 +1993,Fla,8,M,32221,2076 +1993,Fla,8,F,30729,1950 +1993,Fla,9,M,33284,1950 +1993,Fla,9,F,31879,1994 +1993,Fla,10,M,34161,2075 +1993,Fla,10,F,32236,2080 +1993,Fla,11,M,35389,2121 +1993,Fla,11,F,33067,2174 +1993,Fla,12,M,34997,2226 +1993,Fla,12,F,33555,2061 +1993,Fla,13,M,35424,2245 +1993,Fla,13,F,33251,2139 +1993,Fla,14,M,34658,2090 +1993,Fla,14,F,33154,2071 +1993,Fla,15,M,34040,2086 +1993,Fla,15,F,32735,2058 +1993,Fla,16,M,33534,1971 +1993,Fla,16,F,31813,1958 +1993,Fla,17,M,32824,1896 +1993,Fla,17,F,31076,1906 +1993,Fla,18,M,34245,1954 +1993,Fla,18,F,32707,2008 +1993,Fla,19,M,35718,2116 +1993,Fla,19,F,33971,2048 +1993,Fla,20,M,37302,2248 +1993,Fla,20,F,35799,2138 +1993,Fla,21,M,38795,2417 +1993,Fla,21,F,37749,2286 +1993,Fla,22,M,39970,2491 +1993,Fla,22,F,38449,2384 +1993,Fla,23,M,40003,2721 +1993,Fla,23,F,38395,2482 +1993,Fla,24,M,40353,2752 +1993,Fla,24,F,38811,2484 +1993,Fla,25,M,41939,2824 +1993,Fla,25,F,39675,2416 +1993,Fla,26,M,42899,3209 +1993,Fla,26,F,41358,2747 +1993,Fla,27,M,44525,3316 +1993,Fla,27,F,42570,2577 +1993,Fla,28,M,46323,3421 +1993,Fla,28,F,44912,2680 +1993,Fla,29,M,46187,3225 +1993,Fla,29,F,44638,2546 +1993,Fla,30,M,45670,3359 +1993,Fla,30,F,44119,2413 +1993,Fla,31,M,45623,3086 +1993,Fla,31,F,44476,2223 +1993,Fla,32,M,44546,3359 +1993,Fla,32,F,43356,2485 +1993,Fla,33,M,45579,3009 +1993,Fla,33,F,44322,2222 +1993,Fla,34,M,44704,3101 +1993,Fla,34,F,43167,2164 +1993,Fla,35,M,44330,2890 +1993,Fla,35,F,42738,1941 +1993,Fla,36,M,43018,2909 +1993,Fla,36,F,42129,2034 +1993,Fla,37,M,42558,2811 +1993,Fla,37,F,41813,1918 +1993,Fla,38,M,41862,2664 +1993,Fla,38,F,40827,1794 +1993,Fla,39,M,41162,2399 +1993,Fla,39,F,39589,1695 +1993,Fla,40,M,41185,2447 +1993,Fla,40,F,39409,1633 +1993,Fla,41,M,39281,2353 +1993,Fla,41,F,37999,1498 +1993,Fla,42,M,38664,2532 +1993,Fla,42,F,37933,1574 +1993,Fla,43,M,39083,2469 +1993,Fla,43,F,37743,1573 +1993,Fla,44,M,39043,2368 +1993,Fla,44,F,38338,1456 +1993,Fla,45,M,38867,2205 +1993,Fla,45,F,37889,1470 +1993,Fla,46,M,39979,2142 +1993,Fla,46,F,38508,1350 +1993,Fla,47,M,35623,1876 +1993,Fla,47,F,34881,1221 +1993,Fla,48,M,35329,1816 +1993,Fla,48,F,34667,1268 +1993,Fla,49,M,33903,1800 +1993,Fla,49,F,33266,1151 +1993,Fla,50,M,29580,1724 +1993,Fla,50,F,29019,1167 +1993,Fla,51,M,26659,1656 +1993,Fla,51,F,26721,1040 +1993,Fla,52,M,29445,1798 +1993,Fla,52,F,29645,1242 +1993,Fla,53,M,32266,1690 +1993,Fla,53,F,33285,1049 +1993,Fla,54,M,33402,1617 +1993,Fla,54,F,34002,1082 +1993,Fla,55,M,32428,1507 +1993,Fla,55,F,32860,980 +1993,Fla,56,M,31488,1425 +1993,Fla,56,F,32353,904 +1993,Fla,57,M,31451,1358 +1993,Fla,57,F,32399,883 +1993,Fla,58,M,31534,1335 +1993,Fla,58,F,33095,917 +1993,Fla,59,M,31792,1296 +1993,Fla,59,F,33041,864 +1993,Fla,60,M,32469,1276 +1993,Fla,60,F,34545,799 +1993,Fla,61,M,32410,1121 +1993,Fla,61,F,34628,673 +1993,Fla,62,M,31752,1159 +1993,Fla,62,F,34524,773 +1993,Fla,63,M,29483,999 +1993,Fla,63,F,32363,686 +1993,Fla,64,M,28639,941 +1993,Fla,64,F,31704,674 +1993,Fla,65,M,27544,875 +1993,Fla,65,F,30621,612 +1993,Fla,66,M,26950,817 +1993,Fla,66,F,31189,650 +1993,Fla,67,M,26855,806 +1993,Fla,67,F,30822,617 +1993,Fla,68,M,25877,778 +1993,Fla,68,F,30283,562 +1993,Fla,69,M,25057,761 +1993,Fla,69,F,30094,593 +1993,Fla,70,M,23217,640 +1993,Fla,70,F,28528,523 +1993,Fla,71,M,22491,630 +1993,Fla,71,F,28299,499 +1993,Fla,72,M,21520,552 +1993,Fla,72,F,27697,468 +1993,Fla,73,M,16028,427 +1993,Fla,73,F,21024,314 +1993,Fla,74,M,10297,335 +1993,Fla,74,F,14477,292 +1993,Fla,75,M,9680,313 +1993,Fla,75,F,14190,254 +1993,Fla,76,M,10772,269 +1993,Fla,76,F,15702,267 +1993,Fla,77,M,12311,265 +1993,Fla,77,F,18420,266 +1993,Fla,78,M,13004,277 +1993,Fla,78,F,20645,272 +1993,Fla,79,M,11933,225 +1993,Fla,79,F,19966,246 +1993,Fla,80,M,10856,205 +1993,Fla,80,F,18788,245 +1993,Fla,81,M,9175,177 +1993,Fla,81,F,16820,203 +1993,Fla,82,M,8260,119 +1993,Fla,82,F,15804,179 +1993,Fla,83,M,7134,132 +1993,Fla,83,F,14232,206 +1993,Fla,84,M,5987,110 +1993,Fla,84,F,13169,147 +1993,Fla,85,M,5212,93 +1993,Fla,85,F,11475,133 +1993,Fla,86,M,4170,73 +1993,Fla,86,F,9948,126 +1993,Fla,87,M,3332,64 +1993,Fla,87,F,8584,84 +1993,Fla,88,M,2757,50 +1993,Fla,88,F,7254,120 +1993,Fla,89,M,2108,30 +1993,Fla,89,F,5778,65 +1993,Fla,90,M,1602,21 +1993,Fla,90,F,4673,47 +1993,Fla,91,M,1243,20 +1993,Fla,91,F,3730,50 +1993,Fla,92,M,822,13 +1993,Fla,92,F,2707,34 +1993,Fla,93,M,652,14 +1993,Fla,93,F,1970,26 +1993,Fla,94,M,470,5 +1993,Fla,94,F,1409,23 +1993,Fla,95,M,332,13 +1993,Fla,95,F,968,16 +1993,Fla,96,M,201,2 +1993,Fla,96,F,680,10 +1993,Fla,97,M,140,1 +1993,Fla,97,F,445,5 +1993,Fla,98,M,65,1 +1993,Fla,98,F,294,5 +1993,Fla,99,M,56,2 +1993,Fla,99,F,164,2 +1993,Fla,100,M,28,1 +1993,Fla,100,F,94,0 +1993,Fla,101,M,12,2 +1993,Fla,101,F,51,2 +1993,Fla,102,M,12,0 +1993,Fla,102,F,28,0 +1993,Fla,103,M,4,0 +1993,Fla,103,F,12,1 +1993,Fla,104,M,2,0 +1993,Fla,104,F,13,0 +1993,Fla,105,M,0,0 +1993,Fla,105,F,4,1 +1993,Fla,106,M,3,0 +1993,Fla,106,F,2,0 +1993,Fla,107,M,0,0 +1993,Fla,107,F,1,1 +1993,Fla,108,M,0,0 +1993,Fla,108,F,0,1 +1993,Fla,109,M,0,0 +1993,Fla,109,F,0,0 +1993,Fla,110,M,0,0 +1993,Fla,110,F,1,0 +1993,Fla,111,M,0,0 +1993,Fla,111,F,0,0 +1993,Fla,112,M,0,0 +1993,Fla,112,F,0,0 +1993,Fla,113,M,0,0 +1993,Fla,113,F,0,0 +1993,Fla,114,M,0,0 +1993,Fla,114,F,0,0 +1993,Fla,115,M,0,0 +1993,Fla,115,F,0,0 +1993,Fla,116,M,0,0 +1993,Fla,116,F,0,0 +1993,Fla,117,M,0,0 +1993,Fla,117,F,0,0 +1993,Fla,118,M,0,0 +1993,Fla,118,F,0,0 +1993,Fla,119,M,0,0 +1993,Fla,119,F,0,0 +1993,Fla,120,M,0,0 +1993,Fla,120,F,0,0 +1993,Wal,0,M,19883,1311 +1993,Wal,0,F,18932,1288 +1993,Wal,1,M,20532,1403 +1993,Wal,1,F,19723,1381 +1993,Wal,2,M,20381,1420 +1993,Wal,2,F,19514,1386 +1993,Wal,3,M,20499,1510 +1993,Wal,3,F,19469,1454 +1993,Wal,4,M,20375,1611 +1993,Wal,4,F,19294,1569 +1993,Wal,5,M,19557,1676 +1993,Wal,5,F,18678,1550 +1993,Wal,6,M,19620,1752 +1993,Wal,6,F,18589,1568 +1993,Wal,7,M,18926,1662 +1993,Wal,7,F,17975,1579 +1993,Wal,8,M,18593,1715 +1993,Wal,8,F,17895,1677 +1993,Wal,9,M,18591,1760 +1993,Wal,9,F,17201,1676 +1993,Wal,10,M,18724,1922 +1993,Wal,10,F,17917,1853 +1993,Wal,11,M,18895,1946 +1993,Wal,11,F,18383,1876 +1993,Wal,12,M,18957,2041 +1993,Wal,12,F,18394,1905 +1993,Wal,13,M,18675,2142 +1993,Wal,13,F,17643,2000 +1993,Wal,14,M,18356,2210 +1993,Wal,14,F,17629,2038 +1993,Wal,15,M,18681,2170 +1993,Wal,15,F,17688,2185 +1993,Wal,16,M,18810,2250 +1993,Wal,16,F,18109,2156 +1993,Wal,17,M,19013,2306 +1993,Wal,17,F,18273,2183 +1993,Wal,18,M,19765,2612 +1993,Wal,18,F,18772,2397 +1993,Wal,19,M,20502,2950 +1993,Wal,19,F,19583,2706 +1993,Wal,20,M,20982,3136 +1993,Wal,20,F,20155,2859 +1993,Wal,21,M,21263,3267 +1993,Wal,21,F,20657,2952 +1993,Wal,22,M,20715,3379 +1993,Wal,22,F,19879,2950 +1993,Wal,23,M,20489,3416 +1993,Wal,23,F,19817,3014 +1993,Wal,24,M,19797,3499 +1993,Wal,24,F,19433,3137 +1993,Wal,25,M,20077,3516 +1993,Wal,25,F,19446,3020 +1993,Wal,26,M,20289,4057 +1993,Wal,26,F,19984,3322 +1993,Wal,27,M,20952,4258 +1993,Wal,27,F,20676,3354 +1993,Wal,28,M,21756,4192 +1993,Wal,28,F,21659,3328 +1993,Wal,29,M,21519,4159 +1993,Wal,29,F,21704,3198 +1993,Wal,30,M,20873,4133 +1993,Wal,30,F,21330,3074 +1993,Wal,31,M,21572,3985 +1993,Wal,31,F,22090,3178 +1993,Wal,32,M,21460,4409 +1993,Wal,32,F,21707,3136 +1993,Wal,33,M,21833,4158 +1993,Wal,33,F,22706,3029 +1993,Wal,34,M,21560,4176 +1993,Wal,34,F,22226,2990 +1993,Wal,35,M,21415,4072 +1993,Wal,35,F,21903,2875 +1993,Wal,36,M,20981,4211 +1993,Wal,36,F,21773,2923 +1993,Wal,37,M,20922,4000 +1993,Wal,37,F,21879,2865 +1993,Wal,38,M,20890,3916 +1993,Wal,38,F,21752,2715 +1993,Wal,39,M,21001,3674 +1993,Wal,39,F,21531,2514 +1993,Wal,40,M,20943,3561 +1993,Wal,40,F,21341,2479 +1993,Wal,41,M,20295,3360 +1993,Wal,41,F,21094,2369 +1993,Wal,42,M,21214,3468 +1993,Wal,42,F,21294,2497 +1993,Wal,43,M,21129,3263 +1993,Wal,43,F,21365,2318 +1993,Wal,44,M,21764,3208 +1993,Wal,44,F,22089,2375 +1993,Wal,45,M,21883,3170 +1993,Wal,45,F,21955,2195 +1993,Wal,46,M,21311,2975 +1993,Wal,46,F,21858,2036 +1993,Wal,47,M,15871,2365 +1993,Wal,47,F,16720,1733 +1993,Wal,48,M,15944,2360 +1993,Wal,48,F,16413,1802 +1993,Wal,49,M,14933,2115 +1993,Wal,49,F,15555,1652 +1993,Wal,50,M,12962,2076 +1993,Wal,50,F,13585,1620 +1993,Wal,51,M,12100,1987 +1993,Wal,51,F,12919,1540 +1993,Wal,52,M,13542,2333 +1993,Wal,52,F,14447,1808 +1993,Wal,53,M,14739,2146 +1993,Wal,53,F,15975,1809 +1993,Wal,54,M,15003,2021 +1993,Wal,54,F,16398,1782 +1993,Wal,55,M,14376,2053 +1993,Wal,55,F,15382,1664 +1993,Wal,56,M,14027,1999 +1993,Wal,56,F,15461,1699 +1993,Wal,57,M,13944,1995 +1993,Wal,57,F,15503,1717 +1993,Wal,58,M,14713,1924 +1993,Wal,58,F,16186,1750 +1993,Wal,59,M,14825,1910 +1993,Wal,59,F,16336,1756 +1993,Wal,60,M,15688,2052 +1993,Wal,60,F,17849,1707 +1993,Wal,61,M,16229,1843 +1993,Wal,61,F,18409,1681 +1993,Wal,62,M,16091,1988 +1993,Wal,62,F,18575,1743 +1993,Wal,63,M,15212,1919 +1993,Wal,63,F,17863,1684 +1993,Wal,64,M,14958,1917 +1993,Wal,64,F,18112,1599 +1993,Wal,65,M,14707,1909 +1993,Wal,65,F,17693,1666 +1993,Wal,66,M,14463,1921 +1993,Wal,66,F,17908,1654 +1993,Wal,67,M,14403,1786 +1993,Wal,67,F,18422,1614 +1993,Wal,68,M,13848,1754 +1993,Wal,68,F,18073,1533 +1993,Wal,69,M,13170,1689 +1993,Wal,69,F,17639,1445 +1993,Wal,70,M,12909,1473 +1993,Wal,70,F,17669,1362 +1993,Wal,71,M,12702,1280 +1993,Wal,71,F,17982,1288 +1993,Wal,72,M,11963,1144 +1993,Wal,72,F,17497,1174 +1993,Wal,73,M,8379,681 +1993,Wal,73,F,12607,806 +1993,Wal,74,M,5621,523 +1993,Wal,74,F,8808,544 +1993,Wal,75,M,5030,461 +1993,Wal,75,F,8446,490 +1993,Wal,76,M,5477,446 +1993,Wal,76,F,8761,565 +1993,Wal,77,M,6061,465 +1993,Wal,77,F,10404,639 +1993,Wal,78,M,6616,480 +1993,Wal,78,F,12130,682 +1993,Wal,79,M,6010,463 +1993,Wal,79,F,11358,626 +1993,Wal,80,M,5217,395 +1993,Wal,80,F,10941,577 +1993,Wal,81,M,4311,315 +1993,Wal,81,F,9641,526 +1993,Wal,82,M,3948,230 +1993,Wal,82,F,9260,466 +1993,Wal,83,M,3310,168 +1993,Wal,83,F,8418,436 +1993,Wal,84,M,2778,168 +1993,Wal,84,F,7747,373 +1993,Wal,85,M,2367,121 +1993,Wal,85,F,7118,302 +1993,Wal,86,M,1975,113 +1993,Wal,86,F,5951,271 +1993,Wal,87,M,1551,93 +1993,Wal,87,F,4851,234 +1993,Wal,88,M,1246,70 +1993,Wal,88,F,4317,216 +1993,Wal,89,M,965,60 +1993,Wal,89,F,3429,134 +1993,Wal,90,M,718,36 +1993,Wal,90,F,2764,134 +1993,Wal,91,M,579,32 +1993,Wal,91,F,2375,114 +1993,Wal,92,M,371,24 +1993,Wal,92,F,1686,86 +1993,Wal,93,M,274,8 +1993,Wal,93,F,1128,47 +1993,Wal,94,M,168,16 +1993,Wal,94,F,853,38 +1993,Wal,95,M,114,8 +1993,Wal,95,F,584,33 +1993,Wal,96,M,82,11 +1993,Wal,96,F,412,17 +1993,Wal,97,M,30,0 +1993,Wal,97,F,277,9 +1993,Wal,98,M,31,2 +1993,Wal,98,F,179,12 +1993,Wal,99,M,21,1 +1993,Wal,99,F,94,4 +1993,Wal,100,M,7,1 +1993,Wal,100,F,66,3 +1993,Wal,101,M,8,0 +1993,Wal,101,F,29,2 +1993,Wal,102,M,3,0 +1993,Wal,102,F,17,2 +1993,Wal,103,M,2,0 +1993,Wal,103,F,6,2 +1993,Wal,104,M,0,0 +1993,Wal,104,F,8,0 +1993,Wal,105,M,0,0 +1993,Wal,105,F,2,0 +1993,Wal,106,M,0,0 +1993,Wal,106,F,0,0 +1993,Wal,107,M,0,0 +1993,Wal,107,F,0,0 +1993,Wal,108,M,0,0 +1993,Wal,108,F,0,0 +1993,Wal,109,M,0,0 +1993,Wal,109,F,0,0 +1993,Wal,110,M,0,0 +1993,Wal,110,F,0,0 +1993,Wal,111,M,0,0 +1993,Wal,111,F,0,0 +1993,Wal,112,M,0,0 +1993,Wal,112,F,0,0 +1993,Wal,113,M,0,0 +1993,Wal,113,F,0,0 +1993,Wal,114,M,0,0 +1993,Wal,114,F,0,0 +1993,Wal,115,M,0,0 +1993,Wal,115,F,0,0 +1993,Wal,116,M,0,0 +1993,Wal,116,F,0,0 +1993,Wal,117,M,0,0 +1993,Wal,117,F,0,0 +1993,Wal,118,M,0,0 +1993,Wal,118,F,0,0 +1993,Wal,119,M,0,0 +1993,Wal,119,F,0,0 +1993,Wal,120,M,0,0 +1993,Wal,120,F,0,0 +1994,BruCap,0,M,4334,2033 +1994,BruCap,0,F,4073,1942 +1994,BruCap,1,M,4227,2096 +1994,BruCap,1,F,4143,2027 +1994,BruCap,2,M,4086,2043 +1994,BruCap,2,F,3909,2011 +1994,BruCap,3,M,3912,2197 +1994,BruCap,3,F,3769,2027 +1994,BruCap,4,M,3676,2090 +1994,BruCap,4,F,3581,2069 +1994,BruCap,5,M,3623,2131 +1994,BruCap,5,F,3404,2060 +1994,BruCap,6,M,3459,2113 +1994,BruCap,6,F,3320,2037 +1994,BruCap,7,M,3395,2081 +1994,BruCap,7,F,3180,1952 +1994,BruCap,8,M,3224,2066 +1994,BruCap,8,F,2972,1914 +1994,BruCap,9,M,3305,2042 +1994,BruCap,9,F,3119,2017 +1994,BruCap,10,M,3194,2033 +1994,BruCap,10,F,3117,1891 +1994,BruCap,11,M,3236,2090 +1994,BruCap,11,F,3101,2040 +1994,BruCap,12,M,3451,2136 +1994,BruCap,12,F,3230,2028 +1994,BruCap,13,M,3266,2203 +1994,BruCap,13,F,3150,2147 +1994,BruCap,14,M,3121,2289 +1994,BruCap,14,F,2937,2184 +1994,BruCap,15,M,2992,2174 +1994,BruCap,15,F,3029,2230 +1994,BruCap,16,M,2980,2163 +1994,BruCap,16,F,2947,2143 +1994,BruCap,17,M,2939,2190 +1994,BruCap,17,F,2920,2114 +1994,BruCap,18,M,3255,1993 +1994,BruCap,18,F,3221,1843 +1994,BruCap,19,M,3299,2043 +1994,BruCap,19,F,3463,1897 +1994,BruCap,20,M,3615,2187 +1994,BruCap,20,F,3823,2152 +1994,BruCap,21,M,3826,2453 +1994,BruCap,21,F,4059,2358 +1994,BruCap,22,M,4141,2518 +1994,BruCap,22,F,4356,2550 +1994,BruCap,23,M,4300,2771 +1994,BruCap,23,F,4683,2618 +1994,BruCap,24,M,4485,2949 +1994,BruCap,24,F,4769,2822 +1994,BruCap,25,M,4698,3109 +1994,BruCap,25,F,4945,2844 +1994,BruCap,26,M,4910,3061 +1994,BruCap,26,F,5152,2936 +1994,BruCap,27,M,4834,3403 +1994,BruCap,27,F,5059,3147 +1994,BruCap,28,M,5099,3494 +1994,BruCap,28,F,5133,3222 +1994,BruCap,29,M,5059,3577 +1994,BruCap,29,F,5083,3276 +1994,BruCap,30,M,4937,3402 +1994,BruCap,30,F,4975,3005 +1994,BruCap,31,M,4625,3402 +1994,BruCap,31,F,4719,3031 +1994,BruCap,32,M,4545,3214 +1994,BruCap,32,F,4802,2900 +1994,BruCap,33,M,4522,3199 +1994,BruCap,33,F,4774,2933 +1994,BruCap,34,M,4562,2929 +1994,BruCap,34,F,4663,2696 +1994,BruCap,35,M,4381,2907 +1994,BruCap,35,F,4685,2553 +1994,BruCap,36,M,4398,2661 +1994,BruCap,36,F,4590,2391 +1994,BruCap,37,M,4187,2684 +1994,BruCap,37,F,4564,2426 +1994,BruCap,38,M,4210,2554 +1994,BruCap,38,F,4523,2331 +1994,BruCap,39,M,4196,2398 +1994,BruCap,39,F,4412,2188 +1994,BruCap,40,M,4210,2300 +1994,BruCap,40,F,4529,2032 +1994,BruCap,41,M,4193,2337 +1994,BruCap,41,F,4516,2052 +1994,BruCap,42,M,4108,2083 +1994,BruCap,42,F,4463,1762 +1994,BruCap,43,M,3991,2159 +1994,BruCap,43,F,4536,1922 +1994,BruCap,44,M,4062,1919 +1994,BruCap,44,F,4568,1646 +1994,BruCap,45,M,4164,1925 +1994,BruCap,45,F,4614,1625 +1994,BruCap,46,M,4232,1886 +1994,BruCap,46,F,4840,1558 +1994,BruCap,47,M,4363,1763 +1994,BruCap,47,F,4773,1494 +1994,BruCap,48,M,3635,1580 +1994,BruCap,48,F,4120,1378 +1994,BruCap,49,M,3841,1619 +1994,BruCap,49,F,4413,1377 +1994,BruCap,50,M,3730,1503 +1994,BruCap,50,F,4160,1279 +1994,BruCap,51,M,3171,1539 +1994,BruCap,51,F,3603,1225 +1994,BruCap,52,M,2832,1289 +1994,BruCap,52,F,3273,1128 +1994,BruCap,53,M,3164,1592 +1994,BruCap,53,F,3571,1400 +1994,BruCap,54,M,3380,1439 +1994,BruCap,54,F,3979,1187 +1994,BruCap,55,M,3332,1449 +1994,BruCap,55,F,3908,1110 +1994,BruCap,56,M,3349,1337 +1994,BruCap,56,F,3889,1086 +1994,BruCap,57,M,3266,1354 +1994,BruCap,57,F,3865,1103 +1994,BruCap,58,M,3237,1210 +1994,BruCap,58,F,3960,1082 +1994,BruCap,59,M,3443,1204 +1994,BruCap,59,F,4012,967 +1994,BruCap,60,M,3407,1102 +1994,BruCap,60,F,4185,853 +1994,BruCap,61,M,3576,1133 +1994,BruCap,61,F,4409,870 +1994,BruCap,62,M,3626,948 +1994,BruCap,62,F,4531,794 +1994,BruCap,63,M,3601,1033 +1994,BruCap,63,F,4912,832 +1994,BruCap,64,M,3496,901 +1994,BruCap,64,F,4652,656 +1994,BruCap,65,M,3456,793 +1994,BruCap,65,F,4616,683 +1994,BruCap,66,M,3380,700 +1994,BruCap,66,F,4670,578 +1994,BruCap,67,M,3410,629 +1994,BruCap,67,F,4855,566 +1994,BruCap,68,M,3453,579 +1994,BruCap,68,F,4998,517 +1994,BruCap,69,M,3571,462 +1994,BruCap,69,F,5100,483 +1994,BruCap,70,M,3369,491 +1994,BruCap,70,F,5317,464 +1994,BruCap,71,M,3387,414 +1994,BruCap,71,F,5263,406 +1994,BruCap,72,M,3543,393 +1994,BruCap,72,F,5391,365 +1994,BruCap,73,M,3379,353 +1994,BruCap,73,F,5491,429 +1994,BruCap,74,M,2463,213 +1994,BruCap,74,F,3887,278 +1994,BruCap,75,M,1524,178 +1994,BruCap,75,F,2858,218 +1994,BruCap,76,M,1487,170 +1994,BruCap,76,F,2762,221 +1994,BruCap,77,M,1523,132 +1994,BruCap,77,F,2950,195 +1994,BruCap,78,M,1786,144 +1994,BruCap,78,F,3569,200 +1994,BruCap,79,M,1976,156 +1994,BruCap,79,F,4144,198 +1994,BruCap,80,M,1805,129 +1994,BruCap,80,F,3901,212 +1994,BruCap,81,M,1635,112 +1994,BruCap,81,F,3758,206 +1994,BruCap,82,M,1402,102 +1994,BruCap,82,F,3387,171 +1994,BruCap,83,M,1228,90 +1994,BruCap,83,F,3234,177 +1994,BruCap,84,M,1054,65 +1994,BruCap,84,F,2780,156 +1994,BruCap,85,M,881,74 +1994,BruCap,85,F,2717,118 +1994,BruCap,86,M,750,66 +1994,BruCap,86,F,2362,115 +1994,BruCap,87,M,624,47 +1994,BruCap,87,F,2033,102 +1994,BruCap,88,M,502,29 +1994,BruCap,88,F,1789,109 +1994,BruCap,89,M,402,44 +1994,BruCap,89,F,1459,77 +1994,BruCap,90,M,321,10 +1994,BruCap,90,F,1172,68 +1994,BruCap,91,M,231,21 +1994,BruCap,91,F,1030,39 +1994,BruCap,92,M,193,18 +1994,BruCap,92,F,778,45 +1994,BruCap,93,M,117,17 +1994,BruCap,93,F,559,47 +1994,BruCap,94,M,84,11 +1994,BruCap,94,F,457,14 +1994,BruCap,95,M,57,7 +1994,BruCap,95,F,289,28 +1994,BruCap,96,M,36,3 +1994,BruCap,96,F,193,15 +1994,BruCap,97,M,28,1 +1994,BruCap,97,F,138,8 +1994,BruCap,98,M,11,1 +1994,BruCap,98,F,111,9 +1994,BruCap,99,M,12,0 +1994,BruCap,99,F,75,6 +1994,BruCap,100,M,7,0 +1994,BruCap,100,F,34,4 +1994,BruCap,101,M,4,3 +1994,BruCap,101,F,26,2 +1994,BruCap,102,M,1,0 +1994,BruCap,102,F,12,3 +1994,BruCap,103,M,1,0 +1994,BruCap,103,F,9,1 +1994,BruCap,104,M,0,0 +1994,BruCap,104,F,4,1 +1994,BruCap,105,M,1,0 +1994,BruCap,105,F,4,0 +1994,BruCap,106,M,0,0 +1994,BruCap,106,F,1,0 +1994,BruCap,107,M,0,0 +1994,BruCap,107,F,0,0 +1994,BruCap,108,M,0,0 +1994,BruCap,108,F,0,0 +1994,BruCap,109,M,0,0 +1994,BruCap,109,F,0,2 +1994,BruCap,110,M,0,0 +1994,BruCap,110,F,0,0 +1994,BruCap,111,M,0,0 +1994,BruCap,111,F,0,0 +1994,BruCap,112,M,0,0 +1994,BruCap,112,F,0,0 +1994,BruCap,113,M,0,0 +1994,BruCap,113,F,0,0 +1994,BruCap,114,M,0,0 +1994,BruCap,114,F,0,0 +1994,BruCap,115,M,0,0 +1994,BruCap,115,F,0,0 +1994,BruCap,116,M,0,0 +1994,BruCap,116,F,0,0 +1994,BruCap,117,M,0,0 +1994,BruCap,117,F,0,0 +1994,BruCap,118,M,0,0 +1994,BruCap,118,F,0,0 +1994,BruCap,119,M,0,0 +1994,BruCap,119,F,0,0 +1994,BruCap,120,M,0,0 +1994,BruCap,120,F,0,0 +1994,Fla,0,M,32531,2053 +1994,Fla,0,F,31468,1917 +1994,Fla,1,M,33967,2041 +1994,Fla,1,F,32421,2066 +1994,Fla,2,M,34476,2107 +1994,Fla,2,F,32693,2016 +1994,Fla,3,M,34134,2101 +1994,Fla,3,F,32441,2069 +1994,Fla,4,M,33057,2063 +1994,Fla,4,F,31462,1997 +1994,Fla,5,M,32619,2102 +1994,Fla,5,F,31166,1948 +1994,Fla,6,M,32408,2086 +1994,Fla,6,F,30622,1987 +1994,Fla,7,M,32502,2070 +1994,Fla,7,F,30719,1825 +1994,Fla,8,M,31609,2029 +1994,Fla,8,F,30210,1897 +1994,Fla,9,M,32340,2035 +1994,Fla,9,F,30833,1924 +1994,Fla,10,M,33403,1941 +1994,Fla,10,F,31948,2002 +1994,Fla,11,M,34315,2020 +1994,Fla,11,F,32389,2020 +1994,Fla,12,M,35601,1984 +1994,Fla,12,F,33262,2021 +1994,Fla,13,M,35037,2248 +1994,Fla,13,F,33610,2082 +1994,Fla,14,M,35472,2274 +1994,Fla,14,F,33309,2146 +1994,Fla,15,M,34698,2136 +1994,Fla,15,F,33190,2101 +1994,Fla,16,M,34063,2111 +1994,Fla,16,F,32781,2120 +1994,Fla,17,M,33580,2020 +1994,Fla,17,F,31830,2042 +1994,Fla,18,M,32961,1893 +1994,Fla,18,F,31259,1905 +1994,Fla,19,M,34294,1979 +1994,Fla,19,F,32881,1980 +1994,Fla,20,M,35728,2171 +1994,Fla,20,F,34103,2081 +1994,Fla,21,M,37269,2292 +1994,Fla,21,F,35870,2203 +1994,Fla,22,M,38800,2494 +1994,Fla,22,F,37771,2384 +1994,Fla,23,M,39923,2657 +1994,Fla,23,F,38398,2510 +1994,Fla,24,M,39928,2869 +1994,Fla,24,F,38296,2620 +1994,Fla,25,M,40291,2997 +1994,Fla,25,F,38746,2582 +1994,Fla,26,M,41777,2994 +1994,Fla,26,F,39675,2565 +1994,Fla,27,M,42918,3398 +1994,Fla,27,F,41446,2857 +1994,Fla,28,M,44489,3431 +1994,Fla,28,F,42617,2659 +1994,Fla,29,M,46327,3500 +1994,Fla,29,F,45002,2796 +1994,Fla,30,M,46240,3293 +1994,Fla,30,F,44643,2619 +1994,Fla,31,M,45710,3458 +1994,Fla,31,F,44144,2493 +1994,Fla,32,M,45622,3193 +1994,Fla,32,F,44536,2353 +1994,Fla,33,M,44569,3462 +1994,Fla,33,F,43413,2560 +1994,Fla,34,M,45573,3045 +1994,Fla,34,F,44355,2327 +1994,Fla,35,M,44770,3144 +1994,Fla,35,F,43200,2218 +1994,Fla,36,M,44305,2951 +1994,Fla,36,F,42736,2008 +1994,Fla,37,M,43021,2896 +1994,Fla,37,F,42124,2092 +1994,Fla,38,M,42544,2819 +1994,Fla,38,F,41812,1941 +1994,Fla,39,M,41872,2671 +1994,Fla,39,F,40807,1851 +1994,Fla,40,M,41135,2411 +1994,Fla,40,F,39593,1741 +1994,Fla,41,M,41125,2447 +1994,Fla,41,F,39388,1667 +1994,Fla,42,M,39182,2357 +1994,Fla,42,F,37995,1526 +1994,Fla,43,M,38604,2532 +1994,Fla,43,F,37907,1634 +1994,Fla,44,M,39010,2468 +1994,Fla,44,F,37706,1596 +1994,Fla,45,M,38947,2336 +1994,Fla,45,F,38287,1497 +1994,Fla,46,M,38765,2210 +1994,Fla,46,F,37850,1496 +1994,Fla,47,M,39890,2171 +1994,Fla,47,F,38460,1380 +1994,Fla,48,M,35461,1902 +1994,Fla,48,F,34814,1252 +1994,Fla,49,M,35232,1847 +1994,Fla,49,F,34602,1304 +1994,Fla,50,M,33775,1825 +1994,Fla,50,F,33188,1186 +1994,Fla,51,M,29474,1739 +1994,Fla,51,F,28947,1198 +1994,Fla,52,M,26488,1675 +1994,Fla,52,F,26663,1067 +1994,Fla,53,M,29273,1794 +1994,Fla,53,F,29566,1276 +1994,Fla,54,M,32081,1692 +1994,Fla,54,F,33188,1058 +1994,Fla,55,M,33217,1623 +1994,Fla,55,F,33899,1083 +1994,Fla,56,M,32223,1509 +1994,Fla,56,F,32742,1002 +1994,Fla,57,M,31236,1428 +1994,Fla,57,F,32248,920 +1994,Fla,58,M,31185,1361 +1994,Fla,58,F,32273,888 +1994,Fla,59,M,31264,1348 +1994,Fla,59,F,32954,937 +1994,Fla,60,M,31456,1306 +1994,Fla,60,F,32865,880 +1994,Fla,61,M,32078,1280 +1994,Fla,61,F,34339,822 +1994,Fla,62,M,31970,1125 +1994,Fla,62,F,34441,691 +1994,Fla,63,M,31287,1156 +1994,Fla,63,F,34299,779 +1994,Fla,64,M,28984,992 +1994,Fla,64,F,32125,692 +1994,Fla,65,M,28089,935 +1994,Fla,65,F,31425,681 +1994,Fla,66,M,26952,876 +1994,Fla,66,F,30310,614 +1994,Fla,67,M,26347,805 +1994,Fla,67,F,30799,639 +1994,Fla,68,M,26143,791 +1994,Fla,68,F,30456,624 +1994,Fla,69,M,25113,761 +1994,Fla,69,F,29869,560 +1994,Fla,70,M,24335,735 +1994,Fla,70,F,29667,583 +1994,Fla,71,M,22421,621 +1994,Fla,71,F,28034,517 +1994,Fla,72,M,21562,609 +1994,Fla,72,F,27774,489 +1994,Fla,73,M,20544,529 +1994,Fla,73,F,27120,474 +1994,Fla,74,M,15254,411 +1994,Fla,74,F,20481,310 +1994,Fla,75,M,9723,320 +1994,Fla,75,F,14076,286 +1994,Fla,76,M,9062,297 +1994,Fla,76,F,13752,249 +1994,Fla,77,M,10022,255 +1994,Fla,77,F,15181,262 +1994,Fla,78,M,11426,244 +1994,Fla,78,F,17677,253 +1994,Fla,79,M,11921,248 +1994,Fla,79,F,19709,259 +1994,Fla,80,M,10845,208 +1994,Fla,80,F,18920,238 +1994,Fla,81,M,9790,189 +1994,Fla,81,F,17670,233 +1994,Fla,82,M,8169,158 +1994,Fla,82,F,15669,189 +1994,Fla,83,M,7257,105 +1994,Fla,83,F,14547,164 +1994,Fla,84,M,6172,117 +1994,Fla,84,F,12991,201 +1994,Fla,85,M,5114,94 +1994,Fla,85,F,11901,131 +1994,Fla,86,M,4398,69 +1994,Fla,86,F,10226,120 +1994,Fla,87,M,3455,62 +1994,Fla,87,F,8674,111 +1994,Fla,88,M,2714,54 +1994,Fla,88,F,7424,74 +1994,Fla,89,M,2207,43 +1994,Fla,89,F,6173,100 +1994,Fla,90,M,1659,22 +1994,Fla,90,F,4817,58 +1994,Fla,91,M,1187,15 +1994,Fla,91,F,3800,39 +1994,Fla,92,M,931,18 +1994,Fla,92,F,2939,37 +1994,Fla,93,M,589,10 +1994,Fla,93,F,2071,24 +1994,Fla,94,M,478,11 +1994,Fla,94,F,1473,20 +1994,Fla,95,M,316,4 +1994,Fla,95,F,1019,13 +1994,Fla,96,M,225,9 +1994,Fla,96,F,694,11 +1994,Fla,97,M,138,1 +1994,Fla,97,F,486,9 +1994,Fla,98,M,84,1 +1994,Fla,98,F,301,3 +1994,Fla,99,M,46,0 +1994,Fla,99,F,185,5 +1994,Fla,100,M,31,2 +1994,Fla,100,F,96,1 +1994,Fla,101,M,17,1 +1994,Fla,101,F,62,0 +1994,Fla,102,M,5,2 +1994,Fla,102,F,26,2 +1994,Fla,103,M,6,0 +1994,Fla,103,F,14,0 +1994,Fla,104,M,2,0 +1994,Fla,104,F,7,0 +1994,Fla,105,M,2,0 +1994,Fla,105,F,5,0 +1994,Fla,106,M,0,0 +1994,Fla,106,F,1,1 +1994,Fla,107,M,1,0 +1994,Fla,107,F,0,0 +1994,Fla,108,M,0,0 +1994,Fla,108,F,0,1 +1994,Fla,109,M,0,0 +1994,Fla,109,F,0,1 +1994,Fla,110,M,0,0 +1994,Fla,110,F,0,0 +1994,Fla,111,M,0,0 +1994,Fla,111,F,0,0 +1994,Fla,112,M,0,0 +1994,Fla,112,F,0,0 +1994,Fla,113,M,0,1 +1994,Fla,113,F,0,0 +1994,Fla,114,M,0,0 +1994,Fla,114,F,0,0 +1994,Fla,115,M,0,0 +1994,Fla,115,F,0,0 +1994,Fla,116,M,0,0 +1994,Fla,116,F,0,0 +1994,Fla,117,M,0,0 +1994,Fla,117,F,0,0 +1994,Fla,118,M,0,0 +1994,Fla,118,F,0,0 +1994,Fla,119,M,0,0 +1994,Fla,119,F,0,0 +1994,Fla,120,M,0,0 +1994,Fla,120,F,0,0 +1994,Wal,0,M,19044,1260 +1994,Wal,0,F,17917,1243 +1994,Wal,1,M,20100,1372 +1994,Wal,1,F,19168,1334 +1994,Wal,2,M,20734,1432 +1994,Wal,2,F,19940,1407 +1994,Wal,3,M,20547,1444 +1994,Wal,3,F,19693,1400 +1994,Wal,4,M,20629,1528 +1994,Wal,4,F,19616,1500 +1994,Wal,5,M,20495,1627 +1994,Wal,5,F,19439,1575 +1994,Wal,6,M,19698,1669 +1994,Wal,6,F,18804,1561 +1994,Wal,7,M,19721,1750 +1994,Wal,7,F,18704,1577 +1994,Wal,8,M,18992,1652 +1994,Wal,8,F,18093,1563 +1994,Wal,9,M,18678,1710 +1994,Wal,9,F,17983,1659 +1994,Wal,10,M,18662,1723 +1994,Wal,10,F,17283,1625 +1994,Wal,11,M,18835,1874 +1994,Wal,11,F,18028,1812 +1994,Wal,12,M,19030,1859 +1994,Wal,12,F,18511,1825 +1994,Wal,13,M,19027,2012 +1994,Wal,13,F,18460,1892 +1994,Wal,14,M,18741,2104 +1994,Wal,14,F,17684,1961 +1994,Wal,15,M,18384,2211 +1994,Wal,15,F,17674,2004 +1994,Wal,16,M,18722,2159 +1994,Wal,16,F,17736,2172 +1994,Wal,17,M,18848,2287 +1994,Wal,17,F,18134,2196 +1994,Wal,18,M,19089,2284 +1994,Wal,18,F,18420,2189 +1994,Wal,19,M,19841,2578 +1994,Wal,19,F,18860,2372 +1994,Wal,20,M,20501,2982 +1994,Wal,20,F,19643,2615 +1994,Wal,21,M,20986,3175 +1994,Wal,21,F,20197,2826 +1994,Wal,22,M,21247,3260 +1994,Wal,22,F,20682,2925 +1994,Wal,23,M,20659,3439 +1994,Wal,23,F,19841,2930 +1994,Wal,24,M,20304,3492 +1994,Wal,24,F,19769,3020 +1994,Wal,25,M,19627,3587 +1994,Wal,25,F,19394,3188 +1994,Wal,26,M,20012,3572 +1994,Wal,26,F,19487,2984 +1994,Wal,27,M,20213,4111 +1994,Wal,27,F,20088,3325 +1994,Wal,28,M,20931,4296 +1994,Wal,28,F,20867,3324 +1994,Wal,29,M,21843,4226 +1994,Wal,29,F,21817,3330 +1994,Wal,30,M,21564,4171 +1994,Wal,30,F,21877,3191 +1994,Wal,31,M,20924,4179 +1994,Wal,31,F,21466,3125 +1994,Wal,32,M,21681,4008 +1994,Wal,32,F,22227,3204 +1994,Wal,33,M,21558,4435 +1994,Wal,33,F,21823,3159 +1994,Wal,34,M,21942,4140 +1994,Wal,34,F,22770,3039 +1994,Wal,35,M,21588,4135 +1994,Wal,35,F,22320,2994 +1994,Wal,36,M,21520,4068 +1994,Wal,36,F,22001,2861 +1994,Wal,37,M,21041,4189 +1994,Wal,37,F,21856,2921 +1994,Wal,38,M,20946,3981 +1994,Wal,38,F,21914,2860 +1994,Wal,39,M,20907,3850 +1994,Wal,39,F,21755,2730 +1994,Wal,40,M,21024,3661 +1994,Wal,40,F,21590,2524 +1994,Wal,41,M,20911,3537 +1994,Wal,41,F,21348,2479 +1994,Wal,42,M,20315,3338 +1994,Wal,42,F,21082,2374 +1994,Wal,43,M,21159,3460 +1994,Wal,43,F,21301,2478 +1994,Wal,44,M,21077,3257 +1994,Wal,44,F,21372,2298 +1994,Wal,45,M,21695,3191 +1994,Wal,45,F,22081,2376 +1994,Wal,46,M,21829,3144 +1994,Wal,46,F,21919,2180 +1994,Wal,47,M,21227,2966 +1994,Wal,47,F,21837,2036 +1994,Wal,48,M,15819,2348 +1994,Wal,48,F,16700,1730 +1994,Wal,49,M,15862,2339 +1994,Wal,49,F,16384,1794 +1994,Wal,50,M,14835,2094 +1994,Wal,50,F,15519,1642 +1994,Wal,51,M,12920,2055 +1994,Wal,51,F,13558,1623 +1994,Wal,52,M,12033,1961 +1994,Wal,52,F,12897,1518 +1994,Wal,53,M,13443,2305 +1994,Wal,53,F,14402,1799 +1994,Wal,54,M,14654,2120 +1994,Wal,54,F,15938,1805 +1994,Wal,55,M,14900,1991 +1994,Wal,55,F,16329,1787 +1994,Wal,56,M,14239,2029 +1994,Wal,56,F,15347,1652 +1994,Wal,57,M,13919,1989 +1994,Wal,57,F,15416,1690 +1994,Wal,58,M,13778,1962 +1994,Wal,58,F,15452,1711 +1994,Wal,59,M,14535,1877 +1994,Wal,59,F,16115,1729 +1994,Wal,60,M,14642,1889 +1994,Wal,60,F,16282,1752 +1994,Wal,61,M,15440,2016 +1994,Wal,61,F,17744,1682 +1994,Wal,62,M,15981,1793 +1994,Wal,62,F,18306,1659 +1994,Wal,63,M,15810,1954 +1994,Wal,63,F,18431,1728 +1994,Wal,64,M,14902,1863 +1994,Wal,64,F,17680,1661 +1994,Wal,65,M,14580,1847 +1994,Wal,65,F,17938,1565 +1994,Wal,66,M,14277,1832 +1994,Wal,66,F,17489,1637 +1994,Wal,67,M,14021,1846 +1994,Wal,67,F,17698,1648 +1994,Wal,68,M,13940,1728 +1994,Wal,68,F,18192,1591 +1994,Wal,69,M,13380,1686 +1994,Wal,69,F,17817,1500 +1994,Wal,70,M,12691,1617 +1994,Wal,70,F,17360,1417 +1994,Wal,71,M,12350,1397 +1994,Wal,71,F,17299,1351 +1994,Wal,72,M,12114,1218 +1994,Wal,72,F,17615,1260 +1994,Wal,73,M,11323,1088 +1994,Wal,73,F,17079,1162 +1994,Wal,74,M,7897,643 +1994,Wal,74,F,12271,778 +1994,Wal,75,M,5257,486 +1994,Wal,75,F,8543,531 +1994,Wal,76,M,4681,427 +1994,Wal,76,F,8169,476 +1994,Wal,77,M,5087,404 +1994,Wal,77,F,8424,539 +1994,Wal,78,M,5533,423 +1994,Wal,78,F,9963,616 +1994,Wal,79,M,6023,448 +1994,Wal,79,F,11560,650 +1994,Wal,80,M,5408,415 +1994,Wal,80,F,10703,602 +1994,Wal,81,M,4651,364 +1994,Wal,81,F,10261,559 +1994,Wal,82,M,3815,276 +1994,Wal,82,F,8980,500 +1994,Wal,83,M,3437,195 +1994,Wal,83,F,8481,425 +1994,Wal,84,M,2870,152 +1994,Wal,84,F,7658,403 +1994,Wal,85,M,2371,146 +1994,Wal,85,F,6997,346 +1994,Wal,86,M,1990,96 +1994,Wal,86,F,6314,280 +1994,Wal,87,M,1611,89 +1994,Wal,87,F,5162,235 +1994,Wal,88,M,1244,73 +1994,Wal,88,F,4173,209 +1994,Wal,89,M,986,56 +1994,Wal,89,F,3602,189 +1994,Wal,90,M,750,45 +1994,Wal,90,F,2870,115 +1994,Wal,91,M,537,32 +1994,Wal,91,F,2246,112 +1994,Wal,92,M,425,25 +1994,Wal,92,F,1871,95 +1994,Wal,93,M,271,18 +1994,Wal,93,F,1271,72 +1994,Wal,94,M,186,7 +1994,Wal,94,F,850,36 +1994,Wal,95,M,120,11 +1994,Wal,95,F,621,24 +1994,Wal,96,M,69,6 +1994,Wal,96,F,395,27 +1994,Wal,97,M,60,9 +1994,Wal,97,F,299,11 +1994,Wal,98,M,16,0 +1994,Wal,98,F,189,4 +1994,Wal,99,M,18,2 +1994,Wal,99,F,118,7 +1994,Wal,100,M,12,1 +1994,Wal,100,F,57,2 +1994,Wal,101,M,2,1 +1994,Wal,101,F,46,3 +1994,Wal,102,M,1,0 +1994,Wal,102,F,17,1 +1994,Wal,103,M,2,0 +1994,Wal,103,F,10,2 +1994,Wal,104,M,1,0 +1994,Wal,104,F,2,2 +1994,Wal,105,M,0,0 +1994,Wal,105,F,5,0 +1994,Wal,106,M,0,0 +1994,Wal,106,F,0,0 +1994,Wal,107,M,0,0 +1994,Wal,107,F,0,0 +1994,Wal,108,M,0,0 +1994,Wal,108,F,0,0 +1994,Wal,109,M,0,0 +1994,Wal,109,F,0,0 +1994,Wal,110,M,0,0 +1994,Wal,110,F,0,0 +1994,Wal,111,M,0,0 +1994,Wal,111,F,0,0 +1994,Wal,112,M,0,0 +1994,Wal,112,F,0,0 +1994,Wal,113,M,0,0 +1994,Wal,113,F,0,0 +1994,Wal,114,M,0,0 +1994,Wal,114,F,0,0 +1994,Wal,115,M,0,0 +1994,Wal,115,F,0,0 +1994,Wal,116,M,0,0 +1994,Wal,116,F,0,0 +1994,Wal,117,M,0,0 +1994,Wal,117,F,0,0 +1994,Wal,118,M,0,0 +1994,Wal,118,F,0,0 +1994,Wal,119,M,0,0 +1994,Wal,119,F,0,0 +1994,Wal,120,M,0,0 +1994,Wal,120,F,0,0 +1995,BruCap,0,M,4395,2106 +1995,BruCap,0,F,3992,1971 +1995,BruCap,1,M,4169,2079 +1995,BruCap,1,F,3992,1967 +1995,BruCap,2,M,4133,2076 +1995,BruCap,2,F,4001,2028 +1995,BruCap,3,M,3994,2055 +1995,BruCap,3,F,3807,2013 +1995,BruCap,4,M,3889,2156 +1995,BruCap,4,F,3725,1988 +1995,BruCap,5,M,3677,2057 +1995,BruCap,5,F,3558,2037 +1995,BruCap,6,M,3643,2049 +1995,BruCap,6,F,3401,2026 +1995,BruCap,7,M,3511,2035 +1995,BruCap,7,F,3311,2021 +1995,BruCap,8,M,3405,2019 +1995,BruCap,8,F,3190,1912 +1995,BruCap,9,M,3257,2009 +1995,BruCap,9,F,3033,1832 +1995,BruCap,10,M,3327,1964 +1995,BruCap,10,F,3166,1947 +1995,BruCap,11,M,3307,1909 +1995,BruCap,11,F,3182,1809 +1995,BruCap,12,M,3391,1931 +1995,BruCap,12,F,3250,1819 +1995,BruCap,13,M,3436,2114 +1995,BruCap,13,F,3237,1994 +1995,BruCap,14,M,3242,2207 +1995,BruCap,14,F,3168,2144 +1995,BruCap,15,M,3122,2273 +1995,BruCap,15,F,2940,2176 +1995,BruCap,16,M,3006,2172 +1995,BruCap,16,F,3034,2255 +1995,BruCap,17,M,2999,2159 +1995,BruCap,17,F,2968,2169 +1995,BruCap,18,M,3221,2020 +1995,BruCap,18,F,3226,2005 +1995,BruCap,19,M,3542,1826 +1995,BruCap,19,F,3509,1867 +1995,BruCap,20,M,3476,2079 +1995,BruCap,20,F,3620,2039 +1995,BruCap,21,M,3836,2198 +1995,BruCap,21,F,4012,2309 +1995,BruCap,22,M,4035,2525 +1995,BruCap,22,F,4296,2516 +1995,BruCap,23,M,4395,2662 +1995,BruCap,23,F,4648,2701 +1995,BruCap,24,M,4535,2940 +1995,BruCap,24,F,4921,2824 +1995,BruCap,25,M,4775,3183 +1995,BruCap,25,F,4985,3013 +1995,BruCap,26,M,4863,3312 +1995,BruCap,26,F,4991,3064 +1995,BruCap,27,M,5004,3239 +1995,BruCap,27,F,5058,3082 +1995,BruCap,28,M,4855,3549 +1995,BruCap,28,F,4990,3293 +1995,BruCap,29,M,5031,3646 +1995,BruCap,29,F,4970,3325 +1995,BruCap,30,M,4919,3707 +1995,BruCap,30,F,4888,3374 +1995,BruCap,31,M,4868,3500 +1995,BruCap,31,F,4805,3123 +1995,BruCap,32,M,4497,3509 +1995,BruCap,32,F,4579,3032 +1995,BruCap,33,M,4460,3230 +1995,BruCap,33,F,4671,2912 +1995,BruCap,34,M,4426,3188 +1995,BruCap,34,F,4680,2952 +1995,BruCap,35,M,4498,2911 +1995,BruCap,35,F,4572,2671 +1995,BruCap,36,M,4272,2873 +1995,BruCap,36,F,4604,2574 +1995,BruCap,37,M,4309,2606 +1995,BruCap,37,F,4526,2417 +1995,BruCap,38,M,4137,2668 +1995,BruCap,38,F,4469,2436 +1995,BruCap,39,M,4143,2548 +1995,BruCap,39,F,4465,2339 +1995,BruCap,40,M,4181,2390 +1995,BruCap,40,F,4375,2214 +1995,BruCap,41,M,4197,2284 +1995,BruCap,41,F,4497,2050 +1995,BruCap,42,M,4192,2285 +1995,BruCap,42,F,4450,2032 +1995,BruCap,43,M,4058,2052 +1995,BruCap,43,F,4424,1770 +1995,BruCap,44,M,3979,2137 +1995,BruCap,44,F,4529,1921 +1995,BruCap,45,M,4025,1915 +1995,BruCap,45,F,4537,1655 +1995,BruCap,46,M,4157,1914 +1995,BruCap,46,F,4587,1651 +1995,BruCap,47,M,4191,1864 +1995,BruCap,47,F,4786,1554 +1995,BruCap,48,M,4339,1737 +1995,BruCap,48,F,4717,1514 +1995,BruCap,49,M,3617,1590 +1995,BruCap,49,F,4063,1382 +1995,BruCap,50,M,3804,1594 +1995,BruCap,50,F,4367,1383 +1995,BruCap,51,M,3681,1471 +1995,BruCap,51,F,4144,1276 +1995,BruCap,52,M,3139,1513 +1995,BruCap,52,F,3564,1230 +1995,BruCap,53,M,2786,1292 +1995,BruCap,53,F,3226,1113 +1995,BruCap,54,M,3116,1597 +1995,BruCap,54,F,3519,1395 +1995,BruCap,55,M,3320,1429 +1995,BruCap,55,F,3925,1183 +1995,BruCap,56,M,3275,1441 +1995,BruCap,56,F,3832,1115 +1995,BruCap,57,M,3274,1325 +1995,BruCap,57,F,3829,1081 +1995,BruCap,58,M,3187,1340 +1995,BruCap,58,F,3789,1097 +1995,BruCap,59,M,3175,1189 +1995,BruCap,59,F,3902,1068 +1995,BruCap,60,M,3342,1172 +1995,BruCap,60,F,3916,941 +1995,BruCap,61,M,3303,1066 +1995,BruCap,61,F,4075,834 +1995,BruCap,62,M,3467,1097 +1995,BruCap,62,F,4328,846 +1995,BruCap,63,M,3553,918 +1995,BruCap,63,F,4449,767 +1995,BruCap,64,M,3482,1025 +1995,BruCap,64,F,4827,821 +1995,BruCap,65,M,3386,833 +1995,BruCap,65,F,4574,633 +1995,BruCap,66,M,3345,752 +1995,BruCap,66,F,4517,663 +1995,BruCap,67,M,3256,664 +1995,BruCap,67,F,4590,560 +1995,BruCap,68,M,3289,608 +1995,BruCap,68,F,4763,554 +1995,BruCap,69,M,3327,551 +1995,BruCap,69,F,4913,499 +1995,BruCap,70,M,3462,436 +1995,BruCap,70,F,5014,474 +1995,BruCap,71,M,3252,463 +1995,BruCap,71,F,5201,450 +1995,BruCap,72,M,3204,393 +1995,BruCap,72,F,5123,399 +1995,BruCap,73,M,3365,378 +1995,BruCap,73,F,5244,353 +1995,BruCap,74,M,3181,336 +1995,BruCap,74,F,5330,423 +1995,BruCap,75,M,2338,196 +1995,BruCap,75,F,3780,272 +1995,BruCap,76,M,1426,167 +1995,BruCap,76,F,2761,208 +1995,BruCap,77,M,1381,156 +1995,BruCap,77,F,2652,207 +1995,BruCap,78,M,1392,123 +1995,BruCap,78,F,2847,191 +1995,BruCap,79,M,1652,130 +1995,BruCap,79,F,3401,197 +1995,BruCap,80,M,1816,145 +1995,BruCap,80,F,3921,194 +1995,BruCap,81,M,1633,120 +1995,BruCap,81,F,3645,190 +1995,BruCap,82,M,1443,93 +1995,BruCap,82,F,3489,201 +1995,BruCap,83,M,1216,92 +1995,BruCap,83,F,3130,148 +1995,BruCap,84,M,1067,85 +1995,BruCap,84,F,2988,170 +1995,BruCap,85,M,892,54 +1995,BruCap,85,F,2527,144 +1995,BruCap,86,M,749,64 +1995,BruCap,86,F,2423,106 +1995,BruCap,87,M,633,54 +1995,BruCap,87,F,2100,107 +1995,BruCap,88,M,504,42 +1995,BruCap,88,F,1755,91 +1995,BruCap,89,M,402,27 +1995,BruCap,89,F,1493,93 +1995,BruCap,90,M,317,36 +1995,BruCap,90,F,1230,61 +1995,BruCap,91,M,249,7 +1995,BruCap,91,F,956,53 +1995,BruCap,92,M,186,13 +1995,BruCap,92,F,851,37 +1995,BruCap,93,M,137,15 +1995,BruCap,93,F,603,38 +1995,BruCap,94,M,79,12 +1995,BruCap,94,F,429,32 +1995,BruCap,95,M,59,7 +1995,BruCap,95,F,347,12 +1995,BruCap,96,M,39,5 +1995,BruCap,96,F,217,19 +1995,BruCap,97,M,19,3 +1995,BruCap,97,F,137,12 +1995,BruCap,98,M,22,0 +1995,BruCap,98,F,99,6 +1995,BruCap,99,M,8,1 +1995,BruCap,99,F,80,7 +1995,BruCap,100,M,8,0 +1995,BruCap,100,F,42,3 +1995,BruCap,101,M,5,0 +1995,BruCap,101,F,23,2 +1995,BruCap,102,M,3,2 +1995,BruCap,102,F,17,1 +1995,BruCap,103,M,0,0 +1995,BruCap,103,F,7,1 +1995,BruCap,104,M,1,0 +1995,BruCap,104,F,4,0 +1995,BruCap,105,M,0,0 +1995,BruCap,105,F,4,0 +1995,BruCap,106,M,0,0 +1995,BruCap,106,F,1,0 +1995,BruCap,107,M,0,0 +1995,BruCap,107,F,1,0 +1995,BruCap,108,M,0,0 +1995,BruCap,108,F,0,0 +1995,BruCap,109,M,0,0 +1995,BruCap,109,F,0,0 +1995,BruCap,110,M,0,0 +1995,BruCap,110,F,0,2 +1995,BruCap,111,M,0,0 +1995,BruCap,111,F,0,0 +1995,BruCap,112,M,0,0 +1995,BruCap,112,F,0,0 +1995,BruCap,113,M,0,0 +1995,BruCap,113,F,0,0 +1995,BruCap,114,M,0,0 +1995,BruCap,114,F,0,0 +1995,BruCap,115,M,0,0 +1995,BruCap,115,F,0,0 +1995,BruCap,116,M,0,0 +1995,BruCap,116,F,0,0 +1995,BruCap,117,M,0,0 +1995,BruCap,117,F,0,0 +1995,BruCap,118,M,0,0 +1995,BruCap,118,F,0,0 +1995,BruCap,119,M,0,0 +1995,BruCap,119,F,0,0 +1995,BruCap,120,M,0,0 +1995,BruCap,120,F,0,0 +1995,Fla,0,M,31298,2049 +1995,Fla,0,F,29819,1809 +1995,Fla,1,M,32824,2030 +1995,Fla,1,F,31768,1961 +1995,Fla,2,M,34115,2027 +1995,Fla,2,F,32614,2043 +1995,Fla,3,M,34608,2116 +1995,Fla,3,F,32878,1982 +1995,Fla,4,M,34273,2061 +1995,Fla,4,F,32577,2050 +1995,Fla,5,M,33186,2057 +1995,Fla,5,F,31571,1952 +1995,Fla,6,M,32762,2077 +1995,Fla,6,F,31307,1940 +1995,Fla,7,M,32545,2004 +1995,Fla,7,F,30794,1926 +1995,Fla,8,M,32664,2002 +1995,Fla,8,F,30841,1791 +1995,Fla,9,M,31753,1946 +1995,Fla,9,F,30327,1861 +1995,Fla,10,M,32511,1928 +1995,Fla,10,F,31000,1824 +1995,Fla,11,M,33586,1838 +1995,Fla,11,F,32121,1881 +1995,Fla,12,M,34588,1833 +1995,Fla,12,F,32652,1816 +1995,Fla,13,M,35686,1970 +1995,Fla,13,F,33374,1985 +1995,Fla,14,M,35099,2230 +1995,Fla,14,F,33656,2082 +1995,Fla,15,M,35579,2244 +1995,Fla,15,F,33391,2126 +1995,Fla,16,M,34754,2139 +1995,Fla,16,F,33280,2107 +1995,Fla,17,M,34133,2100 +1995,Fla,17,F,32834,2181 +1995,Fla,18,M,33851,1815 +1995,Fla,18,F,32209,1925 +1995,Fla,19,M,33193,1719 +1995,Fla,19,F,31455,1885 +1995,Fla,20,M,34452,1891 +1995,Fla,20,F,32986,2073 +1995,Fla,21,M,35797,2122 +1995,Fla,21,F,34149,2185 +1995,Fla,22,M,37400,2223 +1995,Fla,22,F,35924,2360 +1995,Fla,23,M,38833,2531 +1995,Fla,23,F,37762,2540 +1995,Fla,24,M,39992,2725 +1995,Fla,24,F,38324,2645 +1995,Fla,25,M,39881,2924 +1995,Fla,25,F,38278,2728 +1995,Fla,26,M,40257,2992 +1995,Fla,26,F,38720,2694 +1995,Fla,27,M,41773,2968 +1995,Fla,27,F,39701,2662 +1995,Fla,28,M,42983,3423 +1995,Fla,28,F,41479,2972 +1995,Fla,29,M,44584,3380 +1995,Fla,29,F,42723,2756 +1995,Fla,30,M,46388,3476 +1995,Fla,30,F,45077,2870 +1995,Fla,31,M,46268,3281 +1995,Fla,31,F,44722,2720 +1995,Fla,32,M,45748,3415 +1995,Fla,32,F,44195,2538 +1995,Fla,33,M,45632,3145 +1995,Fla,33,F,44627,2393 +1995,Fla,34,M,44599,3384 +1995,Fla,34,F,43441,2597 +1995,Fla,35,M,45590,2985 +1995,Fla,35,F,44414,2390 +1995,Fla,36,M,44817,3073 +1995,Fla,36,F,43219,2241 +1995,Fla,37,M,44341,2880 +1995,Fla,37,F,42761,2017 +1995,Fla,38,M,43005,2816 +1995,Fla,38,F,42159,2140 +1995,Fla,39,M,42551,2747 +1995,Fla,39,F,41830,1942 +1995,Fla,40,M,41866,2615 +1995,Fla,40,F,40789,1898 +1995,Fla,41,M,41064,2356 +1995,Fla,41,F,39552,1777 +1995,Fla,42,M,41066,2422 +1995,Fla,42,F,39383,1686 +1995,Fla,43,M,39139,2314 +1995,Fla,43,F,37972,1560 +1995,Fla,44,M,38572,2455 +1995,Fla,44,F,37867,1646 +1995,Fla,45,M,38942,2407 +1995,Fla,45,F,37650,1619 +1995,Fla,46,M,38884,2302 +1995,Fla,46,F,38233,1497 +1995,Fla,47,M,38713,2190 +1995,Fla,47,F,37808,1494 +1995,Fla,48,M,39736,2173 +1995,Fla,48,F,38394,1394 +1995,Fla,49,M,35361,1864 +1995,Fla,49,F,34715,1278 +1995,Fla,50,M,35098,1855 +1995,Fla,50,F,34503,1331 +1995,Fla,51,M,33614,1836 +1995,Fla,51,F,33117,1217 +1995,Fla,52,M,29342,1709 +1995,Fla,52,F,28848,1222 +1995,Fla,53,M,26341,1679 +1995,Fla,53,F,26592,1084 +1995,Fla,54,M,29104,1818 +1995,Fla,54,F,29515,1285 +1995,Fla,55,M,31870,1700 +1995,Fla,55,F,33055,1077 +1995,Fla,56,M,33003,1627 +1995,Fla,56,F,33757,1097 +1995,Fla,57,M,32005,1516 +1995,Fla,57,F,32598,1016 +1995,Fla,58,M,30971,1433 +1995,Fla,58,F,32117,944 +1995,Fla,59,M,30876,1365 +1995,Fla,59,F,32121,900 +1995,Fla,60,M,30942,1337 +1995,Fla,60,F,32820,934 +1995,Fla,61,M,31077,1291 +1995,Fla,61,F,32713,879 +1995,Fla,62,M,31669,1253 +1995,Fla,62,F,34128,821 +1995,Fla,63,M,31481,1101 +1995,Fla,63,F,34192,686 +1995,Fla,64,M,30834,1126 +1995,Fla,64,F,34034,774 +1995,Fla,65,M,28466,969 +1995,Fla,65,F,31856,691 +1995,Fla,66,M,27489,919 +1995,Fla,66,F,31116,685 +1995,Fla,67,M,26410,855 +1995,Fla,67,F,29968,611 +1995,Fla,68,M,25714,785 +1995,Fla,68,F,30458,635 +1995,Fla,69,M,25432,761 +1995,Fla,69,F,30053,619 +1995,Fla,70,M,24324,746 +1995,Fla,70,F,29416,552 +1995,Fla,71,M,23447,702 +1995,Fla,71,F,29170,567 +1995,Fla,72,M,21560,598 +1995,Fla,72,F,27498,503 +1995,Fla,73,M,20632,588 +1995,Fla,73,F,27253,485 +1995,Fla,74,M,19632,506 +1995,Fla,74,F,26483,458 +1995,Fla,75,M,14475,397 +1995,Fla,75,F,19901,298 +1995,Fla,76,M,9175,294 +1995,Fla,76,F,13618,272 +1995,Fla,77,M,8529,269 +1995,Fla,77,F,13278,241 +1995,Fla,78,M,9352,245 +1995,Fla,78,F,14594,255 +1995,Fla,79,M,10582,235 +1995,Fla,79,F,16945,252 +1995,Fla,80,M,10921,227 +1995,Fla,80,F,18777,248 +1995,Fla,81,M,9794,185 +1995,Fla,81,F,17842,238 +1995,Fla,82,M,8781,162 +1995,Fla,82,F,16555,207 +1995,Fla,83,M,7230,144 +1995,Fla,83,F,14562,175 +1995,Fla,84,M,6382,94 +1995,Fla,84,F,13358,156 +1995,Fla,85,M,5347,100 +1995,Fla,85,F,11772,185 +1995,Fla,86,M,4358,80 +1995,Fla,86,F,10633,120 +1995,Fla,87,M,3685,53 +1995,Fla,87,F,9051,111 +1995,Fla,88,M,2881,53 +1995,Fla,88,F,7554,90 +1995,Fla,89,M,2183,43 +1995,Fla,89,F,6385,62 +1995,Fla,90,M,1746,32 +1995,Fla,90,F,5237,87 +1995,Fla,91,M,1301,15 +1995,Fla,91,F,3953,45 +1995,Fla,92,M,899,12 +1995,Fla,92,F,3057,33 +1995,Fla,93,M,679,15 +1995,Fla,93,F,2340,31 +1995,Fla,94,M,425,10 +1995,Fla,94,F,1582,18 +1995,Fla,95,M,344,9 +1995,Fla,95,F,1089,16 +1995,Fla,96,M,211,2 +1995,Fla,96,F,724,11 +1995,Fla,97,M,147,8 +1995,Fla,97,F,501,8 +1995,Fla,98,M,85,1 +1995,Fla,98,F,335,8 +1995,Fla,99,M,43,1 +1995,Fla,99,F,213,2 +1995,Fla,100,M,26,0 +1995,Fla,100,F,112,3 +1995,Fla,101,M,22,2 +1995,Fla,101,F,65,0 +1995,Fla,102,M,8,0 +1995,Fla,102,F,37,0 +1995,Fla,103,M,5,2 +1995,Fla,103,F,13,1 +1995,Fla,104,M,2,0 +1995,Fla,104,F,3,0 +1995,Fla,105,M,0,0 +1995,Fla,105,F,3,0 +1995,Fla,106,M,0,0 +1995,Fla,106,F,3,0 +1995,Fla,107,M,0,0 +1995,Fla,107,F,1,1 +1995,Fla,108,M,0,0 +1995,Fla,108,F,0,0 +1995,Fla,109,M,0,0 +1995,Fla,109,F,0,0 +1995,Fla,110,M,0,0 +1995,Fla,110,F,0,1 +1995,Fla,111,M,0,0 +1995,Fla,111,F,0,0 +1995,Fla,112,M,0,0 +1995,Fla,112,F,0,0 +1995,Fla,113,M,0,0 +1995,Fla,113,F,0,0 +1995,Fla,114,M,0,1 +1995,Fla,114,F,0,0 +1995,Fla,115,M,0,0 +1995,Fla,115,F,0,0 +1995,Fla,116,M,0,0 +1995,Fla,116,F,0,0 +1995,Fla,117,M,0,0 +1995,Fla,117,F,0,0 +1995,Fla,118,M,0,0 +1995,Fla,118,F,0,0 +1995,Fla,119,M,0,0 +1995,Fla,119,F,0,0 +1995,Fla,120,M,0,0 +1995,Fla,120,F,0,0 +1995,Wal,0,M,18292,1197 +1995,Wal,0,F,17424,1102 +1995,Wal,1,M,19265,1284 +1995,Wal,1,F,18113,1309 +1995,Wal,2,M,20305,1375 +1995,Wal,2,F,19380,1357 +1995,Wal,3,M,20913,1423 +1995,Wal,3,F,20105,1423 +1995,Wal,4,M,20667,1461 +1995,Wal,4,F,19849,1368 +1995,Wal,5,M,20741,1527 +1995,Wal,5,F,19753,1488 +1995,Wal,6,M,20628,1617 +1995,Wal,6,F,19538,1548 +1995,Wal,7,M,19827,1635 +1995,Wal,7,F,18920,1543 +1995,Wal,8,M,19857,1694 +1995,Wal,8,F,18822,1565 +1995,Wal,9,M,19109,1620 +1995,Wal,9,F,18204,1549 +1995,Wal,10,M,18810,1648 +1995,Wal,10,F,18095,1624 +1995,Wal,11,M,18789,1674 +1995,Wal,11,F,17389,1584 +1995,Wal,12,M,19025,1777 +1995,Wal,12,F,18162,1716 +1995,Wal,13,M,19110,1835 +1995,Wal,13,F,18571,1812 +1995,Wal,14,M,19092,1970 +1995,Wal,14,F,18542,1877 +1995,Wal,15,M,18818,2098 +1995,Wal,15,F,17758,1916 +1995,Wal,16,M,18435,2176 +1995,Wal,16,F,17732,2023 +1995,Wal,17,M,18750,2165 +1995,Wal,17,F,17791,2218 +1995,Wal,18,M,19062,2132 +1995,Wal,18,F,18281,2107 +1995,Wal,19,M,19230,2124 +1995,Wal,19,F,18581,2091 +1995,Wal,20,M,19917,2498 +1995,Wal,20,F,18977,2321 +1995,Wal,21,M,20594,2827 +1995,Wal,21,F,19740,2533 +1995,Wal,22,M,21045,3061 +1995,Wal,22,F,20209,2815 +1995,Wal,23,M,21254,3160 +1995,Wal,23,F,20537,2897 +1995,Wal,24,M,20549,3355 +1995,Wal,24,F,19788,2903 +1995,Wal,25,M,20214,3411 +1995,Wal,25,F,19633,3017 +1995,Wal,26,M,19568,3540 +1995,Wal,26,F,19381,3138 +1995,Wal,27,M,20002,3455 +1995,Wal,27,F,19546,2966 +1995,Wal,28,M,20260,4012 +1995,Wal,28,F,20204,3285 +1995,Wal,29,M,21054,4144 +1995,Wal,29,F,20976,3310 +1995,Wal,30,M,21995,4052 +1995,Wal,30,F,22000,3288 +1995,Wal,31,M,21658,4104 +1995,Wal,31,F,22019,3186 +1995,Wal,32,M,21054,4069 +1995,Wal,32,F,21617,3150 +1995,Wal,33,M,21764,3927 +1995,Wal,33,F,22325,3227 +1995,Wal,34,M,21721,4314 +1995,Wal,34,F,21933,3121 +1995,Wal,35,M,22034,4051 +1995,Wal,35,F,22808,3063 +1995,Wal,36,M,21676,4028 +1995,Wal,36,F,22427,2986 +1995,Wal,37,M,21562,3969 +1995,Wal,37,F,22051,2859 +1995,Wal,38,M,21116,4081 +1995,Wal,38,F,21927,2901 +1995,Wal,39,M,20969,3904 +1995,Wal,39,F,21949,2848 +1995,Wal,40,M,20923,3784 +1995,Wal,40,F,21789,2718 +1995,Wal,41,M,21073,3591 +1995,Wal,41,F,21617,2493 +1995,Wal,42,M,20934,3456 +1995,Wal,42,F,21357,2488 +1995,Wal,43,M,20303,3296 +1995,Wal,43,F,21082,2366 +1995,Wal,44,M,21130,3357 +1995,Wal,44,F,21286,2468 +1995,Wal,45,M,21056,3212 +1995,Wal,45,F,21339,2258 +1995,Wal,46,M,21622,3153 +1995,Wal,46,F,22072,2367 +1995,Wal,47,M,21739,3112 +1995,Wal,47,F,21912,2188 +1995,Wal,48,M,21165,2916 +1995,Wal,48,F,21786,2036 +1995,Wal,49,M,15737,2333 +1995,Wal,49,F,16697,1704 +1995,Wal,50,M,15806,2312 +1995,Wal,50,F,16365,1779 +1995,Wal,51,M,14761,2074 +1995,Wal,51,F,15466,1638 +1995,Wal,52,M,12865,2006 +1995,Wal,52,F,13539,1613 +1995,Wal,53,M,11989,1943 +1995,Wal,53,F,12840,1506 +1995,Wal,54,M,13358,2275 +1995,Wal,54,F,14368,1780 +1995,Wal,55,M,14553,2080 +1995,Wal,55,F,15901,1796 +1995,Wal,56,M,14788,1941 +1995,Wal,56,F,16297,1771 +1995,Wal,57,M,14158,1996 +1995,Wal,57,F,15310,1638 +1995,Wal,58,M,13779,1965 +1995,Wal,58,F,15365,1674 +1995,Wal,59,M,13605,1937 +1995,Wal,59,F,15387,1695 +1995,Wal,60,M,14352,1836 +1995,Wal,60,F,16039,1717 +1995,Wal,61,M,14427,1852 +1995,Wal,61,F,16203,1729 +1995,Wal,62,M,15208,1973 +1995,Wal,62,F,17620,1657 +1995,Wal,63,M,15695,1765 +1995,Wal,63,F,18196,1637 +1995,Wal,64,M,15502,1915 +1995,Wal,64,F,18298,1709 +1995,Wal,65,M,14553,1789 +1995,Wal,65,F,17499,1640 +1995,Wal,66,M,14179,1772 +1995,Wal,66,F,17760,1543 +1995,Wal,67,M,13843,1771 +1995,Wal,67,F,17302,1616 +1995,Wal,68,M,13583,1789 +1995,Wal,68,F,17472,1631 +1995,Wal,69,M,13489,1645 +1995,Wal,69,F,17932,1575 +1995,Wal,70,M,12916,1612 +1995,Wal,70,F,17515,1459 +1995,Wal,71,M,12153,1534 +1995,Wal,71,F,17041,1391 +1995,Wal,72,M,11800,1327 +1995,Wal,72,F,16942,1320 +1995,Wal,73,M,11528,1149 +1995,Wal,73,F,17197,1231 +1995,Wal,74,M,10752,1020 +1995,Wal,74,F,16680,1114 +1995,Wal,75,M,7425,586 +1995,Wal,75,F,11917,750 +1995,Wal,76,M,4900,456 +1995,Wal,76,F,8271,514 +1995,Wal,77,M,4350,394 +1995,Wal,77,F,7860,466 +1995,Wal,78,M,4698,363 +1995,Wal,78,F,8132,519 +1995,Wal,79,M,5054,386 +1995,Wal,79,F,9539,589 +1995,Wal,80,M,5494,413 +1995,Wal,80,F,11009,629 +1995,Wal,81,M,4850,373 +1995,Wal,81,F,10106,578 +1995,Wal,82,M,4120,334 +1995,Wal,82,F,9570,519 +1995,Wal,83,M,3375,233 +1995,Wal,83,F,8302,470 +1995,Wal,84,M,3008,169 +1995,Wal,84,F,7731,411 +1995,Wal,85,M,2447,128 +1995,Wal,85,F,6890,370 +1995,Wal,86,M,1960,134 +1995,Wal,86,F,6218,316 +1995,Wal,87,M,1635,79 +1995,Wal,87,F,5534,245 +1995,Wal,88,M,1274,78 +1995,Wal,88,F,4472,205 +1995,Wal,89,M,1025,59 +1995,Wal,89,F,3568,181 +1995,Wal,90,M,753,41 +1995,Wal,90,F,3037,159 +1995,Wal,91,M,578,37 +1995,Wal,91,F,2346,98 +1995,Wal,92,M,411,23 +1995,Wal,92,F,1784,104 +1995,Wal,93,M,300,23 +1995,Wal,93,F,1437,74 +1995,Wal,94,M,202,12 +1995,Wal,94,F,972,57 +1995,Wal,95,M,132,6 +1995,Wal,95,F,643,28 +1995,Wal,96,M,84,9 +1995,Wal,96,F,442,17 +1995,Wal,97,M,46,5 +1995,Wal,97,F,276,17 +1995,Wal,98,M,38,6 +1995,Wal,98,F,208,10 +1995,Wal,99,M,12,0 +1995,Wal,99,F,138,3 +1995,Wal,100,M,9,1 +1995,Wal,100,F,73,5 +1995,Wal,101,M,6,1 +1995,Wal,101,F,37,1 +1995,Wal,102,M,1,1 +1995,Wal,102,F,29,2 +1995,Wal,103,M,0,0 +1995,Wal,103,F,14,0 +1995,Wal,104,M,2,0 +1995,Wal,104,F,6,1 +1995,Wal,105,M,0,0 +1995,Wal,105,F,2,1 +1995,Wal,106,M,0,0 +1995,Wal,106,F,3,0 +1995,Wal,107,M,0,0 +1995,Wal,107,F,0,0 +1995,Wal,108,M,0,0 +1995,Wal,108,F,0,0 +1995,Wal,109,M,0,0 +1995,Wal,109,F,0,0 +1995,Wal,110,M,0,0 +1995,Wal,110,F,0,0 +1995,Wal,111,M,0,0 +1995,Wal,111,F,0,0 +1995,Wal,112,M,0,0 +1995,Wal,112,F,0,0 +1995,Wal,113,M,0,0 +1995,Wal,113,F,0,0 +1995,Wal,114,M,0,0 +1995,Wal,114,F,0,0 +1995,Wal,115,M,0,0 +1995,Wal,115,F,0,0 +1995,Wal,116,M,0,0 +1995,Wal,116,F,0,0 +1995,Wal,117,M,0,0 +1995,Wal,117,F,0,0 +1995,Wal,118,M,0,0 +1995,Wal,118,F,0,0 +1995,Wal,119,M,0,0 +1995,Wal,119,F,0,0 +1995,Wal,120,M,0,0 +1995,Wal,120,F,0,0 +1996,BruCap,0,M,4299,2075 +1996,BruCap,0,F,4206,1824 +1996,BruCap,1,M,4312,2031 +1996,BruCap,1,F,3878,1914 +1996,BruCap,2,M,4111,1961 +1996,BruCap,2,F,3895,1876 +1996,BruCap,3,M,4030,2024 +1996,BruCap,3,F,3921,1936 +1996,BruCap,4,M,3969,1964 +1996,BruCap,4,F,3793,1907 +1996,BruCap,5,M,3870,2067 +1996,BruCap,5,F,3711,1908 +1996,BruCap,6,M,3671,1953 +1996,BruCap,6,F,3601,1913 +1996,BruCap,7,M,3686,1942 +1996,BruCap,7,F,3432,1908 +1996,BruCap,8,M,3583,1907 +1996,BruCap,8,F,3407,1871 +1996,BruCap,9,M,3456,1878 +1996,BruCap,9,F,3274,1763 +1996,BruCap,10,M,3371,1868 +1996,BruCap,10,F,3091,1730 +1996,BruCap,11,M,3471,1763 +1996,BruCap,11,F,3272,1794 +1996,BruCap,12,M,3525,1627 +1996,BruCap,12,F,3375,1594 +1996,BruCap,13,M,3458,1854 +1996,BruCap,13,F,3281,1746 +1996,BruCap,14,M,3439,2082 +1996,BruCap,14,F,3261,1943 +1996,BruCap,15,M,3246,2150 +1996,BruCap,15,F,3187,2112 +1996,BruCap,16,M,3158,2212 +1996,BruCap,16,F,2968,2131 +1996,BruCap,17,M,3049,2138 +1996,BruCap,17,F,3085,2250 +1996,BruCap,18,M,3384,1855 +1996,BruCap,18,F,3348,1952 +1996,BruCap,19,M,3537,1826 +1996,BruCap,19,F,3585,1875 +1996,BruCap,20,M,3726,1807 +1996,BruCap,20,F,3743,1950 +1996,BruCap,21,M,3691,2113 +1996,BruCap,21,F,3814,2184 +1996,BruCap,22,M,4056,2204 +1996,BruCap,22,F,4240,2382 +1996,BruCap,23,M,4300,2546 +1996,BruCap,23,F,4594,2675 +1996,BruCap,24,M,4677,2754 +1996,BruCap,24,F,4914,2847 +1996,BruCap,25,M,4768,3028 +1996,BruCap,25,F,5110,2878 +1996,BruCap,26,M,4891,3219 +1996,BruCap,26,F,5042,3150 +1996,BruCap,27,M,4940,3304 +1996,BruCap,27,F,4953,3133 +1996,BruCap,28,M,5000,3310 +1996,BruCap,28,F,4906,3112 +1996,BruCap,29,M,4833,3594 +1996,BruCap,29,F,4859,3251 +1996,BruCap,30,M,4949,3585 +1996,BruCap,30,F,4838,3292 +1996,BruCap,31,M,4841,3653 +1996,BruCap,31,F,4771,3344 +1996,BruCap,32,M,4697,3392 +1996,BruCap,32,F,4684,3057 +1996,BruCap,33,M,4387,3415 +1996,BruCap,33,F,4479,2957 +1996,BruCap,34,M,4356,3118 +1996,BruCap,34,F,4577,2858 +1996,BruCap,35,M,4399,3112 +1996,BruCap,35,F,4584,2892 +1996,BruCap,36,M,4494,2805 +1996,BruCap,36,F,4503,2618 +1996,BruCap,37,M,4208,2750 +1996,BruCap,37,F,4532,2503 +1996,BruCap,38,M,4247,2494 +1996,BruCap,38,F,4485,2366 +1996,BruCap,39,M,4109,2579 +1996,BruCap,39,F,4427,2377 +1996,BruCap,40,M,4096,2463 +1996,BruCap,40,F,4436,2310 +1996,BruCap,41,M,4116,2284 +1996,BruCap,41,F,4330,2171 +1996,BruCap,42,M,4163,2174 +1996,BruCap,42,F,4456,2018 +1996,BruCap,43,M,4218,2210 +1996,BruCap,43,F,4416,2004 +1996,BruCap,44,M,4038,1964 +1996,BruCap,44,F,4412,1756 +1996,BruCap,45,M,3967,2099 +1996,BruCap,45,F,4486,1901 +1996,BruCap,46,M,4004,1861 +1996,BruCap,46,F,4515,1628 +1996,BruCap,47,M,4142,1840 +1996,BruCap,47,F,4541,1632 +1996,BruCap,48,M,4173,1812 +1996,BruCap,48,F,4768,1529 +1996,BruCap,49,M,4290,1677 +1996,BruCap,49,F,4664,1504 +1996,BruCap,50,M,3556,1541 +1996,BruCap,50,F,4028,1361 +1996,BruCap,51,M,3736,1583 +1996,BruCap,51,F,4330,1370 +1996,BruCap,52,M,3654,1409 +1996,BruCap,52,F,4105,1255 +1996,BruCap,53,M,3097,1477 +1996,BruCap,53,F,3541,1222 +1996,BruCap,54,M,2765,1261 +1996,BruCap,54,F,3197,1079 +1996,BruCap,55,M,3081,1560 +1996,BruCap,55,F,3476,1369 +1996,BruCap,56,M,3261,1387 +1996,BruCap,56,F,3856,1166 +1996,BruCap,57,M,3216,1381 +1996,BruCap,57,F,3777,1096 +1996,BruCap,58,M,3195,1299 +1996,BruCap,58,F,3756,1058 +1996,BruCap,59,M,3096,1300 +1996,BruCap,59,F,3728,1084 +1996,BruCap,60,M,3102,1153 +1996,BruCap,60,F,3810,1035 +1996,BruCap,61,M,3263,1134 +1996,BruCap,61,F,3825,905 +1996,BruCap,62,M,3178,1018 +1996,BruCap,62,F,3993,796 +1996,BruCap,63,M,3355,1055 +1996,BruCap,63,F,4240,816 +1996,BruCap,64,M,3435,876 +1996,BruCap,64,F,4364,739 +1996,BruCap,65,M,3342,944 +1996,BruCap,65,F,4731,800 +1996,BruCap,66,M,3241,788 +1996,BruCap,66,F,4476,602 +1996,BruCap,67,M,3249,703 +1996,BruCap,67,F,4431,631 +1996,BruCap,68,M,3131,613 +1996,BruCap,68,F,4519,540 +1996,BruCap,69,M,3176,576 +1996,BruCap,69,F,4677,519 +1996,BruCap,70,M,3211,525 +1996,BruCap,70,F,4807,481 +1996,BruCap,71,M,3292,409 +1996,BruCap,71,F,4897,454 +1996,BruCap,72,M,3094,435 +1996,BruCap,72,F,5063,420 +1996,BruCap,73,M,3055,364 +1996,BruCap,73,F,4988,385 +1996,BruCap,74,M,3213,348 +1996,BruCap,74,F,5102,331 +1996,BruCap,75,M,3002,308 +1996,BruCap,75,F,5169,408 +1996,BruCap,76,M,2190,179 +1996,BruCap,76,F,3632,257 +1996,BruCap,77,M,1333,151 +1996,BruCap,77,F,2661,191 +1996,BruCap,78,M,1289,137 +1996,BruCap,78,F,2556,195 +1996,BruCap,79,M,1301,105 +1996,BruCap,79,F,2731,182 +1996,BruCap,80,M,1514,111 +1996,BruCap,80,F,3222,179 +1996,BruCap,81,M,1659,129 +1996,BruCap,81,F,3708,190 +1996,BruCap,82,M,1470,106 +1996,BruCap,82,F,3433,182 +1996,BruCap,83,M,1281,82 +1996,BruCap,83,F,3223,185 +1996,BruCap,84,M,1084,82 +1996,BruCap,84,F,2873,130 +1996,BruCap,85,M,920,76 +1996,BruCap,85,F,2726,152 +1996,BruCap,86,M,753,47 +1996,BruCap,86,F,2277,132 +1996,BruCap,87,M,656,54 +1996,BruCap,87,F,2133,94 +1996,BruCap,88,M,505,46 +1996,BruCap,88,F,1826,93 +1996,BruCap,89,M,403,30 +1996,BruCap,89,F,1499,79 +1996,BruCap,90,M,306,23 +1996,BruCap,90,F,1269,75 +1996,BruCap,91,M,259,23 +1996,BruCap,91,F,1022,55 +1996,BruCap,92,M,190,3 +1996,BruCap,92,F,795,45 +1996,BruCap,93,M,145,10 +1996,BruCap,93,F,678,33 +1996,BruCap,94,M,100,9 +1996,BruCap,94,F,472,30 +1996,BruCap,95,M,56,12 +1996,BruCap,95,F,324,23 +1996,BruCap,96,M,38,4 +1996,BruCap,96,F,250,7 +1996,BruCap,97,M,30,5 +1996,BruCap,97,F,152,17 +1996,BruCap,98,M,13,1 +1996,BruCap,98,F,92,7 +1996,BruCap,99,M,13,0 +1996,BruCap,99,F,74,6 +1996,BruCap,100,M,6,1 +1996,BruCap,100,F,59,6 +1996,BruCap,101,M,4,0 +1996,BruCap,101,F,25,1 +1996,BruCap,102,M,3,1 +1996,BruCap,102,F,17,2 +1996,BruCap,103,M,2,0 +1996,BruCap,103,F,11,0 +1996,BruCap,104,M,0,0 +1996,BruCap,104,F,5,0 +1996,BruCap,105,M,1,0 +1996,BruCap,105,F,0,1 +1996,BruCap,106,M,0,0 +1996,BruCap,106,F,4,0 +1996,BruCap,107,M,0,0 +1996,BruCap,107,F,0,0 +1996,BruCap,108,M,0,0 +1996,BruCap,108,F,0,0 +1996,BruCap,109,M,0,0 +1996,BruCap,109,F,0,0 +1996,BruCap,110,M,0,0 +1996,BruCap,110,F,0,0 +1996,BruCap,111,M,0,0 +1996,BruCap,111,F,0,2 +1996,BruCap,112,M,0,0 +1996,BruCap,112,F,0,0 +1996,BruCap,113,M,0,0 +1996,BruCap,113,F,0,0 +1996,BruCap,114,M,0,0 +1996,BruCap,114,F,0,0 +1996,BruCap,115,M,0,0 +1996,BruCap,115,F,0,0 +1996,BruCap,116,M,0,0 +1996,BruCap,116,F,0,0 +1996,BruCap,117,M,0,0 +1996,BruCap,117,F,0,0 +1996,BruCap,118,M,0,0 +1996,BruCap,118,F,0,0 +1996,BruCap,119,M,0,0 +1996,BruCap,119,F,0,0 +1996,BruCap,120,M,0,0 +1996,BruCap,120,F,0,0 +1996,Fla,0,M,31062,1847 +1996,Fla,0,F,29646,1791 +1996,Fla,1,M,31508,2012 +1996,Fla,1,F,30072,1836 +1996,Fla,2,M,32968,1978 +1996,Fla,2,F,31919,1916 +1996,Fla,3,M,34297,1994 +1996,Fla,3,F,32763,1978 +1996,Fla,4,M,34738,2089 +1996,Fla,4,F,32976,1960 +1996,Fla,5,M,34394,1988 +1996,Fla,5,F,32715,2018 +1996,Fla,6,M,33321,1984 +1996,Fla,6,F,31674,1889 +1996,Fla,7,M,32914,2030 +1996,Fla,7,F,31441,1905 +1996,Fla,8,M,32667,1927 +1996,Fla,8,F,30918,1842 +1996,Fla,9,M,32814,1904 +1996,Fla,9,F,30967,1698 +1996,Fla,10,M,31884,1866 +1996,Fla,10,F,30447,1783 +1996,Fla,11,M,32720,1816 +1996,Fla,11,F,31124,1762 +1996,Fla,12,M,33823,1657 +1996,Fla,12,F,32362,1692 +1996,Fla,13,M,34626,1836 +1996,Fla,13,F,32700,1788 +1996,Fla,14,M,35725,1968 +1996,Fla,14,F,33422,1972 +1996,Fla,15,M,35127,2218 +1996,Fla,15,F,33748,2072 +1996,Fla,16,M,35610,2241 +1996,Fla,16,F,33411,2134 +1996,Fla,17,M,34787,2113 +1996,Fla,17,F,33297,2142 +1996,Fla,18,M,34541,1743 +1996,Fla,18,F,33265,1955 +1996,Fla,19,M,34111,1588 +1996,Fla,19,F,32411,1897 +1996,Fla,20,M,33274,1641 +1996,Fla,20,F,31561,1953 +1996,Fla,21,M,34520,1798 +1996,Fla,21,F,33015,2175 +1996,Fla,22,M,35832,2064 +1996,Fla,22,F,34194,2274 +1996,Fla,23,M,37363,2258 +1996,Fla,23,F,35866,2520 +1996,Fla,24,M,38756,2587 +1996,Fla,24,F,37677,2694 +1996,Fla,25,M,39905,2737 +1996,Fla,25,F,38217,2772 +1996,Fla,26,M,39790,2978 +1996,Fla,26,F,38269,2848 +1996,Fla,27,M,40226,2927 +1996,Fla,27,F,38705,2753 +1996,Fla,28,M,41778,2900 +1996,Fla,28,F,39726,2662 +1996,Fla,29,M,42974,3262 +1996,Fla,29,F,41535,3021 +1996,Fla,30,M,44605,3266 +1996,Fla,30,F,42808,2830 +1996,Fla,31,M,46395,3435 +1996,Fla,31,F,45097,2927 +1996,Fla,32,M,46297,3239 +1996,Fla,32,F,44758,2749 +1996,Fla,33,M,45783,3359 +1996,Fla,33,F,44272,2602 +1996,Fla,34,M,45650,3126 +1996,Fla,34,F,44660,2452 +1996,Fla,35,M,44608,3259 +1996,Fla,35,F,43442,2598 +1996,Fla,36,M,45607,2897 +1996,Fla,36,F,44446,2440 +1996,Fla,37,M,44846,3004 +1996,Fla,37,F,43237,2307 +1996,Fla,38,M,44333,2792 +1996,Fla,38,F,42785,2035 +1996,Fla,39,M,42975,2783 +1996,Fla,39,F,42164,2140 +1996,Fla,40,M,42524,2720 +1996,Fla,40,F,41831,1938 +1996,Fla,41,M,41820,2586 +1996,Fla,41,F,40780,1911 +1996,Fla,42,M,41001,2305 +1996,Fla,42,F,39534,1764 +1996,Fla,43,M,40948,2372 +1996,Fla,43,F,39352,1690 +1996,Fla,44,M,39084,2240 +1996,Fla,44,F,37899,1566 +1996,Fla,45,M,38507,2384 +1996,Fla,45,F,37828,1621 +1996,Fla,46,M,38854,2363 +1996,Fla,46,F,37596,1645 +1996,Fla,47,M,38720,2271 +1996,Fla,47,F,38159,1535 +1996,Fla,48,M,38582,2201 +1996,Fla,48,F,37733,1536 +1996,Fla,49,M,39586,2177 +1996,Fla,49,F,38317,1396 +1996,Fla,50,M,35187,1879 +1996,Fla,50,F,34649,1294 +1996,Fla,51,M,34983,1832 +1996,Fla,51,F,34405,1359 +1996,Fla,52,M,33435,1811 +1996,Fla,52,F,33024,1236 +1996,Fla,53,M,29163,1691 +1996,Fla,53,F,28778,1237 +1996,Fla,54,M,26176,1691 +1996,Fla,54,F,26507,1103 +1996,Fla,55,M,28896,1792 +1996,Fla,55,F,29424,1312 +1996,Fla,56,M,31639,1698 +1996,Fla,56,F,33000,1092 +1996,Fla,57,M,32745,1635 +1996,Fla,57,F,33607,1104 +1996,Fla,58,M,31748,1502 +1996,Fla,58,F,32475,1021 +1996,Fla,59,M,30665,1446 +1996,Fla,59,F,31983,947 +1996,Fla,60,M,30562,1360 +1996,Fla,60,F,31956,893 +1996,Fla,61,M,30601,1326 +1996,Fla,61,F,32635,926 +1996,Fla,62,M,30651,1292 +1996,Fla,62,F,32508,884 +1996,Fla,63,M,31174,1232 +1996,Fla,63,F,33928,818 +1996,Fla,64,M,30976,1095 +1996,Fla,64,F,33937,672 +1996,Fla,65,M,30269,1110 +1996,Fla,65,F,33755,787 +1996,Fla,66,M,27897,942 +1996,Fla,66,F,31595,685 +1996,Fla,67,M,26834,899 +1996,Fla,67,F,30769,688 +1996,Fla,68,M,25778,833 +1996,Fla,68,F,29649,607 +1996,Fla,69,M,24992,765 +1996,Fla,69,F,30082,633 +1996,Fla,70,M,24707,736 +1996,Fla,70,F,29611,603 +1996,Fla,71,M,23512,708 +1996,Fla,71,F,28979,542 +1996,Fla,72,M,22575,675 +1996,Fla,72,F,28638,549 +1996,Fla,73,M,20631,571 +1996,Fla,73,F,26949,499 +1996,Fla,74,M,19719,570 +1996,Fla,74,F,26645,472 +1996,Fla,75,M,18640,479 +1996,Fla,75,F,25760,444 +1996,Fla,76,M,13657,359 +1996,Fla,76,F,19283,289 +1996,Fla,77,M,8583,272 +1996,Fla,77,F,13173,256 +1996,Fla,78,M,7931,249 +1996,Fla,78,F,12728,225 +1996,Fla,79,M,8651,228 +1996,Fla,79,F,13919,235 +1996,Fla,80,M,9690,213 +1996,Fla,80,F,16117,235 +1996,Fla,81,M,9872,204 +1996,Fla,81,F,17783,229 +1996,Fla,82,M,8784,171 +1996,Fla,82,F,16742,231 +1996,Fla,83,M,7773,144 +1996,Fla,83,F,15345,198 +1996,Fla,84,M,6304,127 +1996,Fla,84,F,13420,159 +1996,Fla,85,M,5545,79 +1996,Fla,85,F,12155,138 +1996,Fla,86,M,4552,85 +1996,Fla,86,F,10612,171 +1996,Fla,87,M,3647,70 +1996,Fla,87,F,9466,109 +1996,Fla,88,M,3047,46 +1996,Fla,88,F,7907,93 +1996,Fla,89,M,2278,48 +1996,Fla,89,F,6405,78 +1996,Fla,90,M,1772,36 +1996,Fla,90,F,5387,54 +1996,Fla,91,M,1371,26 +1996,Fla,91,F,4302,76 +1996,Fla,92,M,1007,14 +1996,Fla,92,F,3154,33 +1996,Fla,93,M,654,10 +1996,Fla,93,F,2447,26 +1996,Fla,94,M,489,10 +1996,Fla,94,F,1811,29 +1996,Fla,95,M,302,9 +1996,Fla,95,F,1169,16 +1996,Fla,96,M,244,7 +1996,Fla,96,F,794,14 +1996,Fla,97,M,124,3 +1996,Fla,97,F,520,9 +1996,Fla,98,M,82,5 +1996,Fla,98,F,350,6 +1996,Fla,99,M,56,0 +1996,Fla,99,F,235,6 +1996,Fla,100,M,28,1 +1996,Fla,100,F,158,1 +1996,Fla,101,M,17,0 +1996,Fla,101,F,77,1 +1996,Fla,102,M,9,2 +1996,Fla,102,F,42,0 +1996,Fla,103,M,3,0 +1996,Fla,103,F,19,0 +1996,Fla,104,M,1,1 +1996,Fla,104,F,5,1 +1996,Fla,105,M,1,0 +1996,Fla,105,F,1,0 +1996,Fla,106,M,0,0 +1996,Fla,106,F,1,0 +1996,Fla,107,M,0,0 +1996,Fla,107,F,2,0 +1996,Fla,108,M,0,0 +1996,Fla,108,F,1,1 +1996,Fla,109,M,0,0 +1996,Fla,109,F,0,0 +1996,Fla,110,M,0,0 +1996,Fla,110,F,0,0 +1996,Fla,111,M,0,0 +1996,Fla,111,F,0,0 +1996,Fla,112,M,0,0 +1996,Fla,112,F,0,0 +1996,Fla,113,M,0,0 +1996,Fla,113,F,0,0 +1996,Fla,114,M,0,0 +1996,Fla,114,F,0,0 +1996,Fla,115,M,0,0 +1996,Fla,115,F,0,0 +1996,Fla,116,M,0,0 +1996,Fla,116,F,0,0 +1996,Fla,117,M,0,0 +1996,Fla,117,F,0,0 +1996,Fla,118,M,0,0 +1996,Fla,118,F,0,0 +1996,Fla,119,M,0,0 +1996,Fla,119,F,0,0 +1996,Fla,120,M,0,0 +1996,Fla,120,F,0,0 +1996,Wal,0,M,18229,1027 +1996,Wal,0,F,17451,1037 +1996,Wal,1,M,18454,1186 +1996,Wal,1,F,17659,1056 +1996,Wal,2,M,19460,1220 +1996,Wal,2,F,18308,1224 +1996,Wal,3,M,20454,1309 +1996,Wal,3,F,19527,1294 +1996,Wal,4,M,21067,1355 +1996,Wal,4,F,20248,1358 +1996,Wal,5,M,20782,1430 +1996,Wal,5,F,19940,1358 +1996,Wal,6,M,20865,1452 +1996,Wal,6,F,19866,1428 +1996,Wal,7,M,20717,1526 +1996,Wal,7,F,19645,1447 +1996,Wal,8,M,19940,1547 +1996,Wal,8,F,18999,1476 +1996,Wal,9,M,19973,1571 +1996,Wal,9,F,18907,1489 +1996,Wal,10,M,19201,1526 +1996,Wal,10,F,18299,1452 +1996,Wal,11,M,18934,1528 +1996,Wal,11,F,18227,1518 +1996,Wal,12,M,18945,1508 +1996,Wal,12,F,17584,1429 +1996,Wal,13,M,19054,1693 +1996,Wal,13,F,18230,1652 +1996,Wal,14,M,19160,1793 +1996,Wal,14,F,18645,1746 +1996,Wal,15,M,19168,1923 +1996,Wal,15,F,18580,1831 +1996,Wal,16,M,18867,2035 +1996,Wal,16,F,17819,1879 +1996,Wal,17,M,18448,2172 +1996,Wal,17,F,17771,2019 +1996,Wal,18,M,18963,1953 +1996,Wal,18,F,17993,2047 +1996,Wal,19,M,19218,1925 +1996,Wal,19,F,18477,1964 +1996,Wal,20,M,19330,2033 +1996,Wal,20,F,18614,2002 +1996,Wal,21,M,19959,2354 +1996,Wal,21,F,19006,2314 +1996,Wal,22,M,20630,2696 +1996,Wal,22,F,19750,2515 +1996,Wal,23,M,21044,2940 +1996,Wal,23,F,20095,2721 +1996,Wal,24,M,21174,3039 +1996,Wal,24,F,20378,2834 +1996,Wal,25,M,20446,3152 +1996,Wal,25,F,19671,2878 +1996,Wal,26,M,20146,3246 +1996,Wal,26,F,19579,2918 +1996,Wal,27,M,19559,3348 +1996,Wal,27,F,19431,3054 +1996,Wal,28,M,19988,3309 +1996,Wal,28,F,19677,2913 +1996,Wal,29,M,20388,3755 +1996,Wal,29,F,20330,3239 +1996,Wal,30,M,21237,3893 +1996,Wal,30,F,21112,3230 +1996,Wal,31,M,22072,3861 +1996,Wal,31,F,22096,3279 +1996,Wal,32,M,21743,3911 +1996,Wal,32,F,22104,3159 +1996,Wal,33,M,21178,3904 +1996,Wal,33,F,21676,3085 +1996,Wal,34,M,21876,3770 +1996,Wal,34,F,22397,3185 +1996,Wal,35,M,21774,4068 +1996,Wal,35,F,21990,3020 +1996,Wal,36,M,22080,3862 +1996,Wal,36,F,22861,3023 +1996,Wal,37,M,21723,3885 +1996,Wal,37,F,22477,2955 +1996,Wal,38,M,21619,3853 +1996,Wal,38,F,22094,2824 +1996,Wal,39,M,21159,3982 +1996,Wal,39,F,21926,2859 +1996,Wal,40,M,21007,3794 +1996,Wal,40,F,21963,2805 +1996,Wal,41,M,20932,3694 +1996,Wal,41,F,21802,2712 +1996,Wal,42,M,21082,3514 +1996,Wal,42,F,21624,2477 +1996,Wal,43,M,20914,3413 +1996,Wal,43,F,21329,2476 +1996,Wal,44,M,20256,3245 +1996,Wal,44,F,21058,2352 +1996,Wal,45,M,21107,3300 +1996,Wal,45,F,21273,2453 +1996,Wal,46,M,20990,3166 +1996,Wal,46,F,21266,2259 +1996,Wal,47,M,21549,3119 +1996,Wal,47,F,22024,2353 +1996,Wal,48,M,21618,3053 +1996,Wal,48,F,21891,2159 +1996,Wal,49,M,21055,2867 +1996,Wal,49,F,21754,2040 +1996,Wal,50,M,15702,2284 +1996,Wal,50,F,16652,1699 +1996,Wal,51,M,15700,2280 +1996,Wal,51,F,16347,1774 +1996,Wal,52,M,14666,2034 +1996,Wal,52,F,15445,1612 +1996,Wal,53,M,12781,1984 +1996,Wal,53,F,13502,1589 +1996,Wal,54,M,11929,1920 +1996,Wal,54,F,12806,1483 +1996,Wal,55,M,13271,2232 +1996,Wal,55,F,14305,1777 +1996,Wal,56,M,14421,2046 +1996,Wal,56,F,15829,1773 +1996,Wal,57,M,14681,1910 +1996,Wal,57,F,16234,1761 +1996,Wal,58,M,14018,1958 +1996,Wal,58,F,15254,1621 +1996,Wal,59,M,13632,1935 +1996,Wal,59,F,15298,1651 +1996,Wal,60,M,13433,1879 +1996,Wal,60,F,15301,1678 +1996,Wal,61,M,14144,1812 +1996,Wal,61,F,15986,1697 +1996,Wal,62,M,14205,1823 +1996,Wal,62,F,16061,1713 +1996,Wal,63,M,14967,1938 +1996,Wal,63,F,17482,1636 +1996,Wal,64,M,15377,1739 +1996,Wal,64,F,18026,1640 +1996,Wal,65,M,15132,1831 +1996,Wal,65,F,18095,1683 +1996,Wal,66,M,14183,1728 +1996,Wal,66,F,17311,1614 +1996,Wal,67,M,13756,1705 +1996,Wal,67,F,17547,1524 +1996,Wal,68,M,13413,1695 +1996,Wal,68,F,17099,1595 +1996,Wal,69,M,13104,1716 +1996,Wal,69,F,17198,1595 +1996,Wal,70,M,12984,1575 +1996,Wal,70,F,17658,1550 +1996,Wal,71,M,12390,1522 +1996,Wal,71,F,17202,1432 +1996,Wal,72,M,11660,1440 +1996,Wal,72,F,16682,1342 +1996,Wal,73,M,11190,1254 +1996,Wal,73,F,16551,1286 +1996,Wal,74,M,10884,1069 +1996,Wal,74,F,16774,1185 +1996,Wal,75,M,10128,940 +1996,Wal,75,F,16196,1090 +1996,Wal,76,M,6925,545 +1996,Wal,76,F,11533,735 +1996,Wal,77,M,4525,412 +1996,Wal,77,F,7969,500 +1996,Wal,78,M,4037,357 +1996,Wal,78,F,7527,459 +1996,Wal,79,M,4309,329 +1996,Wal,79,F,7793,496 +1996,Wal,80,M,4565,340 +1996,Wal,80,F,9067,559 +1996,Wal,81,M,4929,371 +1996,Wal,81,F,10381,594 +1996,Wal,82,M,4303,342 +1996,Wal,82,F,9399,542 +1996,Wal,83,M,3656,295 +1996,Wal,83,F,8862,495 +1996,Wal,84,M,2904,192 +1996,Wal,84,F,7583,426 +1996,Wal,85,M,2572,144 +1996,Wal,85,F,6972,377 +1996,Wal,86,M,2023,105 +1996,Wal,86,F,6157,333 +1996,Wal,87,M,1608,107 +1996,Wal,87,F,5527,288 +1996,Wal,88,M,1327,64 +1996,Wal,88,F,4780,210 +1996,Wal,89,M,1040,65 +1996,Wal,89,F,3785,193 +1996,Wal,90,M,810,48 +1996,Wal,90,F,2958,160 +1996,Wal,91,M,600,33 +1996,Wal,91,F,2496,130 +1996,Wal,92,M,436,29 +1996,Wal,92,F,1892,83 +1996,Wal,93,M,296,19 +1996,Wal,93,F,1379,90 +1996,Wal,94,M,221,16 +1996,Wal,94,F,1097,55 +1996,Wal,95,M,134,10 +1996,Wal,95,F,715,41 +1996,Wal,96,M,90,4 +1996,Wal,96,F,458,18 +1996,Wal,97,M,54,7 +1996,Wal,97,F,303,12 +1996,Wal,98,M,30,5 +1996,Wal,98,F,200,15 +1996,Wal,99,M,24,3 +1996,Wal,99,F,144,9 +1996,Wal,100,M,8,0 +1996,Wal,100,F,93,2 +1996,Wal,101,M,5,1 +1996,Wal,101,F,38,3 +1996,Wal,102,M,4,0 +1996,Wal,102,F,23,1 +1996,Wal,103,M,1,1 +1996,Wal,103,F,15,2 +1996,Wal,104,M,0,0 +1996,Wal,104,F,6,0 +1996,Wal,105,M,0,0 +1996,Wal,105,F,3,1 +1996,Wal,106,M,0,0 +1996,Wal,106,F,1,0 +1996,Wal,107,M,0,0 +1996,Wal,107,F,3,0 +1996,Wal,108,M,0,0 +1996,Wal,108,F,0,0 +1996,Wal,109,M,0,0 +1996,Wal,109,F,0,0 +1996,Wal,110,M,0,0 +1996,Wal,110,F,0,0 +1996,Wal,111,M,0,0 +1996,Wal,111,F,0,0 +1996,Wal,112,M,0,0 +1996,Wal,112,F,0,0 +1996,Wal,113,M,0,0 +1996,Wal,113,F,0,0 +1996,Wal,114,M,0,0 +1996,Wal,114,F,0,0 +1996,Wal,115,M,0,0 +1996,Wal,115,F,0,0 +1996,Wal,116,M,0,0 +1996,Wal,116,F,0,0 +1996,Wal,117,M,0,0 +1996,Wal,117,F,0,0 +1996,Wal,118,M,0,0 +1996,Wal,118,F,0,0 +1996,Wal,119,M,0,0 +1996,Wal,119,F,0,0 +1996,Wal,120,M,0,0 +1996,Wal,120,F,0,0 +1997,BruCap,0,M,4450,1909 +1997,BruCap,0,F,4361,1868 +1997,BruCap,1,M,4248,2041 +1997,BruCap,1,F,4121,1851 +1997,BruCap,2,M,4212,2028 +1997,BruCap,2,F,3779,1885 +1997,BruCap,3,M,4065,1904 +1997,BruCap,3,F,3819,1808 +1997,BruCap,4,M,4007,1989 +1997,BruCap,4,F,3890,1866 +1997,BruCap,5,M,3970,1899 +1997,BruCap,5,F,3792,1854 +1997,BruCap,6,M,3857,2006 +1997,BruCap,6,F,3663,1881 +1997,BruCap,7,M,3708,1883 +1997,BruCap,7,F,3636,1847 +1997,BruCap,8,M,3706,1880 +1997,BruCap,8,F,3462,1830 +1997,BruCap,9,M,3612,1842 +1997,BruCap,9,F,3442,1803 +1997,BruCap,10,M,3540,1761 +1997,BruCap,10,F,3323,1682 +1997,BruCap,11,M,3494,1757 +1997,BruCap,11,F,3160,1648 +1997,BruCap,12,M,3699,1539 +1997,BruCap,12,F,3421,1639 +1997,BruCap,13,M,3531,1599 +1997,BruCap,13,F,3407,1564 +1997,BruCap,14,M,3434,1847 +1997,BruCap,14,F,3288,1772 +1997,BruCap,15,M,3408,2051 +1997,BruCap,15,F,3260,1941 +1997,BruCap,16,M,3268,2131 +1997,BruCap,16,F,3221,2129 +1997,BruCap,17,M,3172,2225 +1997,BruCap,17,F,2994,2160 +1997,BruCap,18,M,3416,1855 +1997,BruCap,18,F,3502,2014 +1997,BruCap,19,M,3735,1687 +1997,BruCap,19,F,3768,1833 +1997,BruCap,20,M,3717,1832 +1997,BruCap,20,F,3834,1991 +1997,BruCap,21,M,3877,1869 +1997,BruCap,21,F,3910,2082 +1997,BruCap,22,M,3882,2166 +1997,BruCap,22,F,4028,2287 +1997,BruCap,23,M,4305,2327 +1997,BruCap,23,F,4506,2582 +1997,BruCap,24,M,4559,2718 +1997,BruCap,24,F,4876,2876 +1997,BruCap,25,M,4910,2966 +1997,BruCap,25,F,5149,3058 +1997,BruCap,26,M,4980,3235 +1997,BruCap,26,F,5149,3052 +1997,BruCap,27,M,4940,3356 +1997,BruCap,27,F,5019,3297 +1997,BruCap,28,M,4865,3428 +1997,BruCap,28,F,4848,3234 +1997,BruCap,29,M,4907,3393 +1997,BruCap,29,F,4817,3163 +1997,BruCap,30,M,4782,3636 +1997,BruCap,30,F,4718,3312 +1997,BruCap,31,M,4893,3645 +1997,BruCap,31,F,4709,3359 +1997,BruCap,32,M,4713,3693 +1997,BruCap,32,F,4630,3369 +1997,BruCap,33,M,4627,3372 +1997,BruCap,33,F,4563,3079 +1997,BruCap,34,M,4290,3369 +1997,BruCap,34,F,4377,2995 +1997,BruCap,35,M,4292,3109 +1997,BruCap,35,F,4462,2846 +1997,BruCap,36,M,4334,3129 +1997,BruCap,36,F,4498,2885 +1997,BruCap,37,M,4388,2796 +1997,BruCap,37,F,4461,2633 +1997,BruCap,38,M,4196,2681 +1997,BruCap,38,F,4476,2508 +1997,BruCap,39,M,4225,2445 +1997,BruCap,39,F,4438,2331 +1997,BruCap,40,M,4056,2535 +1997,BruCap,40,F,4404,2359 +1997,BruCap,41,M,4084,2421 +1997,BruCap,41,F,4399,2291 +1997,BruCap,42,M,4108,2217 +1997,BruCap,42,F,4300,2172 +1997,BruCap,43,M,4149,2149 +1997,BruCap,43,F,4419,2013 +1997,BruCap,44,M,4185,2156 +1997,BruCap,44,F,4410,2006 +1997,BruCap,45,M,4002,1967 +1997,BruCap,45,F,4393,1744 +1997,BruCap,46,M,3930,2058 +1997,BruCap,46,F,4450,1881 +1997,BruCap,47,M,3976,1846 +1997,BruCap,47,F,4449,1635 +1997,BruCap,48,M,4109,1828 +1997,BruCap,48,F,4536,1633 +1997,BruCap,49,M,4109,1781 +1997,BruCap,49,F,4747,1507 +1997,BruCap,50,M,4235,1662 +1997,BruCap,50,F,4609,1498 +1997,BruCap,51,M,3525,1525 +1997,BruCap,51,F,3992,1367 +1997,BruCap,52,M,3661,1552 +1997,BruCap,52,F,4284,1334 +1997,BruCap,53,M,3586,1393 +1997,BruCap,53,F,4060,1235 +1997,BruCap,54,M,3074,1445 +1997,BruCap,54,F,3508,1217 +1997,BruCap,55,M,2730,1234 +1997,BruCap,55,F,3145,1065 +1997,BruCap,56,M,3002,1532 +1997,BruCap,56,F,3444,1364 +1997,BruCap,57,M,3177,1356 +1997,BruCap,57,F,3791,1159 +1997,BruCap,58,M,3162,1353 +1997,BruCap,58,F,3721,1073 +1997,BruCap,59,M,3112,1282 +1997,BruCap,59,F,3698,1037 +1997,BruCap,60,M,3005,1266 +1997,BruCap,60,F,3636,1063 +1997,BruCap,61,M,3000,1109 +1997,BruCap,61,F,3696,1014 +1997,BruCap,62,M,3159,1097 +1997,BruCap,62,F,3751,879 +1997,BruCap,63,M,3087,993 +1997,BruCap,63,F,3950,783 +1997,BruCap,64,M,3266,1013 +1997,BruCap,64,F,4179,808 +1997,BruCap,65,M,3321,825 +1997,BruCap,65,F,4278,731 +1997,BruCap,66,M,3217,905 +1997,BruCap,66,F,4657,780 +1997,BruCap,67,M,3134,755 +1997,BruCap,67,F,4420,594 +1997,BruCap,68,M,3127,654 +1997,BruCap,68,F,4362,616 +1997,BruCap,69,M,3019,589 +1997,BruCap,69,F,4452,533 +1997,BruCap,70,M,3085,557 +1997,BruCap,70,F,4601,502 +1997,BruCap,71,M,3077,502 +1997,BruCap,71,F,4697,462 +1997,BruCap,72,M,3156,383 +1997,BruCap,72,F,4792,438 +1997,BruCap,73,M,2958,411 +1997,BruCap,73,F,4941,418 +1997,BruCap,74,M,2903,343 +1997,BruCap,74,F,4863,370 +1997,BruCap,75,M,3044,325 +1997,BruCap,75,F,4950,322 +1997,BruCap,76,M,2772,290 +1997,BruCap,76,F,4995,389 +1997,BruCap,77,M,2072,171 +1997,BruCap,77,F,3504,250 +1997,BruCap,78,M,1237,140 +1997,BruCap,78,F,2562,180 +1997,BruCap,79,M,1180,125 +1997,BruCap,79,F,2458,182 +1997,BruCap,80,M,1178,102 +1997,BruCap,80,F,2606,173 +1997,BruCap,81,M,1392,105 +1997,BruCap,81,F,3033,175 +1997,BruCap,82,M,1502,116 +1997,BruCap,82,F,3473,184 +1997,BruCap,83,M,1319,91 +1997,BruCap,83,F,3193,178 +1997,BruCap,84,M,1121,72 +1997,BruCap,84,F,2964,176 +1997,BruCap,85,M,936,71 +1997,BruCap,85,F,2625,119 +1997,BruCap,86,M,787,64 +1997,BruCap,86,F,2468,142 +1997,BruCap,87,M,635,36 +1997,BruCap,87,F,2044,118 +1997,BruCap,88,M,549,40 +1997,BruCap,88,F,1849,77 +1997,BruCap,89,M,427,40 +1997,BruCap,89,F,1558,76 +1997,BruCap,90,M,311,22 +1997,BruCap,90,F,1289,68 +1997,BruCap,91,M,250,15 +1997,BruCap,91,F,1063,62 +1997,BruCap,92,M,195,19 +1997,BruCap,92,F,834,45 +1997,BruCap,93,M,130,3 +1997,BruCap,93,F,638,41 +1997,BruCap,94,M,99,9 +1997,BruCap,94,F,525,30 +1997,BruCap,95,M,69,6 +1997,BruCap,95,F,383,26 +1997,BruCap,96,M,37,10 +1997,BruCap,96,F,247,15 +1997,BruCap,97,M,28,3 +1997,BruCap,97,F,176,6 +1997,BruCap,98,M,20,5 +1997,BruCap,98,F,117,15 +1997,BruCap,99,M,8,2 +1997,BruCap,99,F,60,7 +1997,BruCap,100,M,9,0 +1997,BruCap,100,F,50,4 +1997,BruCap,101,M,4,0 +1997,BruCap,101,F,32,5 +1997,BruCap,102,M,2,0 +1997,BruCap,102,F,14,1 +1997,BruCap,103,M,2,1 +1997,BruCap,103,F,12,0 +1997,BruCap,104,M,0,0 +1997,BruCap,104,F,6,0 +1997,BruCap,105,M,0,0 +1997,BruCap,105,F,2,0 +1997,BruCap,106,M,1,0 +1997,BruCap,106,F,0,1 +1997,BruCap,107,M,0,0 +1997,BruCap,107,F,2,0 +1997,BruCap,108,M,0,0 +1997,BruCap,108,F,0,0 +1997,BruCap,109,M,0,0 +1997,BruCap,109,F,0,0 +1997,BruCap,110,M,0,0 +1997,BruCap,110,F,0,0 +1997,BruCap,111,M,0,0 +1997,BruCap,111,F,0,0 +1997,BruCap,112,M,0,0 +1997,BruCap,112,F,0,1 +1997,BruCap,113,M,0,0 +1997,BruCap,113,F,0,0 +1997,BruCap,114,M,0,0 +1997,BruCap,114,F,0,0 +1997,BruCap,115,M,0,0 +1997,BruCap,115,F,0,0 +1997,BruCap,116,M,0,0 +1997,BruCap,116,F,0,0 +1997,BruCap,117,M,0,0 +1997,BruCap,117,F,0,0 +1997,BruCap,118,M,0,0 +1997,BruCap,118,F,0,0 +1997,BruCap,119,M,0,0 +1997,BruCap,119,F,0,0 +1997,BruCap,120,M,0,0 +1997,BruCap,120,F,0,0 +1997,Fla,0,M,30996,1758 +1997,Fla,0,F,29758,1785 +1997,Fla,1,M,31234,1878 +1997,Fla,1,F,29850,1804 +1997,Fla,2,M,31661,2012 +1997,Fla,2,F,30206,1838 +1997,Fla,3,M,33093,1951 +1997,Fla,3,F,32101,1869 +1997,Fla,4,M,34368,1982 +1997,Fla,4,F,32907,1956 +1997,Fla,5,M,34906,2063 +1997,Fla,5,F,33079,1966 +1997,Fla,6,M,34539,1958 +1997,Fla,6,F,32827,1986 +1997,Fla,7,M,33439,1957 +1997,Fla,7,F,31789,1870 +1997,Fla,8,M,33007,2002 +1997,Fla,8,F,31560,1868 +1997,Fla,9,M,32780,1881 +1997,Fla,9,F,31038,1816 +1997,Fla,10,M,32933,1868 +1997,Fla,10,F,31089,1648 +1997,Fla,11,M,32025,1784 +1997,Fla,11,F,30584,1696 +1997,Fla,12,M,32966,1639 +1997,Fla,12,F,31398,1556 +1997,Fla,13,M,33892,1663 +1997,Fla,13,F,32390,1702 +1997,Fla,14,M,34675,1866 +1997,Fla,14,F,32720,1775 +1997,Fla,15,M,35782,1983 +1997,Fla,15,F,33489,1956 +1997,Fla,16,M,35189,2224 +1997,Fla,16,F,33775,2106 +1997,Fla,17,M,35636,2258 +1997,Fla,17,F,33480,2203 +1997,Fla,18,M,35212,1753 +1997,Fla,18,F,33734,1940 +1997,Fla,19,M,34769,1545 +1997,Fla,19,F,33481,1882 +1997,Fla,20,M,34129,1598 +1997,Fla,20,F,32485,1986 +1997,Fla,21,M,33289,1644 +1997,Fla,21,F,31608,2070 +1997,Fla,22,M,34550,1876 +1997,Fla,22,F,33050,2324 +1997,Fla,23,M,35812,2178 +1997,Fla,23,F,34145,2433 +1997,Fla,24,M,37257,2439 +1997,Fla,24,F,35752,2677 +1997,Fla,25,M,38635,2750 +1997,Fla,25,F,37570,2855 +1997,Fla,26,M,39856,2816 +1997,Fla,26,F,38215,2948 +1997,Fla,27,M,39719,3041 +1997,Fla,27,F,38241,2912 +1997,Fla,28,M,40227,3013 +1997,Fla,28,F,38776,2891 +1997,Fla,29,M,41810,2997 +1997,Fla,29,F,39728,2820 +1997,Fla,30,M,42987,3339 +1997,Fla,30,F,41605,3108 +1997,Fla,31,M,44632,3344 +1997,Fla,31,F,42867,2931 +1997,Fla,32,M,46461,3461 +1997,Fla,32,F,45150,3006 +1997,Fla,33,M,46343,3307 +1997,Fla,33,F,44781,2815 +1997,Fla,34,M,45775,3409 +1997,Fla,34,F,44302,2695 +1997,Fla,35,M,45653,3149 +1997,Fla,35,F,44722,2493 +1997,Fla,36,M,44624,3253 +1997,Fla,36,F,43451,2602 +1997,Fla,37,M,45627,2870 +1997,Fla,37,F,44475,2461 +1997,Fla,38,M,44807,2962 +1997,Fla,38,F,43258,2340 +1997,Fla,39,M,44273,2798 +1997,Fla,39,F,42780,2086 +1997,Fla,40,M,42951,2793 +1997,Fla,40,F,42143,2193 +1997,Fla,41,M,42462,2717 +1997,Fla,41,F,41814,2002 +1997,Fla,42,M,41738,2583 +1997,Fla,42,F,40751,1929 +1997,Fla,43,M,40915,2288 +1997,Fla,43,F,39489,1808 +1997,Fla,44,M,40865,2386 +1997,Fla,44,F,39300,1724 +1997,Fla,45,M,38996,2256 +1997,Fla,45,F,37864,1591 +1997,Fla,46,M,38439,2396 +1997,Fla,46,F,37756,1664 +1997,Fla,47,M,38745,2399 +1997,Fla,47,F,37554,1678 +1997,Fla,48,M,38631,2288 +1997,Fla,48,F,38049,1551 +1997,Fla,49,M,38436,2243 +1997,Fla,49,F,37635,1572 +1997,Fla,50,M,39446,2207 +1997,Fla,50,F,38241,1432 +1997,Fla,51,M,35033,1911 +1997,Fla,51,F,34537,1314 +1997,Fla,52,M,34815,1864 +1997,Fla,52,F,34321,1392 +1997,Fla,53,M,33232,1840 +1997,Fla,53,F,32942,1273 +1997,Fla,54,M,28986,1703 +1997,Fla,54,F,28700,1262 +1997,Fla,55,M,26017,1703 +1997,Fla,55,F,26431,1127 +1997,Fla,56,M,28717,1788 +1997,Fla,56,F,29319,1333 +1997,Fla,57,M,31406,1710 +1997,Fla,57,F,32887,1108 +1997,Fla,58,M,32506,1640 +1997,Fla,58,F,33488,1108 +1997,Fla,59,M,31501,1500 +1997,Fla,59,F,32357,1015 +1997,Fla,60,M,30394,1439 +1997,Fla,60,F,31841,951 +1997,Fla,61,M,30220,1348 +1997,Fla,61,F,31800,898 +1997,Fla,62,M,30231,1305 +1997,Fla,62,F,32479,937 +1997,Fla,63,M,30186,1291 +1997,Fla,63,F,32323,885 +1997,Fla,64,M,30720,1218 +1997,Fla,64,F,33701,812 +1997,Fla,65,M,30434,1066 +1997,Fla,65,F,33700,668 +1997,Fla,66,M,29698,1080 +1997,Fla,66,F,33456,796 +1997,Fla,67,M,27291,923 +1997,Fla,67,F,31284,691 +1997,Fla,68,M,26212,891 +1997,Fla,68,F,30431,682 +1997,Fla,69,M,25078,808 +1997,Fla,69,F,29315,596 +1997,Fla,70,M,24234,748 +1997,Fla,70,F,29680,636 +1997,Fla,71,M,23869,699 +1997,Fla,71,F,29187,589 +1997,Fla,72,M,22671,681 +1997,Fla,72,F,28480,533 +1997,Fla,73,M,21670,656 +1997,Fla,73,F,28037,538 +1997,Fla,74,M,19676,552 +1997,Fla,74,F,26345,477 +1997,Fla,75,M,18732,533 +1997,Fla,75,F,25976,451 +1997,Fla,76,M,17639,455 +1997,Fla,76,F,25031,427 +1997,Fla,77,M,12840,330 +1997,Fla,77,F,18645,272 +1997,Fla,78,M,7961,242 +1997,Fla,78,F,12701,241 +1997,Fla,79,M,7321,230 +1997,Fla,79,F,12233,214 +1997,Fla,80,M,7912,201 +1997,Fla,80,F,13230,223 +1997,Fla,81,M,8808,189 +1997,Fla,81,F,15204,227 +1997,Fla,82,M,8877,175 +1997,Fla,82,F,16643,222 +1997,Fla,83,M,7796,151 +1997,Fla,83,F,15648,220 +1997,Fla,84,M,6821,128 +1997,Fla,84,F,14084,181 +1997,Fla,85,M,5450,112 +1997,Fla,85,F,12196,145 +1997,Fla,86,M,4741,65 +1997,Fla,86,F,10934,127 +1997,Fla,87,M,3780,72 +1997,Fla,87,F,9377,150 +1997,Fla,88,M,3012,61 +1997,Fla,88,F,8168,96 +1997,Fla,89,M,2445,34 +1997,Fla,89,F,6790,81 +1997,Fla,90,M,1793,38 +1997,Fla,90,F,5409,63 +1997,Fla,91,M,1389,27 +1997,Fla,91,F,4444,45 +1997,Fla,92,M,1036,21 +1997,Fla,92,F,3465,63 +1997,Fla,93,M,720,14 +1997,Fla,93,F,2481,30 +1997,Fla,94,M,467,10 +1997,Fla,94,F,1869,25 +1997,Fla,95,M,328,8 +1997,Fla,95,F,1329,27 +1997,Fla,96,M,203,7 +1997,Fla,96,F,860,13 +1997,Fla,97,M,163,2 +1997,Fla,97,F,564,10 +1997,Fla,98,M,71,2 +1997,Fla,98,F,375,6 +1997,Fla,99,M,55,4 +1997,Fla,99,F,237,3 +1997,Fla,100,M,33,0 +1997,Fla,100,F,162,5 +1997,Fla,101,M,17,0 +1997,Fla,101,F,108,0 +1997,Fla,102,M,9,0 +1997,Fla,102,F,43,0 +1997,Fla,103,M,4,0 +1997,Fla,103,F,26,0 +1997,Fla,104,M,1,0 +1997,Fla,104,F,9,0 +1997,Fla,105,M,1,0 +1997,Fla,105,F,3,0 +1997,Fla,106,M,1,0 +1997,Fla,106,F,1,0 +1997,Fla,107,M,0,0 +1997,Fla,107,F,1,0 +1997,Fla,108,M,0,0 +1997,Fla,108,F,2,0 +1997,Fla,109,M,0,0 +1997,Fla,109,F,1,0 +1997,Fla,110,M,0,0 +1997,Fla,110,F,0,0 +1997,Fla,111,M,0,0 +1997,Fla,111,F,0,0 +1997,Fla,112,M,0,0 +1997,Fla,112,F,0,0 +1997,Fla,113,M,0,0 +1997,Fla,113,F,0,0 +1997,Fla,114,M,0,0 +1997,Fla,114,F,0,0 +1997,Fla,115,M,0,0 +1997,Fla,115,F,0,0 +1997,Fla,116,M,0,0 +1997,Fla,116,F,0,0 +1997,Fla,117,M,0,0 +1997,Fla,117,F,0,0 +1997,Fla,118,M,0,0 +1997,Fla,118,F,0,0 +1997,Fla,119,M,0,0 +1997,Fla,119,F,0,0 +1997,Fla,120,M,0,0 +1997,Fla,120,F,0,0 +1997,Wal,0,M,18694,1035 +1997,Wal,0,F,17962,938 +1997,Wal,1,M,18466,1035 +1997,Wal,1,F,17676,1020 +1997,Wal,2,M,18634,1159 +1997,Wal,2,F,17861,1059 +1997,Wal,3,M,19626,1215 +1997,Wal,3,F,18490,1187 +1997,Wal,4,M,20611,1278 +1997,Wal,4,F,19673,1276 +1997,Wal,5,M,21168,1327 +1997,Wal,5,F,20350,1351 +1997,Wal,6,M,20863,1402 +1997,Wal,6,F,20083,1329 +1997,Wal,7,M,20966,1399 +1997,Wal,7,F,19966,1384 +1997,Wal,8,M,20834,1494 +1997,Wal,8,F,19728,1404 +1997,Wal,9,M,20025,1517 +1997,Wal,9,F,19066,1446 +1997,Wal,10,M,20095,1547 +1997,Wal,10,F,19004,1440 +1997,Wal,11,M,19309,1483 +1997,Wal,11,F,18424,1401 +1997,Wal,12,M,19077,1403 +1997,Wal,12,F,18346,1421 +1997,Wal,13,M,19002,1480 +1997,Wal,13,F,17665,1385 +1997,Wal,14,M,19116,1672 +1997,Wal,14,F,18319,1640 +1997,Wal,15,M,19234,1751 +1997,Wal,15,F,18701,1700 +1997,Wal,16,M,19212,1894 +1997,Wal,16,F,18646,1829 +1997,Wal,17,M,18937,1991 +1997,Wal,17,F,17859,1928 +1997,Wal,18,M,18704,1942 +1997,Wal,18,F,17970,1911 +1997,Wal,19,M,19106,1803 +1997,Wal,19,F,18135,1974 +1997,Wal,20,M,19273,1847 +1997,Wal,20,F,18512,1910 +1997,Wal,21,M,19372,1972 +1997,Wal,21,F,18630,2010 +1997,Wal,22,M,19950,2283 +1997,Wal,22,F,18977,2297 +1997,Wal,23,M,20550,2648 +1997,Wal,23,F,19630,2484 +1997,Wal,24,M,20887,2892 +1997,Wal,24,F,19933,2712 +1997,Wal,25,M,20998,2948 +1997,Wal,25,F,20194,2837 +1997,Wal,26,M,20329,3120 +1997,Wal,26,F,19582,2831 +1997,Wal,27,M,20139,3157 +1997,Wal,27,F,19594,2917 +1997,Wal,28,M,19634,3261 +1997,Wal,28,F,19464,3086 +1997,Wal,29,M,20030,3269 +1997,Wal,29,F,19773,2945 +1997,Wal,30,M,20492,3649 +1997,Wal,30,F,20450,3250 +1997,Wal,31,M,21249,3844 +1997,Wal,31,F,21207,3229 +1997,Wal,32,M,22182,3818 +1997,Wal,32,F,22182,3276 +1997,Wal,33,M,21853,3825 +1997,Wal,33,F,22213,3182 +1997,Wal,34,M,21303,3792 +1997,Wal,34,F,21759,3047 +1997,Wal,35,M,22012,3696 +1997,Wal,35,F,22483,3191 +1997,Wal,36,M,21842,3999 +1997,Wal,36,F,22051,3033 +1997,Wal,37,M,22132,3775 +1997,Wal,37,F,22922,3004 +1997,Wal,38,M,21797,3823 +1997,Wal,38,F,22515,2931 +1997,Wal,39,M,21612,3789 +1997,Wal,39,F,22101,2808 +1997,Wal,40,M,21159,3915 +1997,Wal,40,F,21969,2846 +1997,Wal,41,M,20995,3750 +1997,Wal,41,F,21973,2784 +1997,Wal,42,M,20936,3623 +1997,Wal,42,F,21802,2696 +1997,Wal,43,M,21064,3442 +1997,Wal,43,F,21651,2435 +1997,Wal,44,M,20899,3325 +1997,Wal,44,F,21310,2439 +1997,Wal,45,M,20165,3169 +1997,Wal,45,F,21040,2334 +1997,Wal,46,M,21065,3253 +1997,Wal,46,F,21258,2440 +1997,Wal,47,M,20908,3123 +1997,Wal,47,F,21243,2234 +1997,Wal,48,M,21464,3070 +1997,Wal,48,F,21984,2368 +1997,Wal,49,M,21519,3026 +1997,Wal,49,F,21838,2138 +1997,Wal,50,M,20940,2871 +1997,Wal,50,F,21701,2036 +1997,Wal,51,M,15626,2277 +1997,Wal,51,F,16604,1683 +1997,Wal,52,M,15590,2262 +1997,Wal,52,F,16303,1754 +1997,Wal,53,M,14563,2032 +1997,Wal,53,F,15409,1590 +1997,Wal,54,M,12681,1962 +1997,Wal,54,F,13467,1564 +1997,Wal,55,M,11823,1877 +1997,Wal,55,F,12752,1481 +1997,Wal,56,M,13193,2195 +1997,Wal,56,F,14246,1768 +1997,Wal,57,M,14305,2016 +1997,Wal,57,F,15781,1756 +1997,Wal,58,M,14516,1885 +1997,Wal,58,F,16153,1744 +1997,Wal,59,M,13872,1929 +1997,Wal,59,F,15197,1611 +1997,Wal,60,M,13451,1896 +1997,Wal,60,F,15223,1622 +1997,Wal,61,M,13269,1832 +1997,Wal,61,F,15226,1660 +1997,Wal,62,M,13948,1761 +1997,Wal,62,F,15875,1667 +1997,Wal,63,M,13954,1783 +1997,Wal,63,F,15925,1691 +1997,Wal,64,M,14643,1882 +1997,Wal,64,F,17321,1613 +1997,Wal,65,M,15033,1669 +1997,Wal,65,F,17872,1618 +1997,Wal,66,M,14749,1774 +1997,Wal,66,F,17861,1662 +1997,Wal,67,M,13819,1663 +1997,Wal,67,F,17091,1580 +1997,Wal,68,M,13332,1627 +1997,Wal,68,F,17324,1511 +1997,Wal,69,M,12959,1627 +1997,Wal,69,F,16846,1577 +1997,Wal,70,M,12647,1628 +1997,Wal,70,F,16887,1565 +1997,Wal,71,M,12456,1500 +1997,Wal,71,F,17336,1503 +1997,Wal,72,M,11855,1434 +1997,Wal,72,F,16846,1410 +1997,Wal,73,M,11090,1359 +1997,Wal,73,F,16334,1312 +1997,Wal,74,M,10589,1186 +1997,Wal,74,F,16159,1255 +1997,Wal,75,M,10235,1014 +1997,Wal,75,F,16268,1153 +1997,Wal,76,M,9522,874 +1997,Wal,76,F,15676,1049 +1997,Wal,77,M,6439,507 +1997,Wal,77,F,11147,707 +1997,Wal,78,M,4144,380 +1997,Wal,78,F,7651,478 +1997,Wal,79,M,3712,324 +1997,Wal,79,F,7168,439 +1997,Wal,80,M,3921,306 +1997,Wal,80,F,7408,463 +1997,Wal,81,M,4119,310 +1997,Wal,81,F,8537,529 +1997,Wal,82,M,4377,332 +1997,Wal,82,F,9709,557 +1997,Wal,83,M,3798,304 +1997,Wal,83,F,8681,528 +1997,Wal,84,M,3164,262 +1997,Wal,84,F,8087,464 +1997,Wal,85,M,2479,161 +1997,Wal,85,F,6840,384 +1997,Wal,86,M,2176,121 +1997,Wal,86,F,6231,339 +1997,Wal,87,M,1690,85 +1997,Wal,87,F,5451,294 +1997,Wal,88,M,1317,96 +1997,Wal,88,F,4793,252 +1997,Wal,89,M,1049,45 +1997,Wal,89,F,4067,179 +1997,Wal,90,M,829,46 +1997,Wal,90,F,3188,154 +1997,Wal,91,M,621,39 +1997,Wal,91,F,2422,144 +1997,Wal,92,M,430,23 +1997,Wal,92,F,1969,106 +1997,Wal,93,M,340,17 +1997,Wal,93,F,1491,62 +1997,Wal,94,M,211,16 +1997,Wal,94,F,1025,69 +1997,Wal,95,M,139,12 +1997,Wal,95,F,824,47 +1997,Wal,96,M,81,9 +1997,Wal,96,F,508,32 +1997,Wal,97,M,55,2 +1997,Wal,97,F,310,11 +1997,Wal,98,M,34,6 +1997,Wal,98,F,202,10 +1997,Wal,99,M,22,3 +1997,Wal,99,F,146,15 +1997,Wal,100,M,12,0 +1997,Wal,100,F,91,5 +1997,Wal,101,M,6,0 +1997,Wal,101,F,58,0 +1997,Wal,102,M,4,0 +1997,Wal,102,F,25,2 +1997,Wal,103,M,3,0 +1997,Wal,103,F,14,0 +1997,Wal,104,M,0,1 +1997,Wal,104,F,8,1 +1997,Wal,105,M,0,0 +1997,Wal,105,F,4,0 +1997,Wal,106,M,0,0 +1997,Wal,106,F,3,1 +1997,Wal,107,M,0,0 +1997,Wal,107,F,1,0 +1997,Wal,108,M,0,0 +1997,Wal,108,F,1,0 +1997,Wal,109,M,0,0 +1997,Wal,109,F,0,0 +1997,Wal,110,M,0,0 +1997,Wal,110,F,0,0 +1997,Wal,111,M,0,0 +1997,Wal,111,F,0,0 +1997,Wal,112,M,0,0 +1997,Wal,112,F,0,0 +1997,Wal,113,M,0,0 +1997,Wal,113,F,0,0 +1997,Wal,114,M,0,0 +1997,Wal,114,F,0,0 +1997,Wal,115,M,0,0 +1997,Wal,115,F,0,0 +1997,Wal,116,M,0,0 +1997,Wal,116,F,0,0 +1997,Wal,117,M,1,0 +1997,Wal,117,F,0,0 +1997,Wal,118,M,0,0 +1997,Wal,118,F,0,0 +1997,Wal,119,M,0,0 +1997,Wal,119,F,0,0 +1997,Wal,120,M,0,0 +1997,Wal,120,F,0,0 +1998,BruCap,0,M,4792,1798 +1998,BruCap,0,F,4325,1691 +1998,BruCap,1,M,4444,1796 +1998,BruCap,1,F,4355,1768 +1998,BruCap,2,M,4234,1883 +1998,BruCap,2,F,4115,1735 +1998,BruCap,3,M,4252,1891 +1998,BruCap,3,F,3801,1765 +1998,BruCap,4,M,4105,1781 +1998,BruCap,4,F,3899,1676 +1998,BruCap,5,M,4096,1841 +1998,BruCap,5,F,3949,1769 +1998,BruCap,6,M,4038,1786 +1998,BruCap,6,F,3893,1700 +1998,BruCap,7,M,3992,1856 +1998,BruCap,7,F,3768,1757 +1998,BruCap,8,M,3816,1740 +1998,BruCap,8,F,3727,1725 +1998,BruCap,9,M,3834,1739 +1998,BruCap,9,F,3590,1677 +1998,BruCap,10,M,3725,1711 +1998,BruCap,10,F,3548,1656 +1998,BruCap,11,M,3672,1630 +1998,BruCap,11,F,3431,1550 +1998,BruCap,12,M,3760,1472 +1998,BruCap,12,F,3365,1395 +1998,BruCap,13,M,3758,1491 +1998,BruCap,13,F,3491,1569 +1998,BruCap,14,M,3580,1535 +1998,BruCap,14,F,3452,1515 +1998,BruCap,15,M,3484,1798 +1998,BruCap,15,F,3335,1720 +1998,BruCap,16,M,3484,1969 +1998,BruCap,16,F,3325,1851 +1998,BruCap,17,M,3377,2015 +1998,BruCap,17,F,3318,2073 +1998,BruCap,18,M,3636,1822 +1998,BruCap,18,F,3459,1855 +1998,BruCap,19,M,3775,1642 +1998,BruCap,19,F,3909,1898 +1998,BruCap,20,M,3918,1733 +1998,BruCap,20,F,3991,1922 +1998,BruCap,21,M,3899,1846 +1998,BruCap,21,F,4076,2112 +1998,BruCap,22,M,4099,1896 +1998,BruCap,22,F,4094,2239 +1998,BruCap,23,M,4122,2226 +1998,BruCap,23,F,4315,2488 +1998,BruCap,24,M,4611,2460 +1998,BruCap,24,F,4830,2767 +1998,BruCap,25,M,4899,2894 +1998,BruCap,25,F,5141,3063 +1998,BruCap,26,M,5094,3133 +1998,BruCap,26,F,5225,3192 +1998,BruCap,27,M,5108,3383 +1998,BruCap,27,F,5153,3191 +1998,BruCap,28,M,5010,3462 +1998,BruCap,28,F,4967,3363 +1998,BruCap,29,M,4880,3542 +1998,BruCap,29,F,4789,3242 +1998,BruCap,30,M,4839,3369 +1998,BruCap,30,F,4697,3229 +1998,BruCap,31,M,4733,3607 +1998,BruCap,31,F,4618,3300 +1998,BruCap,32,M,4873,3572 +1998,BruCap,32,F,4649,3314 +1998,BruCap,33,M,4681,3615 +1998,BruCap,33,F,4579,3332 +1998,BruCap,34,M,4678,3291 +1998,BruCap,34,F,4528,2993 +1998,BruCap,35,M,4306,3274 +1998,BruCap,35,F,4356,2929 +1998,BruCap,36,M,4323,2989 +1998,BruCap,36,F,4418,2803 +1998,BruCap,37,M,4401,2982 +1998,BruCap,37,F,4509,2818 +1998,BruCap,38,M,4371,2735 +1998,BruCap,38,F,4494,2556 +1998,BruCap,39,M,4245,2558 +1998,BruCap,39,F,4472,2459 +1998,BruCap,40,M,4246,2306 +1998,BruCap,40,F,4425,2309 +1998,BruCap,41,M,4077,2449 +1998,BruCap,41,F,4406,2313 +1998,BruCap,42,M,4148,2352 +1998,BruCap,42,F,4397,2221 +1998,BruCap,43,M,4142,2105 +1998,BruCap,43,F,4323,2118 +1998,BruCap,44,M,4164,2077 +1998,BruCap,44,F,4437,1950 +1998,BruCap,45,M,4229,2056 +1998,BruCap,45,F,4446,1942 +1998,BruCap,46,M,4033,1887 +1998,BruCap,46,F,4373,1713 +1998,BruCap,47,M,3948,1980 +1998,BruCap,47,F,4458,1842 +1998,BruCap,48,M,3953,1789 +1998,BruCap,48,F,4437,1592 +1998,BruCap,49,M,4103,1789 +1998,BruCap,49,F,4520,1609 +1998,BruCap,50,M,4108,1736 +1998,BruCap,50,F,4700,1513 +1998,BruCap,51,M,4196,1592 +1998,BruCap,51,F,4577,1466 +1998,BruCap,52,M,3550,1444 +1998,BruCap,52,F,3950,1340 +1998,BruCap,53,M,3669,1504 +1998,BruCap,53,F,4245,1309 +1998,BruCap,54,M,3550,1354 +1998,BruCap,54,F,4036,1207 +1998,BruCap,55,M,3058,1395 +1998,BruCap,55,F,3468,1201 +1998,BruCap,56,M,2680,1199 +1998,BruCap,56,F,3121,1040 +1998,BruCap,57,M,2973,1468 +1998,BruCap,57,F,3400,1325 +1998,BruCap,58,M,3139,1307 +1998,BruCap,58,F,3746,1138 +1998,BruCap,59,M,3103,1326 +1998,BruCap,59,F,3670,1052 +1998,BruCap,60,M,3063,1225 +1998,BruCap,60,F,3628,992 +1998,BruCap,61,M,2947,1206 +1998,BruCap,61,F,3572,1013 +1998,BruCap,62,M,2927,1071 +1998,BruCap,62,F,3632,979 +1998,BruCap,63,M,3110,1036 +1998,BruCap,63,F,3692,850 +1998,BruCap,64,M,3003,952 +1998,BruCap,64,F,3905,761 +1998,BruCap,65,M,3168,935 +1998,BruCap,65,F,4114,772 +1998,BruCap,66,M,3226,759 +1998,BruCap,66,F,4199,715 +1998,BruCap,67,M,3136,862 +1998,BruCap,67,F,4557,760 +1998,BruCap,68,M,3033,697 +1998,BruCap,68,F,4346,568 +1998,BruCap,69,M,3025,625 +1998,BruCap,69,F,4306,596 +1998,BruCap,70,M,2920,552 +1998,BruCap,70,F,4356,509 +1998,BruCap,71,M,2977,509 +1998,BruCap,71,F,4508,481 +1998,BruCap,72,M,2958,467 +1998,BruCap,72,F,4602,446 +1998,BruCap,73,M,3033,358 +1998,BruCap,73,F,4700,423 +1998,BruCap,74,M,2831,376 +1998,BruCap,74,F,4808,396 +1998,BruCap,75,M,2729,333 +1998,BruCap,75,F,4737,356 +1998,BruCap,76,M,2861,310 +1998,BruCap,76,F,4805,307 +1998,BruCap,77,M,2609,267 +1998,BruCap,77,F,4827,377 +1998,BruCap,78,M,1926,154 +1998,BruCap,78,F,3376,239 +1998,BruCap,79,M,1139,127 +1998,BruCap,79,F,2450,170 +1998,BruCap,80,M,1066,117 +1998,BruCap,80,F,2325,169 +1998,BruCap,81,M,1071,93 +1998,BruCap,81,F,2453,159 +1998,BruCap,82,M,1249,96 +1998,BruCap,82,F,2812,163 +1998,BruCap,83,M,1343,100 +1998,BruCap,83,F,3236,176 +1998,BruCap,84,M,1150,78 +1998,BruCap,84,F,2941,160 +1998,BruCap,85,M,984,64 +1998,BruCap,85,F,2716,156 +1998,BruCap,86,M,809,60 +1998,BruCap,86,F,2378,110 +1998,BruCap,87,M,651,57 +1998,BruCap,87,F,2174,125 +1998,BruCap,88,M,525,32 +1998,BruCap,88,F,1798,104 +1998,BruCap,89,M,445,28 +1998,BruCap,89,F,1579,67 +1998,BruCap,90,M,353,30 +1998,BruCap,90,F,1320,64 +1998,BruCap,91,M,250,14 +1998,BruCap,91,F,1067,57 +1998,BruCap,92,M,184,10 +1998,BruCap,92,F,858,48 +1998,BruCap,93,M,152,15 +1998,BruCap,93,F,658,30 +1998,BruCap,94,M,93,4 +1998,BruCap,94,F,501,38 +1998,BruCap,95,M,74,7 +1998,BruCap,95,F,390,29 +1998,BruCap,96,M,54,5 +1998,BruCap,96,F,282,20 +1998,BruCap,97,M,23,6 +1998,BruCap,97,F,171,11 +1998,BruCap,98,M,17,2 +1998,BruCap,98,F,132,4 +1998,BruCap,99,M,10,3 +1998,BruCap,99,F,83,12 +1998,BruCap,100,M,6,2 +1998,BruCap,100,F,43,7 +1998,BruCap,101,M,7,0 +1998,BruCap,101,F,30,4 +1998,BruCap,102,M,3,0 +1998,BruCap,102,F,23,4 +1998,BruCap,103,M,2,0 +1998,BruCap,103,F,10,1 +1998,BruCap,104,M,2,1 +1998,BruCap,104,F,9,0 +1998,BruCap,105,M,0,0 +1998,BruCap,105,F,5,0 +1998,BruCap,106,M,0,0 +1998,BruCap,106,F,2,0 +1998,BruCap,107,M,1,0 +1998,BruCap,107,F,0,1 +1998,BruCap,108,M,0,0 +1998,BruCap,108,F,0,0 +1998,BruCap,109,M,0,0 +1998,BruCap,109,F,0,0 +1998,BruCap,110,M,0,0 +1998,BruCap,110,F,0,0 +1998,BruCap,111,M,0,0 +1998,BruCap,111,F,0,0 +1998,BruCap,112,M,0,0 +1998,BruCap,112,F,0,0 +1998,BruCap,113,M,0,0 +1998,BruCap,113,F,0,1 +1998,BruCap,114,M,0,0 +1998,BruCap,114,F,0,0 +1998,BruCap,115,M,0,0 +1998,BruCap,115,F,0,0 +1998,BruCap,116,M,0,0 +1998,BruCap,116,F,0,0 +1998,BruCap,117,M,0,0 +1998,BruCap,117,F,0,0 +1998,BruCap,118,M,0,0 +1998,BruCap,118,F,0,0 +1998,BruCap,119,M,0,0 +1998,BruCap,119,F,0,0 +1998,BruCap,120,M,0,0 +1998,BruCap,120,F,0,0 +1998,Fla,0,M,31001,1802 +1998,Fla,0,F,29769,1737 +1998,Fla,1,M,31218,1774 +1998,Fla,1,F,29955,1744 +1998,Fla,2,M,31430,1855 +1998,Fla,2,F,30037,1777 +1998,Fla,3,M,31804,1935 +1998,Fla,3,F,30358,1739 +1998,Fla,4,M,33213,1894 +1998,Fla,4,F,32198,1820 +1998,Fla,5,M,34519,1904 +1998,Fla,5,F,33029,1910 +1998,Fla,6,M,35012,2009 +1998,Fla,6,F,33223,1882 +1998,Fla,7,M,34665,1879 +1998,Fla,7,F,32989,1925 +1998,Fla,8,M,33588,1864 +1998,Fla,8,F,31889,1811 +1998,Fla,9,M,33147,1891 +1998,Fla,9,F,31702,1792 +1998,Fla,10,M,32903,1782 +1998,Fla,10,F,31158,1720 +1998,Fla,11,M,33090,1733 +1998,Fla,11,F,31234,1569 +1998,Fla,12,M,32266,1559 +1998,Fla,12,F,30790,1526 +1998,Fla,13,M,33031,1615 +1998,Fla,13,F,31448,1519 +1998,Fla,14,M,33936,1617 +1998,Fla,14,F,32467,1656 +1998,Fla,15,M,34715,1825 +1998,Fla,15,F,32788,1746 +1998,Fla,16,M,35849,1946 +1998,Fla,16,F,33544,1957 +1998,Fla,17,M,35269,2210 +1998,Fla,17,F,33860,2112 +1998,Fla,18,M,36067,1848 +1998,Fla,18,F,33919,1874 +1998,Fla,19,M,35411,1565 +1998,Fla,19,F,33984,1816 +1998,Fla,20,M,34781,1519 +1998,Fla,20,F,33583,1880 +1998,Fla,21,M,34154,1613 +1998,Fla,21,F,32508,2045 +1998,Fla,22,M,33275,1677 +1998,Fla,22,F,31638,2135 +1998,Fla,23,M,34512,1969 +1998,Fla,23,F,32955,2445 +1998,Fla,24,M,35724,2290 +1998,Fla,24,F,34065,2574 +1998,Fla,25,M,37115,2541 +1998,Fla,25,F,35669,2808 +1998,Fla,26,M,38526,2798 +1998,Fla,26,F,37557,2936 +1998,Fla,27,M,39773,2905 +1998,Fla,27,F,38229,3065 +1998,Fla,28,M,39657,3118 +1998,Fla,28,F,38216,2970 +1998,Fla,29,M,40179,3080 +1998,Fla,29,F,38843,2944 +1998,Fla,30,M,41801,3031 +1998,Fla,30,F,39753,2889 +1998,Fla,31,M,43001,3403 +1998,Fla,31,F,41649,3134 +1998,Fla,32,M,44664,3339 +1998,Fla,32,F,42944,2983 +1998,Fla,33,M,46492,3443 +1998,Fla,33,F,45212,3054 +1998,Fla,34,M,46303,3287 +1998,Fla,34,F,44825,2845 +1998,Fla,35,M,45845,3310 +1998,Fla,35,F,44303,2707 +1998,Fla,36,M,45618,3088 +1998,Fla,36,F,44778,2536 +1998,Fla,37,M,44630,3135 +1998,Fla,37,F,43490,2606 +1998,Fla,38,M,45605,2833 +1998,Fla,38,F,44457,2440 +1998,Fla,39,M,44770,2899 +1998,Fla,39,F,43284,2290 +1998,Fla,40,M,44258,2750 +1998,Fla,40,F,42777,2094 +1998,Fla,41,M,42938,2684 +1998,Fla,41,F,42124,2175 +1998,Fla,42,M,42417,2641 +1998,Fla,42,F,41805,1971 +1998,Fla,43,M,41678,2528 +1998,Fla,43,F,40724,1913 +1998,Fla,44,M,40868,2237 +1998,Fla,44,F,39445,1782 +1998,Fla,45,M,40765,2316 +1998,Fla,45,F,39251,1705 +1998,Fla,46,M,38916,2239 +1998,Fla,46,F,37791,1590 +1998,Fla,47,M,38335,2350 +1998,Fla,47,F,37712,1666 +1998,Fla,48,M,38638,2369 +1998,Fla,48,F,37486,1665 +1998,Fla,49,M,38512,2287 +1998,Fla,49,F,37972,1554 +1998,Fla,50,M,38327,2218 +1998,Fla,50,F,37562,1580 +1998,Fla,51,M,39312,2231 +1998,Fla,51,F,38175,1462 +1998,Fla,52,M,34859,1910 +1998,Fla,52,F,34431,1304 +1998,Fla,53,M,34611,1841 +1998,Fla,53,F,34241,1384 +1998,Fla,54,M,33024,1823 +1998,Fla,54,F,32830,1272 +1998,Fla,55,M,28774,1693 +1998,Fla,55,F,28618,1272 +1998,Fla,56,M,25838,1704 +1998,Fla,56,F,26334,1127 +1998,Fla,57,M,28511,1762 +1998,Fla,57,F,29201,1327 +1998,Fla,58,M,31131,1687 +1998,Fla,58,F,32740,1095 +1998,Fla,59,M,32218,1644 +1998,Fla,59,F,33343,1084 +1998,Fla,60,M,31166,1460 +1998,Fla,60,F,32231,1016 +1998,Fla,61,M,30058,1419 +1998,Fla,61,F,31673,957 +1998,Fla,62,M,29853,1324 +1998,Fla,62,F,31630,898 +1998,Fla,63,M,29818,1298 +1998,Fla,63,F,32300,937 +1998,Fla,64,M,29777,1263 +1998,Fla,64,F,32094,880 +1998,Fla,65,M,30203,1180 +1998,Fla,65,F,33445,797 +1998,Fla,66,M,29872,1061 +1998,Fla,66,F,33424,651 +1998,Fla,67,M,29033,1035 +1998,Fla,67,F,33164,776 +1998,Fla,68,M,26643,886 +1998,Fla,68,F,30945,681 +1998,Fla,69,M,25549,863 +1998,Fla,69,F,30072,685 +1998,Fla,70,M,24315,768 +1998,Fla,70,F,28960,575 +1998,Fla,71,M,23435,716 +1998,Fla,71,F,29247,626 +1998,Fla,72,M,22987,665 +1998,Fla,72,F,28705,576 +1998,Fla,73,M,21799,655 +1998,Fla,73,F,27932,520 +1998,Fla,74,M,20722,623 +1998,Fla,74,F,27456,525 +1998,Fla,75,M,18765,517 +1998,Fla,75,F,25695,452 +1998,Fla,76,M,17779,492 +1998,Fla,76,F,25222,431 +1998,Fla,77,M,16633,422 +1998,Fla,77,F,24245,409 +1998,Fla,78,M,11965,304 +1998,Fla,78,F,17981,262 +1998,Fla,79,M,7394,216 +1998,Fla,79,F,12163,228 +1998,Fla,80,M,6695,205 +1998,Fla,80,F,11680,205 +1998,Fla,81,M,7197,186 +1998,Fla,81,F,12517,206 +1998,Fla,82,M,7921,168 +1998,Fla,82,F,14283,217 +1998,Fla,83,M,7892,147 +1998,Fla,83,F,15471,206 +1998,Fla,84,M,6857,131 +1998,Fla,84,F,14359,212 +1998,Fla,85,M,5890,110 +1998,Fla,85,F,12735,171 +1998,Fla,86,M,4675,100 +1998,Fla,86,F,10956,126 +1998,Fla,87,M,4003,53 +1998,Fla,87,F,9719,113 +1998,Fla,88,M,3061,58 +1998,Fla,88,F,8208,133 +1998,Fla,89,M,2433,54 +1998,Fla,89,F,7061,83 +1998,Fla,90,M,1924,28 +1998,Fla,90,F,5743,72 +1998,Fla,91,M,1380,32 +1998,Fla,91,F,4468,55 +1998,Fla,92,M,1066,23 +1998,Fla,92,F,3593,40 +1998,Fla,93,M,792,14 +1998,Fla,93,F,2771,50 +1998,Fla,94,M,509,11 +1998,Fla,94,F,1924,20 +1998,Fla,95,M,320,8 +1998,Fla,95,F,1415,14 +1998,Fla,96,M,205,7 +1998,Fla,96,F,981,21 +1998,Fla,97,M,139,6 +1998,Fla,97,F,628,9 +1998,Fla,98,M,96,2 +1998,Fla,98,F,379,9 +1998,Fla,99,M,42,1 +1998,Fla,99,F,238,5 +1998,Fla,100,M,39,3 +1998,Fla,100,F,162,3 +1998,Fla,101,M,18,0 +1998,Fla,101,F,106,2 +1998,Fla,102,M,11,0 +1998,Fla,102,F,62,0 +1998,Fla,103,M,4,0 +1998,Fla,103,F,27,0 +1998,Fla,104,M,1,0 +1998,Fla,104,F,9,0 +1998,Fla,105,M,1,0 +1998,Fla,105,F,3,0 +1998,Fla,106,M,0,0 +1998,Fla,106,F,2,0 +1998,Fla,107,M,1,0 +1998,Fla,107,F,1,0 +1998,Fla,108,M,0,0 +1998,Fla,108,F,1,0 +1998,Fla,109,M,0,0 +1998,Fla,109,F,1,0 +1998,Fla,110,M,0,0 +1998,Fla,110,F,0,0 +1998,Fla,111,M,0,0 +1998,Fla,111,F,0,0 +1998,Fla,112,M,0,0 +1998,Fla,112,F,0,0 +1998,Fla,113,M,0,0 +1998,Fla,113,F,0,0 +1998,Fla,114,M,0,0 +1998,Fla,114,F,0,0 +1998,Fla,115,M,0,0 +1998,Fla,115,F,0,0 +1998,Fla,116,M,0,0 +1998,Fla,116,F,0,0 +1998,Fla,117,M,0,0 +1998,Fla,117,F,0,0 +1998,Fla,118,M,0,0 +1998,Fla,118,F,0,0 +1998,Fla,119,M,0,0 +1998,Fla,119,F,0,0 +1998,Fla,120,M,0,0 +1998,Fla,120,F,0,0 +1998,Wal,0,M,18532,1055 +1998,Wal,0,F,17907,914 +1998,Wal,1,M,18909,1051 +1998,Wal,1,F,18195,949 +1998,Wal,2,M,18615,1036 +1998,Wal,2,F,17860,1001 +1998,Wal,3,M,18788,1180 +1998,Wal,3,F,18026,1031 +1998,Wal,4,M,19762,1189 +1998,Wal,4,F,18604,1176 +1998,Wal,5,M,20708,1279 +1998,Wal,5,F,19762,1267 +1998,Wal,6,M,21253,1344 +1998,Wal,6,F,20454,1318 +1998,Wal,7,M,20971,1387 +1998,Wal,7,F,20141,1309 +1998,Wal,8,M,21039,1380 +1998,Wal,8,F,20078,1353 +1998,Wal,9,M,20906,1470 +1998,Wal,9,F,19812,1355 +1998,Wal,10,M,20126,1473 +1998,Wal,10,F,19136,1405 +1998,Wal,11,M,20198,1487 +1998,Wal,11,F,19078,1394 +1998,Wal,12,M,19428,1389 +1998,Wal,12,F,18581,1307 +1998,Wal,13,M,19148,1397 +1998,Wal,13,F,18408,1370 +1998,Wal,14,M,19039,1486 +1998,Wal,14,F,17708,1365 +1998,Wal,15,M,19186,1629 +1998,Wal,15,F,18356,1612 +1998,Wal,16,M,19273,1737 +1998,Wal,16,F,18790,1701 +1998,Wal,17,M,19267,1874 +1998,Wal,17,F,18667,1851 +1998,Wal,18,M,19188,1792 +1998,Wal,18,F,18055,1856 +1998,Wal,19,M,18883,1749 +1998,Wal,19,F,18079,1808 +1998,Wal,20,M,19174,1741 +1998,Wal,20,F,18177,1923 +1998,Wal,21,M,19266,1835 +1998,Wal,21,F,18447,1936 +1998,Wal,22,M,19322,1906 +1998,Wal,22,F,18576,2026 +1998,Wal,23,M,19808,2249 +1998,Wal,23,F,18847,2299 +1998,Wal,24,M,20295,2602 +1998,Wal,24,F,19425,2478 +1998,Wal,25,M,20649,2825 +1998,Wal,25,F,19766,2720 +1998,Wal,26,M,20822,2883 +1998,Wal,26,F,20126,2802 +1998,Wal,27,M,20241,3022 +1998,Wal,27,F,19580,2796 +1998,Wal,28,M,20107,3108 +1998,Wal,28,F,19701,2909 +1998,Wal,29,M,19661,3200 +1998,Wal,29,F,19528,3087 +1998,Wal,30,M,20165,3210 +1998,Wal,30,F,19945,2962 +1998,Wal,31,M,20568,3640 +1998,Wal,31,F,20577,3272 +1998,Wal,32,M,21297,3819 +1998,Wal,32,F,21314,3246 +1998,Wal,33,M,22291,3763 +1998,Wal,33,F,22268,3275 +1998,Wal,34,M,21921,3776 +1998,Wal,34,F,22279,3200 +1998,Wal,35,M,21432,3700 +1998,Wal,35,F,21874,3044 +1998,Wal,36,M,22077,3642 +1998,Wal,36,F,22576,3146 +1998,Wal,37,M,21936,3951 +1998,Wal,37,F,22123,2999 +1998,Wal,38,M,22171,3745 +1998,Wal,38,F,22949,2992 +1998,Wal,39,M,21775,3771 +1998,Wal,39,F,22565,2891 +1998,Wal,40,M,21592,3737 +1998,Wal,40,F,22179,2771 +1998,Wal,41,M,21193,3844 +1998,Wal,41,F,21986,2837 +1998,Wal,42,M,20990,3671 +1998,Wal,42,F,21997,2748 +1998,Wal,43,M,20905,3558 +1998,Wal,43,F,21805,2646 +1998,Wal,44,M,21022,3401 +1998,Wal,44,F,21634,2411 +1998,Wal,45,M,20868,3269 +1998,Wal,45,F,21279,2417 +1998,Wal,46,M,20094,3139 +1998,Wal,46,F,21026,2325 +1998,Wal,47,M,20987,3190 +1998,Wal,47,F,21232,2407 +1998,Wal,48,M,20862,3085 +1998,Wal,48,F,21218,2215 +1998,Wal,49,M,21369,3038 +1998,Wal,49,F,21934,2362 +1998,Wal,50,M,21406,3011 +1998,Wal,50,F,21794,2137 +1998,Wal,51,M,20840,2831 +1998,Wal,51,F,21626,2012 +1998,Wal,52,M,15498,2254 +1998,Wal,52,F,16570,1679 +1998,Wal,53,M,15474,2247 +1998,Wal,53,F,16244,1731 +1998,Wal,54,M,14437,1998 +1998,Wal,54,F,15354,1575 +1998,Wal,55,M,12579,1924 +1998,Wal,55,F,13405,1542 +1998,Wal,56,M,11724,1851 +1998,Wal,56,F,12707,1486 +1998,Wal,57,M,13068,2168 +1998,Wal,57,F,14213,1761 +1998,Wal,58,M,14167,1986 +1998,Wal,58,F,15718,1732 +1998,Wal,59,M,14370,1851 +1998,Wal,59,F,16049,1734 +1998,Wal,60,M,13689,1904 +1998,Wal,60,F,15114,1592 +1998,Wal,61,M,13322,1857 +1998,Wal,61,F,15125,1612 +1998,Wal,62,M,13081,1794 +1998,Wal,62,F,15117,1644 +1998,Wal,63,M,13706,1714 +1998,Wal,63,F,15755,1648 +1998,Wal,64,M,13708,1736 +1998,Wal,64,F,15784,1677 +1998,Wal,65,M,14349,1802 +1998,Wal,65,F,17168,1582 +1998,Wal,66,M,14680,1616 +1998,Wal,66,F,17676,1585 +1998,Wal,67,M,14369,1715 +1998,Wal,67,F,17657,1643 +1998,Wal,68,M,13425,1611 +1998,Wal,68,F,16853,1552 +1998,Wal,69,M,12914,1559 +1998,Wal,69,F,17051,1488 +1998,Wal,70,M,12504,1556 +1998,Wal,70,F,16565,1525 +1998,Wal,71,M,12123,1554 +1998,Wal,71,F,16599,1527 +1998,Wal,72,M,11901,1423 +1998,Wal,72,F,16991,1471 +1998,Wal,73,M,11289,1340 +1998,Wal,73,F,16507,1385 +1998,Wal,74,M,10546,1279 +1998,Wal,74,F,15947,1298 +1998,Wal,75,M,9995,1102 +1998,Wal,75,F,15723,1213 +1998,Wal,76,M,9651,947 +1998,Wal,76,F,15741,1118 +1998,Wal,77,M,8877,798 +1998,Wal,77,F,15140,1011 +1998,Wal,78,M,5960,467 +1998,Wal,78,F,10703,683 +1998,Wal,79,M,3822,351 +1998,Wal,79,F,7288,452 +1998,Wal,80,M,3367,292 +1998,Wal,80,F,6781,406 +1998,Wal,81,M,3565,276 +1998,Wal,81,F,6983,440 +1998,Wal,82,M,3681,273 +1998,Wal,82,F,7969,507 +1998,Wal,83,M,3864,281 +1998,Wal,83,F,8937,521 +1998,Wal,84,M,3305,269 +1998,Wal,84,F,7976,485 +1998,Wal,85,M,2738,225 +1998,Wal,85,F,7334,427 +1998,Wal,86,M,2086,133 +1998,Wal,86,F,6148,348 +1998,Wal,87,M,1791,108 +1998,Wal,87,F,5486,309 +1998,Wal,88,M,1372,71 +1998,Wal,88,F,4673,268 +1998,Wal,89,M,1065,77 +1998,Wal,89,F,4120,218 +1998,Wal,90,M,821,37 +1998,Wal,90,F,3397,143 +1998,Wal,91,M,647,35 +1998,Wal,91,F,2602,135 +1998,Wal,92,M,445,32 +1998,Wal,92,F,1960,115 +1998,Wal,93,M,312,18 +1998,Wal,93,F,1547,84 +1998,Wal,94,M,228,17 +1998,Wal,94,F,1146,49 +1998,Wal,95,M,153,13 +1998,Wal,95,F,757,56 +1998,Wal,96,M,99,7 +1998,Wal,96,F,612,33 +1998,Wal,97,M,50,6 +1998,Wal,97,F,364,21 +1998,Wal,98,M,37,2 +1998,Wal,98,F,221,8 +1998,Wal,99,M,21,4 +1998,Wal,99,F,130,8 +1998,Wal,100,M,11,2 +1998,Wal,100,F,99,9 +1998,Wal,101,M,5,0 +1998,Wal,101,F,51,3 +1998,Wal,102,M,3,0 +1998,Wal,102,F,40,0 +1998,Wal,103,M,2,0 +1998,Wal,103,F,12,1 +1998,Wal,104,M,2,0 +1998,Wal,104,F,8,0 +1998,Wal,105,M,0,0 +1998,Wal,105,F,7,1 +1998,Wal,106,M,0,0 +1998,Wal,106,F,4,0 +1998,Wal,107,M,0,0 +1998,Wal,107,F,2,1 +1998,Wal,108,M,0,0 +1998,Wal,108,F,1,0 +1998,Wal,109,M,0,0 +1998,Wal,109,F,0,0 +1998,Wal,110,M,0,0 +1998,Wal,110,F,0,0 +1998,Wal,111,M,0,0 +1998,Wal,111,F,0,0 +1998,Wal,112,M,0,0 +1998,Wal,112,F,0,0 +1998,Wal,113,M,0,0 +1998,Wal,113,F,0,0 +1998,Wal,114,M,0,0 +1998,Wal,114,F,0,0 +1998,Wal,115,M,0,0 +1998,Wal,115,F,0,0 +1998,Wal,116,M,0,0 +1998,Wal,116,F,0,0 +1998,Wal,117,M,0,0 +1998,Wal,117,F,0,0 +1998,Wal,118,M,0,0 +1998,Wal,118,F,0,0 +1998,Wal,119,M,0,0 +1998,Wal,119,F,0,0 +1998,Wal,120,M,0,0 +1998,Wal,120,F,0,0 +1999,BruCap,0,M,4890,1591 +1999,BruCap,0,F,4658,1647 +1999,BruCap,1,M,4832,1691 +1999,BruCap,1,F,4405,1579 +1999,BruCap,2,M,4444,1640 +1999,BruCap,2,F,4396,1612 +1999,BruCap,3,M,4279,1723 +1999,BruCap,3,F,4171,1562 +1999,BruCap,4,M,4299,1733 +1999,BruCap,4,F,3858,1628 +1999,BruCap,5,M,4217,1597 +1999,BruCap,5,F,3967,1539 +1999,BruCap,6,M,4182,1700 +1999,BruCap,6,F,4039,1616 +1999,BruCap,7,M,4106,1637 +1999,BruCap,7,F,3988,1528 +1999,BruCap,8,M,4132,1673 +1999,BruCap,8,F,3871,1587 +1999,BruCap,9,M,3920,1591 +1999,BruCap,9,F,3835,1537 +1999,BruCap,10,M,3940,1597 +1999,BruCap,10,F,3708,1513 +1999,BruCap,11,M,3818,1572 +1999,BruCap,11,F,3682,1532 +1999,BruCap,12,M,3858,1398 +1999,BruCap,12,F,3662,1344 +1999,BruCap,13,M,3839,1366 +1999,BruCap,13,F,3421,1337 +1999,BruCap,14,M,3797,1426 +1999,BruCap,14,F,3571,1499 +1999,BruCap,15,M,3668,1483 +1999,BruCap,15,F,3539,1427 +1999,BruCap,16,M,3594,1695 +1999,BruCap,16,F,3456,1609 +1999,BruCap,17,M,3624,1846 +1999,BruCap,17,F,3445,1800 +1999,BruCap,18,M,3719,1724 +1999,BruCap,18,F,3725,1873 +1999,BruCap,19,M,3986,1631 +1999,BruCap,19,F,3823,1740 +1999,BruCap,20,M,3950,1643 +1999,BruCap,20,F,4164,1982 +1999,BruCap,21,M,4083,1789 +1999,BruCap,21,F,4188,2053 +1999,BruCap,22,M,4064,1926 +1999,BruCap,22,F,4306,2237 +1999,BruCap,23,M,4329,1996 +1999,BruCap,23,F,4400,2377 +1999,BruCap,24,M,4416,2360 +1999,BruCap,24,F,4676,2624 +1999,BruCap,25,M,4953,2641 +1999,BruCap,25,F,5124,2882 +1999,BruCap,26,M,5157,3003 +1999,BruCap,26,F,5267,3092 +1999,BruCap,27,M,5233,3181 +1999,BruCap,27,F,5223,3308 +1999,BruCap,28,M,5182,3417 +1999,BruCap,28,F,5169,3223 +1999,BruCap,29,M,4989,3451 +1999,BruCap,29,F,4922,3328 +1999,BruCap,30,M,4852,3547 +1999,BruCap,30,F,4730,3184 +1999,BruCap,31,M,4777,3349 +1999,BruCap,31,F,4596,3147 +1999,BruCap,32,M,4692,3529 +1999,BruCap,32,F,4580,3202 +1999,BruCap,33,M,4879,3439 +1999,BruCap,33,F,4639,3162 +1999,BruCap,34,M,4761,3435 +1999,BruCap,34,F,4563,3195 +1999,BruCap,35,M,4664,3167 +1999,BruCap,35,F,4530,2846 +1999,BruCap,36,M,4387,3153 +1999,BruCap,36,F,4370,2772 +1999,BruCap,37,M,4371,2838 +1999,BruCap,37,F,4448,2679 +1999,BruCap,38,M,4486,2786 +1999,BruCap,38,F,4543,2696 +1999,BruCap,39,M,4454,2564 +1999,BruCap,39,F,4551,2443 +1999,BruCap,40,M,4310,2414 +1999,BruCap,40,F,4501,2330 +1999,BruCap,41,M,4298,2172 +1999,BruCap,41,F,4468,2218 +1999,BruCap,42,M,4156,2281 +1999,BruCap,42,F,4456,2221 +1999,BruCap,43,M,4210,2213 +1999,BruCap,43,F,4445,2118 +1999,BruCap,44,M,4200,2003 +1999,BruCap,44,F,4345,2037 +1999,BruCap,45,M,4231,1958 +1999,BruCap,45,F,4483,1847 +1999,BruCap,46,M,4283,1940 +1999,BruCap,46,F,4489,1883 +1999,BruCap,47,M,4076,1794 +1999,BruCap,47,F,4375,1634 +1999,BruCap,48,M,3976,1869 +1999,BruCap,48,F,4460,1794 +1999,BruCap,49,M,3972,1706 +1999,BruCap,49,F,4405,1546 +1999,BruCap,50,M,4105,1735 +1999,BruCap,50,F,4495,1586 +1999,BruCap,51,M,4108,1681 +1999,BruCap,51,F,4681,1479 +1999,BruCap,52,M,4186,1531 +1999,BruCap,52,F,4511,1432 +1999,BruCap,53,M,3536,1394 +1999,BruCap,53,F,3960,1276 +1999,BruCap,54,M,3655,1446 +1999,BruCap,54,F,4238,1263 +1999,BruCap,55,M,3564,1307 +1999,BruCap,55,F,3992,1174 +1999,BruCap,56,M,3033,1349 +1999,BruCap,56,F,3433,1173 +1999,BruCap,57,M,2664,1148 +1999,BruCap,57,F,3073,999 +1999,BruCap,58,M,2951,1406 +1999,BruCap,58,F,3361,1296 +1999,BruCap,59,M,3099,1238 +1999,BruCap,59,F,3696,1099 +1999,BruCap,60,M,3055,1252 +1999,BruCap,60,F,3626,1018 +1999,BruCap,61,M,2972,1166 +1999,BruCap,61,F,3577,921 +1999,BruCap,62,M,2878,1149 +1999,BruCap,62,F,3525,983 +1999,BruCap,63,M,2866,1015 +1999,BruCap,63,F,3579,943 +1999,BruCap,64,M,3019,997 +1999,BruCap,64,F,3630,831 +1999,BruCap,65,M,2912,884 +1999,BruCap,65,F,3858,724 +1999,BruCap,66,M,3082,868 +1999,BruCap,66,F,4038,734 +1999,BruCap,67,M,3136,713 +1999,BruCap,67,F,4123,685 +1999,BruCap,68,M,3022,814 +1999,BruCap,68,F,4498,725 +1999,BruCap,69,M,2924,650 +1999,BruCap,69,F,4284,540 +1999,BruCap,70,M,2926,582 +1999,BruCap,70,F,4224,569 +1999,BruCap,71,M,2817,506 +1999,BruCap,71,F,4266,482 +1999,BruCap,72,M,2867,460 +1999,BruCap,72,F,4427,459 +1999,BruCap,73,M,2847,429 +1999,BruCap,73,F,4495,429 +1999,BruCap,74,M,2901,333 +1999,BruCap,74,F,4589,412 +1999,BruCap,75,M,2687,358 +1999,BruCap,75,F,4655,373 +1999,BruCap,76,M,2568,311 +1999,BruCap,76,F,4568,337 +1999,BruCap,77,M,2668,283 +1999,BruCap,77,F,4644,297 +1999,BruCap,78,M,2434,229 +1999,BruCap,78,F,4620,361 +1999,BruCap,79,M,1761,145 +1999,BruCap,79,F,3230,225 +1999,BruCap,80,M,1043,117 +1999,BruCap,80,F,2337,159 +1999,BruCap,81,M,977,112 +1999,BruCap,81,F,2202,158 +1999,BruCap,82,M,941,81 +1999,BruCap,82,F,2293,143 +1999,BruCap,83,M,1112,82 +1999,BruCap,83,F,2620,144 +1999,BruCap,84,M,1190,85 +1999,BruCap,84,F,2984,162 +1999,BruCap,85,M,1022,61 +1999,BruCap,85,F,2680,147 +1999,BruCap,86,M,843,57 +1999,BruCap,86,F,2417,140 +1999,BruCap,87,M,699,47 +1999,BruCap,87,F,2122,104 +1999,BruCap,88,M,550,51 +1999,BruCap,88,F,1929,115 +1999,BruCap,89,M,429,30 +1999,BruCap,89,F,1542,88 +1999,BruCap,90,M,362,22 +1999,BruCap,90,F,1352,58 +1999,BruCap,91,M,274,20 +1999,BruCap,91,F,1091,50 +1999,BruCap,92,M,193,8 +1999,BruCap,92,F,876,47 +1999,BruCap,93,M,142,9 +1999,BruCap,93,F,681,43 +1999,BruCap,94,M,120,13 +1999,BruCap,94,F,526,25 +1999,BruCap,95,M,75,3 +1999,BruCap,95,F,377,28 +1999,BruCap,96,M,51,7 +1999,BruCap,96,F,299,19 +1999,BruCap,97,M,37,5 +1999,BruCap,97,F,205,12 +1999,BruCap,98,M,12,6 +1999,BruCap,98,F,127,10 +1999,BruCap,99,M,14,0 +1999,BruCap,99,F,96,0 +1999,BruCap,100,M,5,2 +1999,BruCap,100,F,65,10 +1999,BruCap,101,M,4,1 +1999,BruCap,101,F,34,4 +1999,BruCap,102,M,4,0 +1999,BruCap,102,F,18,3 +1999,BruCap,103,M,1,0 +1999,BruCap,103,F,13,4 +1999,BruCap,104,M,1,0 +1999,BruCap,104,F,4,0 +1999,BruCap,105,M,0,1 +1999,BruCap,105,F,7,0 +1999,BruCap,106,M,0,0 +1999,BruCap,106,F,3,0 +1999,BruCap,107,M,0,0 +1999,BruCap,107,F,2,0 +1999,BruCap,108,M,1,0 +1999,BruCap,108,F,0,1 +1999,BruCap,109,M,0,0 +1999,BruCap,109,F,0,0 +1999,BruCap,110,M,0,0 +1999,BruCap,110,F,0,0 +1999,BruCap,111,M,0,0 +1999,BruCap,111,F,0,0 +1999,BruCap,112,M,0,0 +1999,BruCap,112,F,0,0 +1999,BruCap,113,M,0,0 +1999,BruCap,113,F,0,0 +1999,BruCap,114,M,0,0 +1999,BruCap,114,F,0,1 +1999,BruCap,115,M,0,0 +1999,BruCap,115,F,0,0 +1999,BruCap,116,M,0,0 +1999,BruCap,116,F,0,0 +1999,BruCap,117,M,0,0 +1999,BruCap,117,F,0,0 +1999,BruCap,118,M,0,0 +1999,BruCap,118,F,0,0 +1999,BruCap,119,M,0,0 +1999,BruCap,119,F,0,0 +1999,BruCap,120,M,0,0 +1999,BruCap,120,F,0,0 +1999,Fla,0,M,30556,1700 +1999,Fla,0,F,28843,1660 +1999,Fla,1,M,31231,1781 +1999,Fla,1,F,29998,1682 +1999,Fla,2,M,31426,1741 +1999,Fla,2,F,30120,1722 +1999,Fla,3,M,31607,1779 +1999,Fla,3,F,30216,1699 +1999,Fla,4,M,31957,1884 +1999,Fla,4,F,30498,1714 +1999,Fla,5,M,33385,1808 +1999,Fla,5,F,32380,1722 +1999,Fla,6,M,34662,1842 +1999,Fla,6,F,33195,1856 +1999,Fla,7,M,35154,1934 +1999,Fla,7,F,33358,1824 +1999,Fla,8,M,34790,1816 +1999,Fla,8,F,33146,1850 +1999,Fla,9,M,33720,1808 +1999,Fla,9,F,32027,1776 +1999,Fla,10,M,33311,1828 +1999,Fla,10,F,31835,1717 +1999,Fla,11,M,33054,1671 +1999,Fla,11,F,31296,1660 +1999,Fla,12,M,33365,1518 +1999,Fla,12,F,31437,1407 +1999,Fla,13,M,32356,1520 +1999,Fla,13,F,30871,1484 +1999,Fla,14,M,33108,1594 +1999,Fla,14,F,31506,1485 +1999,Fla,15,M,33963,1583 +1999,Fla,15,F,32536,1630 +1999,Fla,16,M,34759,1796 +1999,Fla,16,F,32864,1717 +1999,Fla,17,M,35948,1911 +1999,Fla,17,F,33654,1987 +1999,Fla,18,M,35744,1809 +1999,Fla,18,F,34291,1810 +1999,Fla,19,M,36319,1614 +1999,Fla,19,F,34225,1820 +1999,Fla,20,M,35515,1556 +1999,Fla,20,F,34056,1888 +1999,Fla,21,M,34791,1614 +1999,Fla,21,F,33630,2025 +1999,Fla,22,M,34134,1738 +1999,Fla,22,F,32510,2211 +1999,Fla,23,M,33206,1885 +1999,Fla,23,F,31589,2295 +1999,Fla,24,M,34398,2185 +1999,Fla,24,F,32889,2589 +1999,Fla,25,M,35535,2366 +1999,Fla,25,F,33941,2644 +1999,Fla,26,M,36968,2693 +1999,Fla,26,F,35636,2927 +1999,Fla,27,M,38512,2884 +1999,Fla,27,F,37592,2995 +1999,Fla,28,M,39729,2936 +1999,Fla,28,F,38230,3120 +1999,Fla,29,M,39695,3165 +1999,Fla,29,F,38304,3091 +1999,Fla,30,M,40212,3184 +1999,Fla,30,F,38894,3015 +1999,Fla,31,M,41810,3050 +1999,Fla,31,F,39797,2925 +1999,Fla,32,M,43064,3447 +1999,Fla,32,F,41658,3213 +1999,Fla,33,M,44722,3365 +1999,Fla,33,F,43018,3019 +1999,Fla,34,M,46563,3443 +1999,Fla,34,F,45260,3109 +1999,Fla,35,M,46376,3250 +1999,Fla,35,F,44891,2868 +1999,Fla,36,M,45824,3245 +1999,Fla,36,F,44366,2694 +1999,Fla,37,M,45629,3008 +1999,Fla,37,F,44788,2527 +1999,Fla,38,M,44620,3143 +1999,Fla,38,F,43533,2643 +1999,Fla,39,M,45632,2820 +1999,Fla,39,F,44464,2473 +1999,Fla,40,M,44781,2851 +1999,Fla,40,F,43337,2287 +1999,Fla,41,M,44199,2722 +1999,Fla,41,F,42751,2080 +1999,Fla,42,M,42908,2627 +1999,Fla,42,F,42137,2177 +1999,Fla,43,M,42371,2625 +1999,Fla,43,F,41783,1984 +1999,Fla,44,M,41610,2498 +1999,Fla,44,F,40701,1907 +1999,Fla,45,M,40783,2239 +1999,Fla,45,F,39394,1795 +1999,Fla,46,M,40713,2323 +1999,Fla,46,F,39215,1704 +1999,Fla,47,M,38835,2223 +1999,Fla,47,F,37751,1579 +1999,Fla,48,M,38241,2296 +1999,Fla,48,F,37660,1667 +1999,Fla,49,M,38480,2334 +1999,Fla,49,F,37433,1663 +1999,Fla,50,M,38394,2254 +1999,Fla,50,F,37886,1554 +1999,Fla,51,M,38152,2209 +1999,Fla,51,F,37458,1602 +1999,Fla,52,M,39146,2220 +1999,Fla,52,F,38081,1453 +1999,Fla,53,M,34685,1882 +1999,Fla,53,F,34339,1307 +1999,Fla,54,M,34425,1811 +1999,Fla,54,F,34129,1379 +1999,Fla,55,M,32822,1795 +1999,Fla,55,F,32741,1263 +1999,Fla,56,M,28579,1676 +1999,Fla,56,F,28502,1272 +1999,Fla,57,M,25653,1663 +1999,Fla,57,F,26256,1129 +1999,Fla,58,M,28278,1730 +1999,Fla,58,F,29061,1319 +1999,Fla,59,M,30860,1652 +1999,Fla,59,F,32589,1091 +1999,Fla,60,M,31889,1599 +1999,Fla,60,F,33207,1077 +1999,Fla,61,M,30847,1424 +1999,Fla,61,F,32035,1011 +1999,Fla,62,M,29685,1374 +1999,Fla,62,F,31491,954 +1999,Fla,63,M,29457,1300 +1999,Fla,63,F,31446,897 +1999,Fla,64,M,29396,1263 +1999,Fla,64,F,32061,912 +1999,Fla,65,M,29297,1217 +1999,Fla,65,F,31820,876 +1999,Fla,66,M,29610,1146 +1999,Fla,66,F,33126,792 +1999,Fla,67,M,29235,1039 +1999,Fla,67,F,33140,650 +1999,Fla,68,M,28370,993 +1999,Fla,68,F,32828,768 +1999,Fla,69,M,25934,856 +1999,Fla,69,F,30564,663 +1999,Fla,70,M,24819,832 +1999,Fla,70,F,29703,670 +1999,Fla,71,M,23501,743 +1999,Fla,71,F,28557,584 +1999,Fla,72,M,22574,686 +1999,Fla,72,F,28752,611 +1999,Fla,73,M,22107,645 +1999,Fla,73,F,28168,571 +1999,Fla,74,M,20795,624 +1999,Fla,74,F,27357,514 +1999,Fla,75,M,19731,595 +1999,Fla,75,F,26820,514 +1999,Fla,76,M,17803,484 +1999,Fla,76,F,24977,436 +1999,Fla,77,M,16748,458 +1999,Fla,77,F,24436,421 +1999,Fla,78,M,15617,396 +1999,Fla,78,F,23314,396 +1999,Fla,79,M,11118,282 +1999,Fla,79,F,17253,245 +1999,Fla,80,M,6807,198 +1999,Fla,80,F,11560,211 +1999,Fla,81,M,6105,184 +1999,Fla,81,F,11026,189 +1999,Fla,82,M,6486,167 +1999,Fla,82,F,11729,194 +1999,Fla,83,M,7066,150 +1999,Fla,83,F,13319,192 +1999,Fla,84,M,6913,130 +1999,Fla,84,F,14244,187 +1999,Fla,85,M,5956,113 +1999,Fla,85,F,13112,182 +1999,Fla,86,M,5048,101 +1999,Fla,86,F,11478,152 +1999,Fla,87,M,3962,83 +1999,Fla,87,F,9710,121 +1999,Fla,88,M,3272,44 +1999,Fla,88,F,8421,100 +1999,Fla,89,M,2478,46 +1999,Fla,89,F,7051,105 +1999,Fla,90,M,1936,45 +1999,Fla,90,F,6047,69 +1999,Fla,91,M,1514,27 +1999,Fla,91,F,4794,57 +1999,Fla,92,M,1034,20 +1999,Fla,92,F,3613,45 +1999,Fla,93,M,825,20 +1999,Fla,93,F,2876,35 +1999,Fla,94,M,574,11 +1999,Fla,94,F,2138,40 +1999,Fla,95,M,364,4 +1999,Fla,95,F,1481,17 +1999,Fla,96,M,226,5 +1999,Fla,96,F,1076,9 +1999,Fla,97,M,128,4 +1999,Fla,97,F,716,18 +1999,Fla,98,M,91,4 +1999,Fla,98,F,443,9 +1999,Fla,99,M,46,0 +1999,Fla,99,F,258,0 +1999,Fla,100,M,25,0 +1999,Fla,100,F,154,5 +1999,Fla,101,M,23,1 +1999,Fla,101,F,103,3 +1999,Fla,102,M,7,0 +1999,Fla,102,F,67,1 +1999,Fla,103,M,7,0 +1999,Fla,103,F,38,0 +1999,Fla,104,M,2,0 +1999,Fla,104,F,15,0 +1999,Fla,105,M,1,0 +1999,Fla,105,F,3,0 +1999,Fla,106,M,0,0 +1999,Fla,106,F,2,0 +1999,Fla,107,M,0,0 +1999,Fla,107,F,1,0 +1999,Fla,108,M,0,0 +1999,Fla,108,F,1,0 +1999,Fla,109,M,0,0 +1999,Fla,109,F,1,0 +1999,Fla,110,M,0,0 +1999,Fla,110,F,1,0 +1999,Fla,111,M,0,0 +1999,Fla,111,F,0,0 +1999,Fla,112,M,0,0 +1999,Fla,112,F,0,0 +1999,Fla,113,M,0,0 +1999,Fla,113,F,0,0 +1999,Fla,114,M,0,0 +1999,Fla,114,F,0,0 +1999,Fla,115,M,0,0 +1999,Fla,115,F,0,0 +1999,Fla,116,M,0,0 +1999,Fla,116,F,0,0 +1999,Fla,117,M,0,0 +1999,Fla,117,F,0,0 +1999,Fla,118,M,0,0 +1999,Fla,118,F,0,0 +1999,Fla,119,M,0,0 +1999,Fla,119,F,0,0 +1999,Fla,120,M,0,0 +1999,Fla,120,F,0,0 +1999,Wal,0,M,18629,895 +1999,Wal,0,F,17800,896 +1999,Wal,1,M,18769,1040 +1999,Wal,1,F,18115,921 +1999,Wal,2,M,19157,1048 +1999,Wal,2,F,18352,964 +1999,Wal,3,M,18787,995 +1999,Wal,3,F,18018,981 +1999,Wal,4,M,18946,1166 +1999,Wal,4,F,18129,1021 +1999,Wal,5,M,19849,1149 +1999,Wal,5,F,18700,1156 +1999,Wal,6,M,20832,1271 +1999,Wal,6,F,19874,1222 +1999,Wal,7,M,21363,1321 +1999,Wal,7,F,20577,1262 +1999,Wal,8,M,21066,1353 +1999,Wal,8,F,20243,1295 +1999,Wal,9,M,21162,1357 +1999,Wal,9,F,20175,1311 +1999,Wal,10,M,21011,1418 +1999,Wal,10,F,19896,1356 +1999,Wal,11,M,20257,1435 +1999,Wal,11,F,19268,1332 +1999,Wal,12,M,20342,1377 +1999,Wal,12,F,19189,1319 +1999,Wal,13,M,19477,1363 +1999,Wal,13,F,18650,1311 +1999,Wal,14,M,19191,1394 +1999,Wal,14,F,18466,1361 +1999,Wal,15,M,19093,1495 +1999,Wal,15,F,17751,1359 +1999,Wal,16,M,19266,1589 +1999,Wal,16,F,18419,1623 +1999,Wal,17,M,19318,1730 +1999,Wal,17,F,18822,1726 +1999,Wal,18,M,19467,1738 +1999,Wal,18,F,18844,1808 +1999,Wal,19,M,19326,1648 +1999,Wal,19,F,18179,1779 +1999,Wal,20,M,18911,1711 +1999,Wal,20,F,18119,1804 +1999,Wal,21,M,19126,1721 +1999,Wal,21,F,18194,1936 +1999,Wal,22,M,19209,1832 +1999,Wal,22,F,18390,1957 +1999,Wal,23,M,19178,1935 +1999,Wal,23,F,18397,2057 +1999,Wal,24,M,19570,2270 +1999,Wal,24,F,18615,2324 +1999,Wal,25,M,20033,2580 +1999,Wal,25,F,19242,2460 +1999,Wal,26,M,20494,2760 +1999,Wal,26,F,19707,2711 +1999,Wal,27,M,20732,2828 +1999,Wal,27,F,20153,2777 +1999,Wal,28,M,20249,2971 +1999,Wal,28,F,19687,2762 +1999,Wal,29,M,20172,3058 +1999,Wal,29,F,19791,2903 +1999,Wal,30,M,19803,3140 +1999,Wal,30,F,19717,3055 +1999,Wal,31,M,20265,3152 +1999,Wal,31,F,20091,2972 +1999,Wal,32,M,20672,3604 +1999,Wal,32,F,20733,3224 +1999,Wal,33,M,21410,3794 +1999,Wal,33,F,21422,3248 +1999,Wal,34,M,22365,3721 +1999,Wal,34,F,22355,3266 +1999,Wal,35,M,22011,3680 +1999,Wal,35,F,22397,3153 +1999,Wal,36,M,21481,3642 +1999,Wal,36,F,21966,3010 +1999,Wal,37,M,22124,3575 +1999,Wal,37,F,22645,3112 +1999,Wal,38,M,22034,3889 +1999,Wal,38,F,22185,2973 +1999,Wal,39,M,22187,3708 +1999,Wal,39,F,23025,2946 +1999,Wal,40,M,21774,3716 +1999,Wal,40,F,22588,2854 +1999,Wal,41,M,21619,3668 +1999,Wal,41,F,22193,2736 +1999,Wal,42,M,21173,3773 +1999,Wal,42,F,22013,2802 +1999,Wal,43,M,20975,3606 +1999,Wal,43,F,22005,2680 +1999,Wal,44,M,20894,3499 +1999,Wal,44,F,21828,2592 +1999,Wal,45,M,20958,3352 +1999,Wal,45,F,21604,2404 +1999,Wal,46,M,20779,3213 +1999,Wal,46,F,21273,2398 +1999,Wal,47,M,19981,3098 +1999,Wal,47,F,20993,2314 +1999,Wal,48,M,20919,3167 +1999,Wal,48,F,21190,2384 +1999,Wal,49,M,20790,3026 +1999,Wal,49,F,21186,2199 +1999,Wal,50,M,21271,2992 +1999,Wal,50,F,21877,2339 +1999,Wal,51,M,21278,3000 +1999,Wal,51,F,21736,2130 +1999,Wal,52,M,20722,2780 +1999,Wal,52,F,21590,1983 +1999,Wal,53,M,15425,2217 +1999,Wal,53,F,16514,1664 +1999,Wal,54,M,15362,2198 +1999,Wal,54,F,16161,1708 +1999,Wal,55,M,14327,1958 +1999,Wal,55,F,15301,1565 +1999,Wal,56,M,12460,1880 +1999,Wal,56,F,13366,1528 +1999,Wal,57,M,11612,1815 +1999,Wal,57,F,12650,1470 +1999,Wal,58,M,12937,2127 +1999,Wal,58,F,14163,1747 +1999,Wal,59,M,14024,1940 +1999,Wal,59,F,15626,1712 +1999,Wal,60,M,14200,1812 +1999,Wal,60,F,15954,1725 +1999,Wal,61,M,13546,1856 +1999,Wal,61,F,15062,1564 +1999,Wal,62,M,13133,1823 +1999,Wal,62,F,15048,1583 +1999,Wal,63,M,12854,1762 +1999,Wal,63,F,15018,1617 +1999,Wal,64,M,13465,1683 +1999,Wal,64,F,15610,1617 +1999,Wal,65,M,13405,1678 +1999,Wal,65,F,15632,1641 +1999,Wal,66,M,14022,1742 +1999,Wal,66,F,16989,1561 +1999,Wal,67,M,14286,1545 +1999,Wal,67,F,17441,1554 +1999,Wal,68,M,13921,1655 +1999,Wal,68,F,17424,1620 +1999,Wal,69,M,12992,1546 +1999,Wal,69,F,16598,1523 +1999,Wal,70,M,12435,1470 +1999,Wal,70,F,16767,1450 +1999,Wal,71,M,12029,1480 +1999,Wal,71,F,16263,1509 +1999,Wal,72,M,11603,1484 +1999,Wal,72,F,16258,1497 +1999,Wal,73,M,11349,1334 +1999,Wal,73,F,16621,1445 +1999,Wal,74,M,10750,1253 +1999,Wal,74,F,16041,1354 +1999,Wal,75,M,9957,1213 +1999,Wal,75,F,15458,1271 +1999,Wal,76,M,9374,1020 +1999,Wal,76,F,15235,1174 +1999,Wal,77,M,8991,870 +1999,Wal,77,F,15191,1077 +1999,Wal,78,M,8168,738 +1999,Wal,78,F,14517,1000 +1999,Wal,79,M,5493,423 +1999,Wal,79,F,10202,646 +1999,Wal,80,M,3485,303 +1999,Wal,80,F,6941,425 +1999,Wal,81,M,3034,257 +1999,Wal,81,F,6355,391 +1999,Wal,82,M,3170,240 +1999,Wal,82,F,6562,413 +1999,Wal,83,M,3266,242 +1999,Wal,83,F,7381,482 +1999,Wal,84,M,3378,241 +1999,Wal,84,F,8192,486 +1999,Wal,85,M,2812,228 +1999,Wal,85,F,7206,434 +1999,Wal,86,M,2341,201 +1999,Wal,86,F,6557,369 +1999,Wal,87,M,1745,102 +1999,Wal,87,F,5418,316 +1999,Wal,88,M,1441,89 +1999,Wal,88,F,4770,293 +1999,Wal,89,M,1103,50 +1999,Wal,89,F,3969,239 +1999,Wal,90,M,858,61 +1999,Wal,90,F,3460,192 +1999,Wal,91,M,643,23 +1999,Wal,91,F,2769,123 +1999,Wal,92,M,484,24 +1999,Wal,92,F,2081,121 +1999,Wal,93,M,320,24 +1999,Wal,93,F,1552,90 +1999,Wal,94,M,232,12 +1999,Wal,94,F,1212,71 +1999,Wal,95,M,160,14 +1999,Wal,95,F,872,33 +1999,Wal,96,M,104,10 +1999,Wal,96,F,537,41 +1999,Wal,97,M,64,4 +1999,Wal,97,F,433,30 +1999,Wal,98,M,29,5 +1999,Wal,98,F,235,17 +1999,Wal,99,M,28,0 +1999,Wal,99,F,157,1 +1999,Wal,100,M,14,4 +1999,Wal,100,F,95,3 +1999,Wal,101,M,6,1 +1999,Wal,101,F,62,7 +1999,Wal,102,M,2,0 +1999,Wal,102,F,33,1 +1999,Wal,103,M,1,0 +1999,Wal,103,F,24,0 +1999,Wal,104,M,1,0 +1999,Wal,104,F,6,0 +1999,Wal,105,M,2,0 +1999,Wal,105,F,4,0 +1999,Wal,106,M,0,0 +1999,Wal,106,F,5,1 +1999,Wal,107,M,0,0 +1999,Wal,107,F,2,0 +1999,Wal,108,M,0,0 +1999,Wal,108,F,1,0 +1999,Wal,109,M,0,0 +1999,Wal,109,F,0,0 +1999,Wal,110,M,0,0 +1999,Wal,110,F,0,0 +1999,Wal,111,M,0,0 +1999,Wal,111,F,0,0 +1999,Wal,112,M,0,0 +1999,Wal,112,F,0,0 +1999,Wal,113,M,0,0 +1999,Wal,113,F,0,0 +1999,Wal,114,M,0,0 +1999,Wal,114,F,0,0 +1999,Wal,115,M,0,0 +1999,Wal,115,F,0,0 +1999,Wal,116,M,0,0 +1999,Wal,116,F,0,0 +1999,Wal,117,M,0,0 +1999,Wal,117,F,0,0 +1999,Wal,118,M,0,0 +1999,Wal,118,F,0,0 +1999,Wal,119,M,0,0 +1999,Wal,119,F,0,0 +1999,Wal,120,M,0,0 +1999,Wal,120,F,0,0 +2000,BruCap,0,M,4967,1648 +2000,BruCap,0,F,4805,1624 +2000,BruCap,1,M,4788,1621 +2000,BruCap,1,F,4553,1677 +2000,BruCap,2,M,4772,1699 +2000,BruCap,2,F,4373,1547 +2000,BruCap,3,M,4379,1624 +2000,BruCap,3,F,4351,1595 +2000,BruCap,4,M,4266,1681 +2000,BruCap,4,F,4125,1524 +2000,BruCap,5,M,4306,1724 +2000,BruCap,5,F,3912,1546 +2000,BruCap,6,M,4221,1612 +2000,BruCap,6,F,4003,1509 +2000,BruCap,7,M,4195,1665 +2000,BruCap,7,F,4063,1557 +2000,BruCap,8,M,4129,1593 +2000,BruCap,8,F,4001,1495 +2000,BruCap,9,M,4151,1656 +2000,BruCap,9,F,3893,1574 +2000,BruCap,10,M,3983,1552 +2000,BruCap,10,F,3864,1492 +2000,BruCap,11,M,3990,1550 +2000,BruCap,11,F,3788,1461 +2000,BruCap,12,M,3973,1414 +2000,BruCap,12,F,3790,1406 +2000,BruCap,13,M,3923,1364 +2000,BruCap,13,F,3729,1310 +2000,BruCap,14,M,3852,1367 +2000,BruCap,14,F,3425,1357 +2000,BruCap,15,M,3804,1428 +2000,BruCap,15,F,3633,1472 +2000,BruCap,16,M,3694,1465 +2000,BruCap,16,F,3580,1428 +2000,BruCap,17,M,3624,1697 +2000,BruCap,17,F,3520,1637 +2000,BruCap,18,M,3938,1659 +2000,BruCap,18,F,3773,1631 +2000,BruCap,19,M,4084,1536 +2000,BruCap,19,F,4142,1771 +2000,BruCap,20,M,4164,1670 +2000,BruCap,20,F,4066,1878 +2000,BruCap,21,M,4111,1676 +2000,BruCap,21,F,4372,2180 +2000,BruCap,22,M,4201,1934 +2000,BruCap,22,F,4437,2277 +2000,BruCap,23,M,4255,2162 +2000,BruCap,23,F,4594,2457 +2000,BruCap,24,M,4594,2203 +2000,BruCap,24,F,4675,2610 +2000,BruCap,25,M,4741,2633 +2000,BruCap,25,F,4979,2862 +2000,BruCap,26,M,5099,2866 +2000,BruCap,26,F,5283,3000 +2000,BruCap,27,M,5288,3163 +2000,BruCap,27,F,5274,3200 +2000,BruCap,28,M,5262,3306 +2000,BruCap,28,F,5204,3322 +2000,BruCap,29,M,5176,3501 +2000,BruCap,29,F,5087,3274 +2000,BruCap,30,M,4972,3518 +2000,BruCap,30,F,4799,3371 +2000,BruCap,31,M,4810,3625 +2000,BruCap,31,F,4615,3227 +2000,BruCap,32,M,4710,3359 +2000,BruCap,32,F,4502,3126 +2000,BruCap,33,M,4637,3542 +2000,BruCap,33,F,4536,3133 +2000,BruCap,34,M,4834,3393 +2000,BruCap,34,F,4572,3123 +2000,BruCap,35,M,4704,3396 +2000,BruCap,35,F,4489,3136 +2000,BruCap,36,M,4676,3139 +2000,BruCap,36,F,4495,2795 +2000,BruCap,37,M,4379,3124 +2000,BruCap,37,F,4380,2768 +2000,BruCap,38,M,4369,2728 +2000,BruCap,38,F,4449,2632 +2000,BruCap,39,M,4486,2729 +2000,BruCap,39,F,4528,2662 +2000,BruCap,40,M,4415,2490 +2000,BruCap,40,F,4552,2414 +2000,BruCap,41,M,4282,2350 +2000,BruCap,41,F,4456,2275 +2000,BruCap,42,M,4307,2082 +2000,BruCap,42,F,4462,2156 +2000,BruCap,43,M,4130,2229 +2000,BruCap,43,F,4475,2208 +2000,BruCap,44,M,4187,2182 +2000,BruCap,44,F,4465,2061 +2000,BruCap,45,M,4185,1919 +2000,BruCap,45,F,4372,1975 +2000,BruCap,46,M,4192,1905 +2000,BruCap,46,F,4473,1832 +2000,BruCap,47,M,4244,1915 +2000,BruCap,47,F,4485,1864 +2000,BruCap,48,M,4058,1743 +2000,BruCap,48,F,4340,1633 +2000,BruCap,49,M,3962,1839 +2000,BruCap,49,F,4442,1765 +2000,BruCap,50,M,3996,1626 +2000,BruCap,50,F,4372,1539 +2000,BruCap,51,M,4036,1692 +2000,BruCap,51,F,4446,1554 +2000,BruCap,52,M,4057,1642 +2000,BruCap,52,F,4632,1456 +2000,BruCap,53,M,4097,1506 +2000,BruCap,53,F,4482,1433 +2000,BruCap,54,M,3492,1346 +2000,BruCap,54,F,3937,1256 +2000,BruCap,55,M,3617,1407 +2000,BruCap,55,F,4170,1258 +2000,BruCap,56,M,3493,1270 +2000,BruCap,56,F,3965,1163 +2000,BruCap,57,M,2983,1316 +2000,BruCap,57,F,3393,1156 +2000,BruCap,58,M,2641,1118 +2000,BruCap,58,F,3034,968 +2000,BruCap,59,M,2894,1350 +2000,BruCap,59,F,3330,1262 +2000,BruCap,60,M,3019,1191 +2000,BruCap,60,F,3648,1077 +2000,BruCap,61,M,2993,1197 +2000,BruCap,61,F,3555,993 +2000,BruCap,62,M,2897,1122 +2000,BruCap,62,F,3514,897 +2000,BruCap,63,M,2815,1095 +2000,BruCap,63,F,3465,953 +2000,BruCap,64,M,2791,972 +2000,BruCap,64,F,3559,917 +2000,BruCap,65,M,2942,923 +2000,BruCap,65,F,3552,819 +2000,BruCap,66,M,2838,825 +2000,BruCap,66,F,3796,702 +2000,BruCap,67,M,2990,823 +2000,BruCap,67,F,3959,724 +2000,BruCap,68,M,3036,673 +2000,BruCap,68,F,4047,661 +2000,BruCap,69,M,2909,769 +2000,BruCap,69,F,4399,722 +2000,BruCap,70,M,2789,613 +2000,BruCap,70,F,4192,524 +2000,BruCap,71,M,2820,549 +2000,BruCap,71,F,4148,558 +2000,BruCap,72,M,2743,470 +2000,BruCap,72,F,4183,477 +2000,BruCap,73,M,2730,444 +2000,BruCap,73,F,4326,446 +2000,BruCap,74,M,2720,394 +2000,BruCap,74,F,4361,420 +2000,BruCap,75,M,2760,306 +2000,BruCap,75,F,4472,400 +2000,BruCap,76,M,2525,331 +2000,BruCap,76,F,4527,361 +2000,BruCap,77,M,2414,291 +2000,BruCap,77,F,4425,326 +2000,BruCap,78,M,2468,262 +2000,BruCap,78,F,4450,288 +2000,BruCap,79,M,2262,202 +2000,BruCap,79,F,4414,340 +2000,BruCap,80,M,1614,135 +2000,BruCap,80,F,3067,207 +2000,BruCap,81,M,928,107 +2000,BruCap,81,F,2198,143 +2000,BruCap,82,M,899,96 +2000,BruCap,82,F,2056,154 +2000,BruCap,83,M,823,70 +2000,BruCap,83,F,2146,127 +2000,BruCap,84,M,976,70 +2000,BruCap,84,F,2403,128 +2000,BruCap,85,M,1032,78 +2000,BruCap,85,F,2684,156 +2000,BruCap,86,M,876,52 +2000,BruCap,86,F,2399,135 +2000,BruCap,87,M,709,46 +2000,BruCap,87,F,2136,131 +2000,BruCap,88,M,586,42 +2000,BruCap,88,F,1858,92 +2000,BruCap,89,M,458,41 +2000,BruCap,89,F,1655,95 +2000,BruCap,90,M,352,23 +2000,BruCap,90,F,1281,80 +2000,BruCap,91,M,271,18 +2000,BruCap,91,F,1120,50 +2000,BruCap,92,M,201,16 +2000,BruCap,92,F,879,40 +2000,BruCap,93,M,139,6 +2000,BruCap,93,F,684,39 +2000,BruCap,94,M,108,6 +2000,BruCap,94,F,525,36 +2000,BruCap,95,M,77,7 +2000,BruCap,95,F,399,17 +2000,BruCap,96,M,56,2 +2000,BruCap,96,F,291,20 +2000,BruCap,97,M,35,6 +2000,BruCap,97,F,210,13 +2000,BruCap,98,M,19,5 +2000,BruCap,98,F,136,8 +2000,BruCap,99,M,7,3 +2000,BruCap,99,F,80,9 +2000,BruCap,100,M,8,1 +2000,BruCap,100,F,58,3 +2000,BruCap,101,M,3,1 +2000,BruCap,101,F,42,8 +2000,BruCap,102,M,2,1 +2000,BruCap,102,F,21,4 +2000,BruCap,103,M,1,0 +2000,BruCap,103,F,11,2 +2000,BruCap,104,M,1,0 +2000,BruCap,104,F,6,2 +2000,BruCap,105,M,0,0 +2000,BruCap,105,F,3,0 +2000,BruCap,106,M,0,1 +2000,BruCap,106,F,2,0 +2000,BruCap,107,M,0,0 +2000,BruCap,107,F,2,0 +2000,BruCap,108,M,0,0 +2000,BruCap,108,F,1,0 +2000,BruCap,109,M,1,0 +2000,BruCap,109,F,0,1 +2000,BruCap,110,M,0,0 +2000,BruCap,110,F,0,0 +2000,BruCap,111,M,0,0 +2000,BruCap,111,F,0,0 +2000,BruCap,112,M,0,0 +2000,BruCap,112,F,0,0 +2000,BruCap,113,M,0,0 +2000,BruCap,113,F,0,0 +2000,BruCap,114,M,0,0 +2000,BruCap,114,F,0,0 +2000,BruCap,115,M,0,0 +2000,BruCap,115,F,0,0 +2000,BruCap,116,M,0,0 +2000,BruCap,116,F,0,0 +2000,BruCap,117,M,0,0 +2000,BruCap,117,F,0,0 +2000,BruCap,118,M,0,0 +2000,BruCap,118,F,0,0 +2000,BruCap,119,M,0,0 +2000,BruCap,119,F,0,0 +2000,BruCap,120,M,0,0 +2000,BruCap,120,F,0,0 +2000,Fla,0,M,29661,1721 +2000,Fla,0,F,28625,1678 +2000,Fla,1,M,30671,1739 +2000,Fla,1,F,29047,1733 +2000,Fla,2,M,31324,1789 +2000,Fla,2,F,30100,1737 +2000,Fla,3,M,31544,1736 +2000,Fla,3,F,30262,1753 +2000,Fla,4,M,31714,1805 +2000,Fla,4,F,30332,1711 +2000,Fla,5,M,32051,1886 +2000,Fla,5,F,30571,1728 +2000,Fla,6,M,33474,1827 +2000,Fla,6,F,32486,1730 +2000,Fla,7,M,34748,1863 +2000,Fla,7,F,33263,1871 +2000,Fla,8,M,35238,1936 +2000,Fla,8,F,33461,1804 +2000,Fla,9,M,34909,1816 +2000,Fla,9,F,33241,1842 +2000,Fla,10,M,33826,1798 +2000,Fla,10,F,32153,1716 +2000,Fla,11,M,33433,1777 +2000,Fla,11,F,31951,1680 +2000,Fla,12,M,33310,1506 +2000,Fla,12,F,31520,1489 +2000,Fla,13,M,33420,1511 +2000,Fla,13,F,31468,1428 +2000,Fla,14,M,32396,1530 +2000,Fla,14,F,30916,1512 +2000,Fla,15,M,33135,1613 +2000,Fla,15,F,31528,1516 +2000,Fla,16,M,33974,1605 +2000,Fla,16,F,32582,1642 +2000,Fla,17,M,34814,1825 +2000,Fla,17,F,32875,1786 +2000,Fla,18,M,36277,1655 +2000,Fla,18,F,34039,1787 +2000,Fla,19,M,35928,1607 +2000,Fla,19,F,34528,1781 +2000,Fla,20,M,36379,1598 +2000,Fla,20,F,34317,1896 +2000,Fla,21,M,35534,1617 +2000,Fla,21,F,34118,1974 +2000,Fla,22,M,34779,1700 +2000,Fla,22,F,33675,2171 +2000,Fla,23,M,34004,1918 +2000,Fla,23,F,32461,2344 +2000,Fla,24,M,33063,2059 +2000,Fla,24,F,31484,2463 +2000,Fla,25,M,34251,2343 +2000,Fla,25,F,32784,2696 +2000,Fla,26,M,35437,2527 +2000,Fla,26,F,33877,2773 +2000,Fla,27,M,36799,2847 +2000,Fla,27,F,35645,3045 +2000,Fla,28,M,38481,3000 +2000,Fla,28,F,37609,3103 +2000,Fla,29,M,39727,3109 +2000,Fla,29,F,38283,3216 +2000,Fla,30,M,39707,3219 +2000,Fla,30,F,38386,3162 +2000,Fla,31,M,40190,3280 +2000,Fla,31,F,38970,3062 +2000,Fla,32,M,41796,3092 +2000,Fla,32,F,39817,3019 +2000,Fla,33,M,43072,3480 +2000,Fla,33,F,41736,3275 +2000,Fla,34,M,44697,3361 +2000,Fla,34,F,43063,3073 +2000,Fla,35,M,46531,3473 +2000,Fla,35,F,45335,3136 +2000,Fla,36,M,46336,3254 +2000,Fla,36,F,44970,2905 +2000,Fla,37,M,45805,3249 +2000,Fla,37,F,44377,2718 +2000,Fla,38,M,45589,3059 +2000,Fla,38,F,44805,2580 +2000,Fla,39,M,44633,3115 +2000,Fla,39,F,43569,2625 +2000,Fla,40,M,45562,2825 +2000,Fla,40,F,44472,2479 +2000,Fla,41,M,44699,2858 +2000,Fla,41,F,43323,2287 +2000,Fla,42,M,44125,2701 +2000,Fla,42,F,42712,2120 +2000,Fla,43,M,42883,2633 +2000,Fla,43,F,42133,2163 +2000,Fla,44,M,42251,2600 +2000,Fla,44,F,41770,1980 +2000,Fla,45,M,41539,2487 +2000,Fla,45,F,40657,1884 +2000,Fla,46,M,40688,2238 +2000,Fla,46,F,39342,1763 +2000,Fla,47,M,40579,2314 +2000,Fla,47,F,39146,1748 +2000,Fla,48,M,38722,2216 +2000,Fla,48,F,37714,1585 +2000,Fla,49,M,38092,2293 +2000,Fla,49,F,37591,1664 +2000,Fla,50,M,38338,2347 +2000,Fla,50,F,37349,1677 +2000,Fla,51,M,38218,2245 +2000,Fla,51,F,37789,1562 +2000,Fla,52,M,37991,2177 +2000,Fla,52,F,37336,1588 +2000,Fla,53,M,38923,2211 +2000,Fla,53,F,37998,1457 +2000,Fla,54,M,34505,1866 +2000,Fla,54,F,34242,1329 +2000,Fla,55,M,34206,1805 +2000,Fla,55,F,34021,1392 +2000,Fla,56,M,32576,1786 +2000,Fla,56,F,32617,1271 +2000,Fla,57,M,28329,1673 +2000,Fla,57,F,28398,1256 +2000,Fla,58,M,25383,1651 +2000,Fla,58,F,26145,1132 +2000,Fla,59,M,28015,1701 +2000,Fla,59,F,28939,1311 +2000,Fla,60,M,30567,1623 +2000,Fla,60,F,32407,1074 +2000,Fla,61,M,31537,1565 +2000,Fla,61,F,33033,1062 +2000,Fla,62,M,30494,1388 +2000,Fla,62,F,31882,1011 +2000,Fla,63,M,29297,1367 +2000,Fla,63,F,31293,957 +2000,Fla,64,M,29003,1283 +2000,Fla,64,F,31212,896 +2000,Fla,65,M,28917,1218 +2000,Fla,65,F,31833,899 +2000,Fla,66,M,28776,1184 +2000,Fla,66,F,31566,872 +2000,Fla,67,M,29012,1118 +2000,Fla,67,F,32842,779 +2000,Fla,68,M,28568,1005 +2000,Fla,68,F,32811,638 +2000,Fla,69,M,27690,966 +2000,Fla,69,F,32453,756 +2000,Fla,70,M,25219,829 +2000,Fla,70,F,30185,639 +2000,Fla,71,M,24034,811 +2000,Fla,71,F,29254,666 +2000,Fla,72,M,22708,707 +2000,Fla,72,F,28118,580 +2000,Fla,73,M,21692,638 +2000,Fla,73,F,28251,595 +2000,Fla,74,M,21204,625 +2000,Fla,74,F,27555,557 +2000,Fla,75,M,19839,587 +2000,Fla,75,F,26688,505 +2000,Fla,76,M,18718,568 +2000,Fla,76,F,26071,494 +2000,Fla,77,M,16794,463 +2000,Fla,77,F,24243,425 +2000,Fla,78,M,15716,424 +2000,Fla,78,F,23598,409 +2000,Fla,79,M,14518,376 +2000,Fla,79,F,22344,382 +2000,Fla,80,M,10251,249 +2000,Fla,80,F,16447,239 +2000,Fla,81,M,6204,181 +2000,Fla,81,F,10943,203 +2000,Fla,82,M,5507,166 +2000,Fla,82,F,10373,188 +2000,Fla,83,M,5787,148 +2000,Fla,83,F,10921,186 +2000,Fla,84,M,6240,134 +2000,Fla,84,F,12214,182 +2000,Fla,85,M,6009,112 +2000,Fla,85,F,13005,175 +2000,Fla,86,M,5085,97 +2000,Fla,86,F,11823,166 +2000,Fla,87,M,4243,84 +2000,Fla,87,F,10225,140 +2000,Fla,88,M,3308,68 +2000,Fla,88,F,8464,105 +2000,Fla,89,M,2675,35 +2000,Fla,89,F,7247,92 +2000,Fla,90,M,1971,35 +2000,Fla,90,F,5930,87 +2000,Fla,91,M,1492,32 +2000,Fla,91,F,5044,56 +2000,Fla,92,M,1139,24 +2000,Fla,92,F,3844,51 +2000,Fla,93,M,756,15 +2000,Fla,93,F,2871,34 +2000,Fla,94,M,619,11 +2000,Fla,94,F,2193,31 +2000,Fla,95,M,403,10 +2000,Fla,95,F,1586,27 +2000,Fla,96,M,254,4 +2000,Fla,96,F,1077,15 +2000,Fla,97,M,160,2 +2000,Fla,97,F,763,9 +2000,Fla,98,M,79,4 +2000,Fla,98,F,503,9 +2000,Fla,99,M,55,3 +2000,Fla,99,F,297,9 +2000,Fla,100,M,25,0 +2000,Fla,100,F,159,2 +2000,Fla,101,M,15,0 +2000,Fla,101,F,92,5 +2000,Fla,102,M,11,1 +2000,Fla,102,F,65,3 +2000,Fla,103,M,1,0 +2000,Fla,103,F,40,0 +2000,Fla,104,M,3,0 +2000,Fla,104,F,24,0 +2000,Fla,105,M,2,0 +2000,Fla,105,F,7,0 +2000,Fla,106,M,0,0 +2000,Fla,106,F,3,0 +2000,Fla,107,M,0,0 +2000,Fla,107,F,0,0 +2000,Fla,108,M,0,0 +2000,Fla,108,F,0,0 +2000,Fla,109,M,0,0 +2000,Fla,109,F,1,0 +2000,Fla,110,M,0,0 +2000,Fla,110,F,0,0 +2000,Fla,111,M,0,0 +2000,Fla,111,F,0,0 +2000,Fla,112,M,0,0 +2000,Fla,112,F,0,0 +2000,Fla,113,M,0,0 +2000,Fla,113,F,0,0 +2000,Fla,114,M,0,0 +2000,Fla,114,F,0,0 +2000,Fla,115,M,0,0 +2000,Fla,115,F,0,0 +2000,Fla,116,M,0,0 +2000,Fla,116,F,0,0 +2000,Fla,117,M,0,0 +2000,Fla,117,F,0,0 +2000,Fla,118,M,0,0 +2000,Fla,118,F,0,0 +2000,Fla,119,M,0,0 +2000,Fla,119,F,0,0 +2000,Fla,120,M,0,0 +2000,Fla,120,F,0,0 +2000,Wal,0,M,18683,868 +2000,Wal,0,F,17787,845 +2000,Wal,1,M,18887,907 +2000,Wal,1,F,18024,929 +2000,Wal,2,M,18937,1061 +2000,Wal,2,F,18261,929 +2000,Wal,3,M,19301,1069 +2000,Wal,3,F,18493,953 +2000,Wal,4,M,18859,1016 +2000,Wal,4,F,18112,995 +2000,Wal,5,M,19063,1123 +2000,Wal,5,F,18194,1023 +2000,Wal,6,M,19906,1165 +2000,Wal,6,F,18800,1148 +2000,Wal,7,M,20923,1275 +2000,Wal,7,F,19953,1217 +2000,Wal,8,M,21426,1306 +2000,Wal,8,F,20666,1255 +2000,Wal,9,M,21136,1343 +2000,Wal,9,F,20330,1307 +2000,Wal,10,M,21197,1367 +2000,Wal,10,F,20242,1299 +2000,Wal,11,M,21104,1362 +2000,Wal,11,F,19973,1342 +2000,Wal,12,M,20358,1377 +2000,Wal,12,F,19403,1282 +2000,Wal,13,M,20375,1394 +2000,Wal,13,F,19259,1313 +2000,Wal,14,M,19522,1354 +2000,Wal,14,F,18698,1308 +2000,Wal,15,M,19244,1408 +2000,Wal,15,F,18501,1358 +2000,Wal,16,M,19135,1511 +2000,Wal,16,F,17791,1405 +2000,Wal,17,M,19291,1586 +2000,Wal,17,F,18470,1669 +2000,Wal,18,M,19464,1640 +2000,Wal,18,F,18984,1754 +2000,Wal,19,M,19594,1616 +2000,Wal,19,F,18968,1777 +2000,Wal,20,M,19310,1653 +2000,Wal,20,F,18200,1816 +2000,Wal,21,M,18835,1742 +2000,Wal,21,F,18065,1855 +2000,Wal,22,M,19042,1745 +2000,Wal,22,F,18037,2026 +2000,Wal,23,M,19026,1914 +2000,Wal,23,F,18199,2017 +2000,Wal,24,M,18884,2033 +2000,Wal,24,F,18172,2100 +2000,Wal,25,M,19270,2284 +2000,Wal,25,F,18355,2355 +2000,Wal,26,M,19838,2636 +2000,Wal,26,F,19127,2485 +2000,Wal,27,M,20377,2760 +2000,Wal,27,F,19717,2738 +2000,Wal,28,M,20683,2842 +2000,Wal,28,F,20219,2776 +2000,Wal,29,M,20246,2920 +2000,Wal,29,F,19768,2767 +2000,Wal,30,M,20201,3050 +2000,Wal,30,F,19922,2942 +2000,Wal,31,M,19787,3149 +2000,Wal,31,F,19845,3065 +2000,Wal,32,M,20342,3137 +2000,Wal,32,F,20210,2964 +2000,Wal,33,M,20702,3625 +2000,Wal,33,F,20775,3232 +2000,Wal,34,M,21505,3782 +2000,Wal,34,F,21557,3253 +2000,Wal,35,M,22394,3709 +2000,Wal,35,F,22445,3268 +2000,Wal,36,M,22030,3728 +2000,Wal,36,F,22445,3133 +2000,Wal,37,M,21513,3624 +2000,Wal,37,F,21984,2984 +2000,Wal,38,M,22144,3549 +2000,Wal,38,F,22660,3136 +2000,Wal,39,M,22000,3880 +2000,Wal,39,F,22234,2952 +2000,Wal,40,M,22195,3669 +2000,Wal,40,F,23049,2944 +2000,Wal,41,M,21782,3697 +2000,Wal,41,F,22667,2861 +2000,Wal,42,M,21602,3641 +2000,Wal,42,F,22188,2718 +2000,Wal,43,M,21167,3737 +2000,Wal,43,F,22022,2794 +2000,Wal,44,M,20917,3576 +2000,Wal,44,F,21978,2659 +2000,Wal,45,M,20843,3491 +2000,Wal,45,F,21809,2595 +2000,Wal,46,M,20860,3328 +2000,Wal,46,F,21580,2389 +2000,Wal,47,M,20687,3202 +2000,Wal,47,F,21252,2393 +2000,Wal,48,M,19901,3097 +2000,Wal,48,F,20959,2320 +2000,Wal,49,M,20816,3151 +2000,Wal,49,F,21168,2378 +2000,Wal,50,M,20685,3009 +2000,Wal,50,F,21161,2201 +2000,Wal,51,M,21167,2978 +2000,Wal,51,F,21830,2317 +2000,Wal,52,M,21105,2977 +2000,Wal,52,F,21696,2122 +2000,Wal,53,M,20605,2750 +2000,Wal,53,F,21526,1973 +2000,Wal,54,M,15334,2191 +2000,Wal,54,F,16471,1673 +2000,Wal,55,M,15219,2179 +2000,Wal,55,F,16126,1704 +2000,Wal,56,M,14234,1955 +2000,Wal,56,F,15247,1552 +2000,Wal,57,M,12346,1838 +2000,Wal,57,F,13303,1521 +2000,Wal,58,M,11478,1791 +2000,Wal,58,F,12603,1459 +2000,Wal,59,M,12818,2107 +2000,Wal,59,F,14098,1737 +2000,Wal,60,M,13871,1930 +2000,Wal,60,F,15571,1710 +2000,Wal,61,M,13986,1797 +2000,Wal,61,F,15830,1719 +2000,Wal,62,M,13318,1830 +2000,Wal,62,F,14949,1543 +2000,Wal,63,M,12942,1791 +2000,Wal,63,F,14931,1576 +2000,Wal,64,M,12620,1730 +2000,Wal,64,F,14872,1602 +2000,Wal,65,M,13167,1621 +2000,Wal,65,F,15489,1596 +2000,Wal,66,M,13113,1620 +2000,Wal,66,F,15467,1630 +2000,Wal,67,M,13650,1681 +2000,Wal,67,F,16781,1545 +2000,Wal,68,M,13889,1489 +2000,Wal,68,F,17224,1542 +2000,Wal,69,M,13486,1600 +2000,Wal,69,F,17216,1598 +2000,Wal,70,M,12543,1492 +2000,Wal,70,F,16338,1511 +2000,Wal,71,M,11987,1411 +2000,Wal,71,F,16444,1435 +2000,Wal,72,M,11497,1409 +2000,Wal,72,F,15952,1472 +2000,Wal,73,M,11113,1387 +2000,Wal,73,F,15882,1473 +2000,Wal,74,M,10809,1249 +2000,Wal,74,F,16220,1417 +2000,Wal,75,M,10148,1181 +2000,Wal,75,F,15639,1317 +2000,Wal,76,M,9398,1116 +2000,Wal,76,F,14996,1234 +2000,Wal,77,M,8790,950 +2000,Wal,77,F,14670,1133 +2000,Wal,78,M,8303,797 +2000,Wal,78,F,14628,1037 +2000,Wal,79,M,7543,671 +2000,Wal,79,F,13872,955 +2000,Wal,80,M,5010,391 +2000,Wal,80,F,9691,610 +2000,Wal,81,M,3145,272 +2000,Wal,81,F,6574,395 +2000,Wal,82,M,2700,227 +2000,Wal,82,F,5911,364 +2000,Wal,83,M,2783,209 +2000,Wal,83,F,6073,385 +2000,Wal,84,M,2823,216 +2000,Wal,84,F,6761,443 +2000,Wal,85,M,2895,205 +2000,Wal,85,F,7441,440 +2000,Wal,86,M,2386,195 +2000,Wal,86,F,6459,385 +2000,Wal,87,M,1924,166 +2000,Wal,87,F,5775,320 +2000,Wal,88,M,1468,87 +2000,Wal,88,F,4747,278 +2000,Wal,89,M,1198,72 +2000,Wal,89,F,4100,264 +2000,Wal,90,M,864,38 +2000,Wal,90,F,3302,200 +2000,Wal,91,M,663,44 +2000,Wal,91,F,2838,165 +2000,Wal,92,M,472,22 +2000,Wal,92,F,2247,102 +2000,Wal,93,M,354,22 +2000,Wal,93,F,1630,99 +2000,Wal,94,M,233,14 +2000,Wal,94,F,1197,73 +2000,Wal,95,M,155,7 +2000,Wal,95,F,900,54 +2000,Wal,96,M,110,6 +2000,Wal,96,F,607,28 +2000,Wal,97,M,69,7 +2000,Wal,97,F,364,33 +2000,Wal,98,M,42,1 +2000,Wal,98,F,298,24 +2000,Wal,99,M,21,5 +2000,Wal,99,F,165,11 +2000,Wal,100,M,18,1 +2000,Wal,100,F,92,3 +2000,Wal,101,M,7,3 +2000,Wal,101,F,53,2 +2000,Wal,102,M,4,1 +2000,Wal,102,F,41,4 +2000,Wal,103,M,0,0 +2000,Wal,103,F,13,1 +2000,Wal,104,M,1,0 +2000,Wal,104,F,16,0 +2000,Wal,105,M,1,0 +2000,Wal,105,F,2,0 +2000,Wal,106,M,1,0 +2000,Wal,106,F,3,0 +2000,Wal,107,M,0,0 +2000,Wal,107,F,3,0 +2000,Wal,108,M,0,0 +2000,Wal,108,F,1,0 +2000,Wal,109,M,0,0 +2000,Wal,109,F,1,0 +2000,Wal,110,M,0,0 +2000,Wal,110,F,0,0 +2000,Wal,111,M,0,0 +2000,Wal,111,F,0,0 +2000,Wal,112,M,0,0 +2000,Wal,112,F,0,0 +2000,Wal,113,M,0,0 +2000,Wal,113,F,0,0 +2000,Wal,114,M,0,0 +2000,Wal,114,F,0,0 +2000,Wal,115,M,0,0 +2000,Wal,115,F,0,0 +2000,Wal,116,M,0,0 +2000,Wal,116,F,0,0 +2000,Wal,117,M,0,0 +2000,Wal,117,F,0,0 +2000,Wal,118,M,0,0 +2000,Wal,118,F,0,0 +2000,Wal,119,M,0,0 +2000,Wal,119,F,0,0 +2000,Wal,120,M,0,0 +2000,Wal,120,F,0,0 +2001,BruCap,0,M,5478,1533 +2001,BruCap,0,F,5082,1479 +2001,BruCap,1,M,5120,1465 +2001,BruCap,1,F,4882,1431 +2001,BruCap,2,M,4889,1425 +2001,BruCap,2,F,4626,1486 +2001,BruCap,3,M,4878,1492 +2001,BruCap,3,F,4520,1364 +2001,BruCap,4,M,4497,1434 +2001,BruCap,4,F,4494,1388 +2001,BruCap,5,M,4430,1468 +2001,BruCap,5,F,4272,1330 +2001,BruCap,6,M,4427,1477 +2001,BruCap,6,F,4082,1357 +2001,BruCap,7,M,4419,1378 +2001,BruCap,7,F,4160,1315 +2001,BruCap,8,M,4346,1468 +2001,BruCap,8,F,4225,1324 +2001,BruCap,9,M,4301,1403 +2001,BruCap,9,F,4205,1313 +2001,BruCap,10,M,4327,1436 +2001,BruCap,10,F,4096,1352 +2001,BruCap,11,M,4168,1359 +2001,BruCap,11,F,4039,1299 +2001,BruCap,12,M,4248,1289 +2001,BruCap,12,F,4026,1232 +2001,BruCap,13,M,4079,1293 +2001,BruCap,13,F,3976,1238 +2001,BruCap,14,M,4038,1257 +2001,BruCap,14,F,3846,1205 +2001,BruCap,15,M,3965,1264 +2001,BruCap,15,F,3555,1259 +2001,BruCap,16,M,3943,1303 +2001,BruCap,16,F,3805,1332 +2001,BruCap,17,M,3833,1336 +2001,BruCap,17,F,3725,1324 +2001,BruCap,18,M,3877,1534 +2001,BruCap,18,F,3747,1593 +2001,BruCap,19,M,4230,1496 +2001,BruCap,19,F,4134,1614 +2001,BruCap,20,M,4277,1553 +2001,BruCap,20,F,4416,1836 +2001,BruCap,21,M,4338,1670 +2001,BruCap,21,F,4290,2059 +2001,BruCap,22,M,4269,1772 +2001,BruCap,22,F,4619,2300 +2001,BruCap,23,M,4479,2082 +2001,BruCap,23,F,4753,2433 +2001,BruCap,24,M,4495,2397 +2001,BruCap,24,F,4916,2626 +2001,BruCap,25,M,4840,2403 +2001,BruCap,25,F,4968,2800 +2001,BruCap,26,M,4998,2872 +2001,BruCap,26,F,5137,3031 +2001,BruCap,27,M,5259,2996 +2001,BruCap,27,F,5325,3100 +2001,BruCap,28,M,5379,3199 +2001,BruCap,28,F,5289,3270 +2001,BruCap,29,M,5345,3368 +2001,BruCap,29,F,5230,3282 +2001,BruCap,30,M,5208,3542 +2001,BruCap,30,F,5118,3158 +2001,BruCap,31,M,5145,3392 +2001,BruCap,31,F,4761,3277 +2001,BruCap,32,M,4872,3462 +2001,BruCap,32,F,4651,3070 +2001,BruCap,33,M,4777,3234 +2001,BruCap,33,F,4543,2987 +2001,BruCap,34,M,4765,3364 +2001,BruCap,34,F,4634,2979 +2001,BruCap,35,M,4942,3231 +2001,BruCap,35,F,4675,2935 +2001,BruCap,36,M,4836,3186 +2001,BruCap,36,F,4610,2946 +2001,BruCap,37,M,4780,2909 +2001,BruCap,37,F,4594,2658 +2001,BruCap,38,M,4520,2899 +2001,BruCap,38,F,4488,2555 +2001,BruCap,39,M,4513,2522 +2001,BruCap,39,F,4539,2449 +2001,BruCap,40,M,4605,2522 +2001,BruCap,40,F,4654,2450 +2001,BruCap,41,M,4538,2319 +2001,BruCap,41,F,4650,2248 +2001,BruCap,42,M,4423,2191 +2001,BruCap,42,F,4568,2115 +2001,BruCap,43,M,4379,1962 +2001,BruCap,43,F,4570,1999 +2001,BruCap,44,M,4245,2074 +2001,BruCap,44,F,4585,2034 +2001,BruCap,45,M,4260,2037 +2001,BruCap,45,F,4565,1897 +2001,BruCap,46,M,4266,1794 +2001,BruCap,46,F,4463,1854 +2001,BruCap,47,M,4276,1768 +2001,BruCap,47,F,4554,1707 +2001,BruCap,48,M,4309,1790 +2001,BruCap,48,F,4553,1778 +2001,BruCap,49,M,4089,1607 +2001,BruCap,49,F,4385,1522 +2001,BruCap,50,M,4027,1721 +2001,BruCap,50,F,4489,1658 +2001,BruCap,51,M,4008,1541 +2001,BruCap,51,F,4408,1480 +2001,BruCap,52,M,4074,1608 +2001,BruCap,52,F,4490,1459 +2001,BruCap,53,M,4054,1558 +2001,BruCap,53,F,4630,1398 +2001,BruCap,54,M,4083,1426 +2001,BruCap,54,F,4499,1371 +2001,BruCap,55,M,3477,1283 +2001,BruCap,55,F,3940,1197 +2001,BruCap,56,M,3594,1294 +2001,BruCap,56,F,4142,1230 +2001,BruCap,57,M,3472,1205 +2001,BruCap,57,F,3942,1098 +2001,BruCap,58,M,3014,1211 +2001,BruCap,58,F,3381,1103 +2001,BruCap,59,M,2622,1047 +2001,BruCap,59,F,3005,917 +2001,BruCap,60,M,2911,1235 +2001,BruCap,60,F,3333,1195 +2001,BruCap,61,M,2982,1121 +2001,BruCap,61,F,3625,1031 +2001,BruCap,62,M,2980,1121 +2001,BruCap,62,F,3526,946 +2001,BruCap,63,M,2858,1045 +2001,BruCap,63,F,3455,867 +2001,BruCap,64,M,2796,1004 +2001,BruCap,64,F,3442,905 +2001,BruCap,65,M,2758,860 +2001,BruCap,65,F,3518,883 +2001,BruCap,66,M,2870,821 +2001,BruCap,66,F,3488,787 +2001,BruCap,67,M,2759,756 +2001,BruCap,67,F,3758,683 +2001,BruCap,68,M,2952,757 +2001,BruCap,68,F,3917,699 +2001,BruCap,69,M,2942,628 +2001,BruCap,69,F,3971,629 +2001,BruCap,70,M,2817,693 +2001,BruCap,70,F,4299,705 +2001,BruCap,71,M,2698,576 +2001,BruCap,71,F,4121,515 +2001,BruCap,72,M,2728,506 +2001,BruCap,72,F,4046,551 +2001,BruCap,73,M,2641,434 +2001,BruCap,73,F,4109,465 +2001,BruCap,74,M,2618,417 +2001,BruCap,74,F,4220,433 +2001,BruCap,75,M,2586,359 +2001,BruCap,75,F,4251,403 +2001,BruCap,76,M,2608,287 +2001,BruCap,76,F,4367,384 +2001,BruCap,77,M,2376,295 +2001,BruCap,77,F,4374,349 +2001,BruCap,78,M,2269,271 +2001,BruCap,78,F,4263,300 +2001,BruCap,79,M,2333,234 +2001,BruCap,79,F,4276,274 +2001,BruCap,80,M,2070,186 +2001,BruCap,80,F,4220,317 +2001,BruCap,81,M,1462,123 +2001,BruCap,81,F,2916,193 +2001,BruCap,82,M,863,99 +2001,BruCap,82,F,2057,132 +2001,BruCap,83,M,819,89 +2001,BruCap,83,F,1923,150 +2001,BruCap,84,M,743,56 +2001,BruCap,84,F,1975,117 +2001,BruCap,85,M,838,62 +2001,BruCap,85,F,2216,116 +2001,BruCap,86,M,905,65 +2001,BruCap,86,F,2401,133 +2001,BruCap,87,M,755,42 +2001,BruCap,87,F,2121,128 +2001,BruCap,88,M,587,45 +2001,BruCap,88,F,1866,114 +2001,BruCap,89,M,477,32 +2001,BruCap,89,F,1583,75 +2001,BruCap,90,M,356,31 +2001,BruCap,90,F,1398,86 +2001,BruCap,91,M,262,16 +2001,BruCap,91,F,1039,70 +2001,BruCap,92,M,211,14 +2001,BruCap,92,F,902,41 +2001,BruCap,93,M,144,11 +2001,BruCap,93,F,696,30 +2001,BruCap,94,M,101,5 +2001,BruCap,94,F,546,30 +2001,BruCap,95,M,79,5 +2001,BruCap,95,F,407,26 +2001,BruCap,96,M,46,6 +2001,BruCap,96,F,285,14 +2001,BruCap,97,M,32,2 +2001,BruCap,97,F,198,14 +2001,BruCap,98,M,25,4 +2001,BruCap,98,F,149,13 +2001,BruCap,99,M,11,3 +2001,BruCap,99,F,90,6 +2001,BruCap,100,M,3,2 +2001,BruCap,100,F,50,5 +2001,BruCap,101,M,4,1 +2001,BruCap,101,F,35,2 +2001,BruCap,102,M,0,1 +2001,BruCap,102,F,24,7 +2001,BruCap,103,M,1,1 +2001,BruCap,103,F,11,2 +2001,BruCap,104,M,0,0 +2001,BruCap,104,F,8,0 +2001,BruCap,105,M,0,0 +2001,BruCap,105,F,5,2 +2001,BruCap,106,M,0,0 +2001,BruCap,106,F,1,0 +2001,BruCap,107,M,0,1 +2001,BruCap,107,F,2,0 +2001,BruCap,108,M,0,0 +2001,BruCap,108,F,2,0 +2001,BruCap,109,M,0,0 +2001,BruCap,109,F,1,0 +2001,BruCap,110,M,1,0 +2001,BruCap,110,F,0,0 +2001,BruCap,111,M,0,0 +2001,BruCap,111,F,0,0 +2001,BruCap,112,M,0,0 +2001,BruCap,112,F,0,0 +2001,BruCap,113,M,0,0 +2001,BruCap,113,F,0,0 +2001,BruCap,114,M,0,0 +2001,BruCap,114,F,0,0 +2001,BruCap,115,M,0,0 +2001,BruCap,115,F,0,0 +2001,BruCap,116,M,0,0 +2001,BruCap,116,F,0,0 +2001,BruCap,117,M,0,0 +2001,BruCap,117,F,0,0 +2001,BruCap,118,M,0,0 +2001,BruCap,118,F,0,0 +2001,BruCap,119,M,0,0 +2001,BruCap,119,F,0,0 +2001,BruCap,120,M,0,0 +2001,BruCap,120,F,0,0 +2001,Fla,0,M,29884,1575 +2001,Fla,0,F,28697,1516 +2001,Fla,1,M,30005,1541 +2001,Fla,1,F,29013,1558 +2001,Fla,2,M,30976,1561 +2001,Fla,2,F,29398,1502 +2001,Fla,3,M,31643,1560 +2001,Fla,3,F,30405,1521 +2001,Fla,4,M,31883,1436 +2001,Fla,4,F,30568,1506 +2001,Fla,5,M,32022,1544 +2001,Fla,5,F,30632,1462 +2001,Fla,6,M,32395,1620 +2001,Fla,6,F,30819,1493 +2001,Fla,7,M,33743,1578 +2001,Fla,7,F,32808,1452 +2001,Fla,8,M,35083,1565 +2001,Fla,8,F,33614,1556 +2001,Fla,9,M,35564,1633 +2001,Fla,9,F,33757,1547 +2001,Fla,10,M,35207,1568 +2001,Fla,10,F,33572,1540 +2001,Fla,11,M,34128,1511 +2001,Fla,11,F,32508,1419 +2001,Fla,12,M,33822,1420 +2001,Fla,12,F,32294,1367 +2001,Fla,13,M,33527,1334 +2001,Fla,13,F,31693,1344 +2001,Fla,14,M,33623,1361 +2001,Fla,14,F,31649,1298 +2001,Fla,15,M,32579,1383 +2001,Fla,15,F,31078,1367 +2001,Fla,16,M,33315,1457 +2001,Fla,16,F,31711,1368 +2001,Fla,17,M,34190,1437 +2001,Fla,17,F,32828,1530 +2001,Fla,18,M,35146,1513 +2001,Fla,18,F,33294,1585 +2001,Fla,19,M,36446,1502 +2001,Fla,19,F,34281,1717 +2001,Fla,20,M,36027,1555 +2001,Fla,20,F,34643,1825 +2001,Fla,21,M,36399,1655 +2001,Fla,21,F,34432,1952 +2001,Fla,22,M,35538,1677 +2001,Fla,22,F,34223,2147 +2001,Fla,23,M,34719,1866 +2001,Fla,23,F,33671,2339 +2001,Fla,24,M,33953,2050 +2001,Fla,24,F,32416,2458 +2001,Fla,25,M,32973,2175 +2001,Fla,25,F,31428,2541 +2001,Fla,26,M,34153,2435 +2001,Fla,26,F,32836,2710 +2001,Fla,27,M,35424,2571 +2001,Fla,27,F,33995,2759 +2001,Fla,28,M,36881,2791 +2001,Fla,28,F,35843,2902 +2001,Fla,29,M,38610,2898 +2001,Fla,29,F,37837,2974 +2001,Fla,30,M,39861,3052 +2001,Fla,30,F,38558,3167 +2001,Fla,31,M,39879,3134 +2001,Fla,31,F,38698,3037 +2001,Fla,32,M,40377,3112 +2001,Fla,32,F,39195,2967 +2001,Fla,33,M,41971,2968 +2001,Fla,33,F,40072,2909 +2001,Fla,34,M,43276,3294 +2001,Fla,34,F,41952,3134 +2001,Fla,35,M,44876,3175 +2001,Fla,35,F,43308,2926 +2001,Fla,36,M,46726,3293 +2001,Fla,36,F,45569,2906 +2001,Fla,37,M,46459,3048 +2001,Fla,37,F,45186,2699 +2001,Fla,38,M,45922,3073 +2001,Fla,38,F,44585,2582 +2001,Fla,39,M,45682,2887 +2001,Fla,39,F,44985,2383 +2001,Fla,40,M,44816,2879 +2001,Fla,40,F,43778,2427 +2001,Fla,41,M,45571,2694 +2001,Fla,41,F,44609,2333 +2001,Fla,42,M,44761,2711 +2001,Fla,42,F,43442,2122 +2001,Fla,43,M,44201,2587 +2001,Fla,43,F,42808,2013 +2001,Fla,44,M,42960,2483 +2001,Fla,44,F,42249,2013 +2001,Fla,45,M,42300,2449 +2001,Fla,45,F,41826,1893 +2001,Fla,46,M,41538,2357 +2001,Fla,46,F,40687,1798 +2001,Fla,47,M,40648,2158 +2001,Fla,47,F,39366,1714 +2001,Fla,48,M,40566,2207 +2001,Fla,48,F,39129,1669 +2001,Fla,49,M,38693,2147 +2001,Fla,49,F,37673,1550 +2001,Fla,50,M,38029,2191 +2001,Fla,50,F,37601,1609 +2001,Fla,51,M,38246,2262 +2001,Fla,51,F,37303,1646 +2001,Fla,52,M,38113,2164 +2001,Fla,52,F,37739,1532 +2001,Fla,53,M,37849,2168 +2001,Fla,53,F,37301,1549 +2001,Fla,54,M,38776,2182 +2001,Fla,54,F,37916,1449 +2001,Fla,55,M,34325,1809 +2001,Fla,55,F,34148,1289 +2001,Fla,56,M,33995,1769 +2001,Fla,56,F,33897,1383 +2001,Fla,57,M,32402,1713 +2001,Fla,57,F,32540,1242 +2001,Fla,58,M,28133,1606 +2001,Fla,58,F,28321,1226 +2001,Fla,59,M,25219,1584 +2001,Fla,59,F,26057,1105 +2001,Fla,60,M,27792,1621 +2001,Fla,60,F,28857,1278 +2001,Fla,61,M,30283,1559 +2001,Fla,61,F,32219,1047 +2001,Fla,62,M,31229,1495 +2001,Fla,62,F,32864,1046 +2001,Fla,63,M,30161,1321 +2001,Fla,63,F,31702,989 +2001,Fla,64,M,28956,1297 +2001,Fla,64,F,31088,940 +2001,Fla,65,M,28567,1239 +2001,Fla,65,F,31005,861 +2001,Fla,66,M,28441,1161 +2001,Fla,66,F,31588,880 +2001,Fla,67,M,28256,1128 +2001,Fla,67,F,31341,857 +2001,Fla,68,M,28420,1066 +2001,Fla,68,F,32540,766 +2001,Fla,69,M,27887,954 +2001,Fla,69,F,32476,636 +2001,Fla,70,M,27001,924 +2001,Fla,70,F,32073,753 +2001,Fla,71,M,24486,788 +2001,Fla,71,F,29737,620 +2001,Fla,72,M,23187,757 +2001,Fla,72,F,28813,659 +2001,Fla,73,M,21886,665 +2001,Fla,73,F,27587,571 +2001,Fla,74,M,20772,605 +2001,Fla,74,F,27697,566 +2001,Fla,75,M,20240,585 +2001,Fla,75,F,26929,542 +2001,Fla,76,M,18912,549 +2001,Fla,76,F,25946,479 +2001,Fla,77,M,17640,528 +2001,Fla,77,F,25343,478 +2001,Fla,78,M,15839,430 +2001,Fla,78,F,23419,408 +2001,Fla,79,M,14643,396 +2001,Fla,79,F,22693,394 +2001,Fla,80,M,13413,346 +2001,Fla,80,F,21312,352 +2001,Fla,81,M,9290,228 +2001,Fla,81,F,15630,226 +2001,Fla,82,M,5615,167 +2001,Fla,82,F,10339,187 +2001,Fla,83,M,4934,141 +2001,Fla,83,F,9610,170 +2001,Fla,84,M,5111,133 +2001,Fla,84,F,10111,163 +2001,Fla,85,M,5402,112 +2001,Fla,85,F,11115,160 +2001,Fla,86,M,5160,98 +2001,Fla,86,F,11700,158 +2001,Fla,87,M,4303,79 +2001,Fla,87,F,10489,143 +2001,Fla,88,M,3531,60 +2001,Fla,88,F,8944,122 +2001,Fla,89,M,2736,56 +2001,Fla,89,F,7328,87 +2001,Fla,90,M,2114,28 +2001,Fla,90,F,6087,73 +2001,Fla,91,M,1542,32 +2001,Fla,91,F,4867,71 +2001,Fla,92,M,1126,26 +2001,Fla,92,F,4121,47 +2001,Fla,93,M,844,19 +2001,Fla,93,F,3063,39 +2001,Fla,94,M,543,10 +2001,Fla,94,F,2228,26 +2001,Fla,95,M,428,10 +2001,Fla,95,F,1673,25 +2001,Fla,96,M,279,6 +2001,Fla,96,F,1116,20 +2001,Fla,97,M,185,2 +2001,Fla,97,F,789,13 +2001,Fla,98,M,89,1 +2001,Fla,98,F,542,6 +2001,Fla,99,M,44,3 +2001,Fla,99,F,352,7 +2001,Fla,100,M,35,2 +2001,Fla,100,F,193,6 +2001,Fla,101,M,17,0 +2001,Fla,101,F,109,1 +2001,Fla,102,M,6,0 +2001,Fla,102,F,50,4 +2001,Fla,103,M,6,1 +2001,Fla,103,F,35,3 +2001,Fla,104,M,1,0 +2001,Fla,104,F,21,0 +2001,Fla,105,M,3,0 +2001,Fla,105,F,18,0 +2001,Fla,106,M,1,0 +2001,Fla,106,F,4,0 +2001,Fla,107,M,0,0 +2001,Fla,107,F,1,0 +2001,Fla,108,M,0,0 +2001,Fla,108,F,0,0 +2001,Fla,109,M,0,0 +2001,Fla,109,F,0,0 +2001,Fla,110,M,0,0 +2001,Fla,110,F,1,0 +2001,Fla,111,M,0,0 +2001,Fla,111,F,0,0 +2001,Fla,112,M,0,0 +2001,Fla,112,F,0,0 +2001,Fla,113,M,0,0 +2001,Fla,113,F,0,0 +2001,Fla,114,M,0,0 +2001,Fla,114,F,0,0 +2001,Fla,115,M,0,0 +2001,Fla,115,F,0,0 +2001,Fla,116,M,0,0 +2001,Fla,116,F,0,0 +2001,Fla,117,M,0,0 +2001,Fla,117,F,0,0 +2001,Fla,118,M,0,0 +2001,Fla,118,F,0,0 +2001,Fla,119,M,0,0 +2001,Fla,119,F,0,0 +2001,Fla,120,M,0,0 +2001,Fla,120,F,0,0 +2001,Wal,0,M,19321,834 +2001,Wal,0,F,18451,762 +2001,Wal,1,M,18925,829 +2001,Wal,1,F,18084,811 +2001,Wal,2,M,19063,849 +2001,Wal,2,F,18256,856 +2001,Wal,3,M,19168,950 +2001,Wal,3,F,18458,872 +2001,Wal,4,M,19505,990 +2001,Wal,4,F,18670,884 +2001,Wal,5,M,19018,977 +2001,Wal,5,F,18314,904 +2001,Wal,6,M,19247,1026 +2001,Wal,6,F,18327,953 +2001,Wal,7,M,20063,1063 +2001,Wal,7,F,18951,1068 +2001,Wal,8,M,21081,1173 +2001,Wal,8,F,20144,1104 +2001,Wal,9,M,21612,1211 +2001,Wal,9,F,20799,1134 +2001,Wal,10,M,21307,1232 +2001,Wal,10,F,20475,1198 +2001,Wal,11,M,21357,1246 +2001,Wal,11,F,20370,1218 +2001,Wal,12,M,21270,1222 +2001,Wal,12,F,20174,1193 +2001,Wal,13,M,20485,1263 +2001,Wal,13,F,19548,1172 +2001,Wal,14,M,20483,1314 +2001,Wal,14,F,19374,1196 +2001,Wal,15,M,19642,1282 +2001,Wal,15,F,18817,1206 +2001,Wal,16,M,19353,1343 +2001,Wal,16,F,18609,1328 +2001,Wal,17,M,19248,1424 +2001,Wal,17,F,17891,1384 +2001,Wal,18,M,19470,1427 +2001,Wal,18,F,18654,1593 +2001,Wal,19,M,19623,1471 +2001,Wal,19,F,19096,1677 +2001,Wal,20,M,19624,1568 +2001,Wal,20,F,18994,1786 +2001,Wal,21,M,19267,1647 +2001,Wal,21,F,18171,1841 +2001,Wal,22,M,18750,1749 +2001,Wal,22,F,17981,1888 +2001,Wal,23,M,18872,1764 +2001,Wal,23,F,17854,2016 +2001,Wal,24,M,18809,1904 +2001,Wal,24,F,18054,1990 +2001,Wal,25,M,18616,2058 +2001,Wal,25,F,17982,2127 +2001,Wal,26,M,19084,2287 +2001,Wal,26,F,18350,2316 +2001,Wal,27,M,19828,2598 +2001,Wal,27,F,19233,2464 +2001,Wal,28,M,20398,2734 +2001,Wal,28,F,19894,2652 +2001,Wal,29,M,20739,2788 +2001,Wal,29,F,20431,2687 +2001,Wal,30,M,20340,2856 +2001,Wal,30,F,19952,2712 +2001,Wal,31,M,20306,2976 +2001,Wal,31,F,20156,2845 +2001,Wal,32,M,19989,2962 +2001,Wal,32,F,20079,2948 +2001,Wal,33,M,20515,3019 +2001,Wal,33,F,20413,2871 +2001,Wal,34,M,20869,3460 +2001,Wal,34,F,20972,3154 +2001,Wal,35,M,21682,3641 +2001,Wal,35,F,21804,3076 +2001,Wal,36,M,22605,3514 +2001,Wal,36,F,22659,3156 +2001,Wal,37,M,22251,3513 +2001,Wal,37,F,22608,2997 +2001,Wal,38,M,21697,3443 +2001,Wal,38,F,22186,2822 +2001,Wal,39,M,22269,3374 +2001,Wal,39,F,22861,2977 +2001,Wal,40,M,22208,3664 +2001,Wal,40,F,22401,2795 +2001,Wal,41,M,22319,3483 +2001,Wal,41,F,23214,2785 +2001,Wal,42,M,21897,3533 +2001,Wal,42,F,22822,2732 +2001,Wal,43,M,21700,3490 +2001,Wal,43,F,22308,2624 +2001,Wal,44,M,21260,3542 +2001,Wal,44,F,22120,2665 +2001,Wal,45,M,21037,3392 +2001,Wal,45,F,22054,2563 +2001,Wal,46,M,20875,3353 +2001,Wal,46,F,21885,2503 +2001,Wal,47,M,20889,3181 +2001,Wal,47,F,21632,2268 +2001,Wal,48,M,20692,3059 +2001,Wal,48,F,21317,2276 +2001,Wal,49,M,19885,2994 +2001,Wal,49,F,20996,2261 +2001,Wal,50,M,20795,3034 +2001,Wal,50,F,21160,2320 +2001,Wal,51,M,20673,2901 +2001,Wal,51,F,21109,2143 +2001,Wal,52,M,21106,2904 +2001,Wal,52,F,21814,2266 +2001,Wal,53,M,21013,2891 +2001,Wal,53,F,21663,2087 +2001,Wal,54,M,20501,2670 +2001,Wal,54,F,21499,1921 +2001,Wal,55,M,15239,2126 +2001,Wal,55,F,16443,1643 +2001,Wal,56,M,15136,2117 +2001,Wal,56,F,16086,1661 +2001,Wal,57,M,14112,1896 +2001,Wal,57,F,15204,1516 +2001,Wal,58,M,12250,1778 +2001,Wal,58,F,13279,1479 +2001,Wal,59,M,11377,1744 +2001,Wal,59,F,12584,1427 +2001,Wal,60,M,12712,2020 +2001,Wal,60,F,14031,1695 +2001,Wal,61,M,13758,1864 +2001,Wal,61,F,15474,1678 +2001,Wal,62,M,13803,1723 +2001,Wal,62,F,15708,1669 +2001,Wal,63,M,13144,1779 +2001,Wal,63,F,14862,1506 +2001,Wal,64,M,12724,1717 +2001,Wal,64,F,14831,1535 +2001,Wal,65,M,12376,1664 +2001,Wal,65,F,14741,1590 +2001,Wal,66,M,12888,1570 +2001,Wal,66,F,15345,1576 +2001,Wal,67,M,12837,1548 +2001,Wal,67,F,15317,1611 +2001,Wal,68,M,13328,1601 +2001,Wal,68,F,16585,1513 +2001,Wal,69,M,13436,1433 +2001,Wal,69,F,17000,1516 +2001,Wal,70,M,12982,1528 +2001,Wal,70,F,16984,1572 +2001,Wal,71,M,12062,1429 +2001,Wal,71,F,16043,1490 +2001,Wal,72,M,11520,1328 +2001,Wal,72,F,16139,1402 +2001,Wal,73,M,11017,1346 +2001,Wal,73,F,15605,1435 +2001,Wal,74,M,10609,1298 +2001,Wal,74,F,15461,1448 +2001,Wal,75,M,10243,1154 +2001,Wal,75,F,15776,1367 +2001,Wal,76,M,9559,1093 +2001,Wal,76,F,15166,1278 +2001,Wal,77,M,8779,1019 +2001,Wal,77,F,14509,1194 +2001,Wal,78,M,8192,862 +2001,Wal,78,F,14113,1103 +2001,Wal,79,M,7613,722 +2001,Wal,79,F,13987,984 +2001,Wal,80,M,6898,602 +2001,Wal,80,F,13164,917 +2001,Wal,81,M,4520,356 +2001,Wal,81,F,9141,593 +2001,Wal,82,M,2820,235 +2001,Wal,82,F,6087,370 +2001,Wal,83,M,2414,199 +2001,Wal,83,F,5481,339 +2001,Wal,84,M,2435,181 +2001,Wal,84,F,5572,351 +2001,Wal,85,M,2421,187 +2001,Wal,85,F,6123,404 +2001,Wal,86,M,2430,168 +2001,Wal,86,F,6639,394 +2001,Wal,87,M,2002,165 +2001,Wal,87,F,5697,361 +2001,Wal,88,M,1553,139 +2001,Wal,88,F,5040,273 +2001,Wal,89,M,1179,65 +2001,Wal,89,F,4053,243 +2001,Wal,90,M,935,55 +2001,Wal,90,F,3442,220 +2001,Wal,91,M,668,30 +2001,Wal,91,F,2686,174 +2001,Wal,92,M,489,36 +2001,Wal,92,F,2267,131 +2001,Wal,93,M,349,13 +2001,Wal,93,F,1748,81 +2001,Wal,94,M,254,16 +2001,Wal,94,F,1249,77 +2001,Wal,95,M,169,13 +2001,Wal,95,F,907,56 +2001,Wal,96,M,103,5 +2001,Wal,96,F,635,47 +2001,Wal,97,M,73,5 +2001,Wal,97,F,428,21 +2001,Wal,98,M,39,3 +2001,Wal,98,F,245,26 +2001,Wal,99,M,24,1 +2001,Wal,99,F,195,15 +2001,Wal,100,M,13,2 +2001,Wal,100,F,110,10 +2001,Wal,101,M,11,1 +2001,Wal,101,F,56,2 +2001,Wal,102,M,5,1 +2001,Wal,102,F,33,0 +2001,Wal,103,M,2,0 +2001,Wal,103,F,18,3 +2001,Wal,104,M,0,0 +2001,Wal,104,F,7,0 +2001,Wal,105,M,1,0 +2001,Wal,105,F,8,0 +2001,Wal,106,M,0,0 +2001,Wal,106,F,1,0 +2001,Wal,107,M,1,0 +2001,Wal,107,F,2,0 +2001,Wal,108,M,0,0 +2001,Wal,108,F,2,0 +2001,Wal,109,M,0,0 +2001,Wal,109,F,1,0 +2001,Wal,110,M,0,0 +2001,Wal,110,F,0,0 +2001,Wal,111,M,0,0 +2001,Wal,111,F,0,0 +2001,Wal,112,M,0,0 +2001,Wal,112,F,0,0 +2001,Wal,113,M,0,0 +2001,Wal,113,F,0,0 +2001,Wal,114,M,0,0 +2001,Wal,114,F,0,0 +2001,Wal,115,M,0,0 +2001,Wal,115,F,0,0 +2001,Wal,116,M,0,0 +2001,Wal,116,F,0,0 +2001,Wal,117,M,0,0 +2001,Wal,117,F,0,0 +2001,Wal,118,M,0,0 +2001,Wal,118,F,0,0 +2001,Wal,119,M,0,0 +2001,Wal,119,F,0,0 +2001,Wal,120,M,0,0 +2001,Wal,120,F,0,0 +2002,BruCap,0,M,5736,1497 +2002,BruCap,0,F,5580,1450 +2002,BruCap,1,M,5504,1364 +2002,BruCap,1,F,5101,1395 +2002,BruCap,2,M,5185,1321 +2002,BruCap,2,F,4943,1326 +2002,BruCap,3,M,5009,1287 +2002,BruCap,3,F,4745,1352 +2002,BruCap,4,M,4977,1359 +2002,BruCap,4,F,4626,1217 +2002,BruCap,5,M,4660,1301 +2002,BruCap,5,F,4622,1244 +2002,BruCap,6,M,4562,1349 +2002,BruCap,6,F,4433,1213 +2002,BruCap,7,M,4589,1327 +2002,BruCap,7,F,4261,1184 +2002,BruCap,8,M,4597,1270 +2002,BruCap,8,F,4325,1199 +2002,BruCap,9,M,4487,1336 +2002,BruCap,9,F,4436,1162 +2002,BruCap,10,M,4469,1222 +2002,BruCap,10,F,4400,1146 +2002,BruCap,11,M,4505,1274 +2002,BruCap,11,F,4254,1212 +2002,BruCap,12,M,4369,1213 +2002,BruCap,12,F,4251,1143 +2002,BruCap,13,M,4386,1216 +2002,BruCap,13,F,4180,1124 +2002,BruCap,14,M,4212,1207 +2002,BruCap,14,F,4094,1159 +2002,BruCap,15,M,4179,1187 +2002,BruCap,15,F,3985,1143 +2002,BruCap,16,M,4103,1190 +2002,BruCap,16,F,3721,1163 +2002,BruCap,17,M,4110,1181 +2002,BruCap,17,F,3956,1280 +2002,BruCap,18,M,3964,1304 +2002,BruCap,18,F,3884,1369 +2002,BruCap,19,M,4074,1452 +2002,BruCap,19,F,4017,1571 +2002,BruCap,20,M,4409,1549 +2002,BruCap,20,F,4337,1762 +2002,BruCap,21,M,4411,1610 +2002,BruCap,21,F,4596,1991 +2002,BruCap,22,M,4520,1782 +2002,BruCap,22,F,4549,2273 +2002,BruCap,23,M,4511,2007 +2002,BruCap,23,F,4963,2453 +2002,BruCap,24,M,4830,2333 +2002,BruCap,24,F,5133,2599 +2002,BruCap,25,M,4779,2687 +2002,BruCap,25,F,5319,2842 +2002,BruCap,26,M,5141,2656 +2002,BruCap,26,F,5205,2977 +2002,BruCap,27,M,5151,3126 +2002,BruCap,27,F,5238,3168 +2002,BruCap,28,M,5356,3232 +2002,BruCap,28,F,5369,3231 +2002,BruCap,29,M,5453,3370 +2002,BruCap,29,F,5331,3341 +2002,BruCap,30,M,5378,3474 +2002,BruCap,30,F,5262,3360 +2002,BruCap,31,M,5319,3664 +2002,BruCap,31,F,5159,3209 +2002,BruCap,32,M,5196,3468 +2002,BruCap,32,F,4843,3288 +2002,BruCap,33,M,4972,3466 +2002,BruCap,33,F,4710,3086 +2002,BruCap,34,M,4851,3299 +2002,BruCap,34,F,4640,2994 +2002,BruCap,35,M,4879,3317 +2002,BruCap,35,F,4714,2935 +2002,BruCap,36,M,5083,3234 +2002,BruCap,36,F,4744,2897 +2002,BruCap,37,M,4959,3129 +2002,BruCap,37,F,4754,2870 +2002,BruCap,38,M,4895,2842 +2002,BruCap,38,F,4718,2577 +2002,BruCap,39,M,4655,2840 +2002,BruCap,39,F,4612,2474 +2002,BruCap,40,M,4610,2480 +2002,BruCap,40,F,4636,2300 +2002,BruCap,41,M,4704,2435 +2002,BruCap,41,F,4768,2355 +2002,BruCap,42,M,4646,2249 +2002,BruCap,42,F,4753,2163 +2002,BruCap,43,M,4488,2104 +2002,BruCap,43,F,4668,1994 +2002,BruCap,44,M,4436,1935 +2002,BruCap,44,F,4678,1906 +2002,BruCap,45,M,4315,2001 +2002,BruCap,45,F,4675,1926 +2002,BruCap,46,M,4350,1941 +2002,BruCap,46,F,4679,1803 +2002,BruCap,47,M,4311,1714 +2002,BruCap,47,F,4590,1740 +2002,BruCap,48,M,4339,1665 +2002,BruCap,48,F,4601,1636 +2002,BruCap,49,M,4352,1712 +2002,BruCap,49,F,4637,1695 +2002,BruCap,50,M,4098,1533 +2002,BruCap,50,F,4397,1470 +2002,BruCap,51,M,4080,1635 +2002,BruCap,51,F,4573,1573 +2002,BruCap,52,M,4053,1483 +2002,BruCap,52,F,4463,1390 +2002,BruCap,53,M,4079,1559 +2002,BruCap,53,F,4476,1427 +2002,BruCap,54,M,4071,1461 +2002,BruCap,54,F,4639,1356 +2002,BruCap,55,M,4064,1368 +2002,BruCap,55,F,4486,1345 +2002,BruCap,56,M,3483,1208 +2002,BruCap,56,F,3950,1147 +2002,BruCap,57,M,3589,1257 +2002,BruCap,57,F,4133,1157 +2002,BruCap,58,M,3466,1137 +2002,BruCap,58,F,3925,1070 +2002,BruCap,59,M,3045,1107 +2002,BruCap,59,F,3375,1046 +2002,BruCap,60,M,2591,955 +2002,BruCap,60,F,2973,883 +2002,BruCap,61,M,2924,1115 +2002,BruCap,61,F,3351,1163 +2002,BruCap,62,M,2972,1027 +2002,BruCap,62,F,3606,975 +2002,BruCap,63,M,2975,1019 +2002,BruCap,63,F,3496,917 +2002,BruCap,64,M,2821,936 +2002,BruCap,64,F,3405,841 +2002,BruCap,65,M,2788,880 +2002,BruCap,65,F,3399,877 +2002,BruCap,66,M,2721,770 +2002,BruCap,66,F,3502,847 +2002,BruCap,67,M,2818,743 +2002,BruCap,67,F,3463,765 +2002,BruCap,68,M,2697,705 +2002,BruCap,68,F,3695,673 +2002,BruCap,69,M,2871,702 +2002,BruCap,69,F,3874,678 +2002,BruCap,70,M,2864,579 +2002,BruCap,70,F,3892,628 +2002,BruCap,71,M,2714,660 +2002,BruCap,71,F,4215,698 +2002,BruCap,72,M,2611,542 +2002,BruCap,72,F,4034,503 +2002,BruCap,73,M,2637,473 +2002,BruCap,73,F,3966,536 +2002,BruCap,74,M,2534,419 +2002,BruCap,74,F,4012,456 +2002,BruCap,75,M,2488,388 +2002,BruCap,75,F,4099,419 +2002,BruCap,76,M,2467,335 +2002,BruCap,76,F,4115,408 +2002,BruCap,77,M,2451,261 +2002,BruCap,77,F,4213,374 +2002,BruCap,78,M,2232,264 +2002,BruCap,78,F,4205,345 +2002,BruCap,79,M,2108,254 +2002,BruCap,79,F,4088,288 +2002,BruCap,80,M,2147,217 +2002,BruCap,80,F,4062,256 +2002,BruCap,81,M,1907,167 +2002,BruCap,81,F,3985,308 +2002,BruCap,82,M,1354,100 +2002,BruCap,82,F,2731,181 +2002,BruCap,83,M,786,92 +2002,BruCap,83,F,1906,134 +2002,BruCap,84,M,721,75 +2002,BruCap,84,F,1772,138 +2002,BruCap,85,M,646,50 +2002,BruCap,85,F,1794,105 +2002,BruCap,86,M,717,57 +2002,BruCap,86,F,2020,110 +2002,BruCap,87,M,775,54 +2002,BruCap,87,F,2159,119 +2002,BruCap,88,M,620,39 +2002,BruCap,88,F,1862,116 +2002,BruCap,89,M,473,44 +2002,BruCap,89,F,1593,105 +2002,BruCap,90,M,371,25 +2002,BruCap,90,F,1361,74 +2002,BruCap,91,M,284,25 +2002,BruCap,91,F,1143,74 +2002,BruCap,92,M,204,12 +2002,BruCap,92,F,860,60 +2002,BruCap,93,M,155,11 +2002,BruCap,93,F,748,38 +2002,BruCap,94,M,104,9 +2002,BruCap,94,F,531,24 +2002,BruCap,95,M,75,5 +2002,BruCap,95,F,417,24 +2002,BruCap,96,M,63,1 +2002,BruCap,96,F,309,16 +2002,BruCap,97,M,33,6 +2002,BruCap,97,F,221,12 +2002,BruCap,98,M,18,2 +2002,BruCap,98,F,146,9 +2002,BruCap,99,M,13,1 +2002,BruCap,99,F,96,11 +2002,BruCap,100,M,11,3 +2002,BruCap,100,F,52,4 +2002,BruCap,101,M,2,2 +2002,BruCap,101,F,31,4 +2002,BruCap,102,M,1,1 +2002,BruCap,102,F,24,2 +2002,BruCap,103,M,0,1 +2002,BruCap,103,F,13,7 +2002,BruCap,104,M,0,1 +2002,BruCap,104,F,7,1 +2002,BruCap,105,M,0,0 +2002,BruCap,105,F,6,0 +2002,BruCap,106,M,0,0 +2002,BruCap,106,F,5,2 +2002,BruCap,107,M,0,0 +2002,BruCap,107,F,1,0 +2002,BruCap,108,M,0,1 +2002,BruCap,108,F,2,0 +2002,BruCap,109,M,0,0 +2002,BruCap,109,F,2,0 +2002,BruCap,110,M,0,0 +2002,BruCap,110,F,1,0 +2002,BruCap,111,M,1,0 +2002,BruCap,111,F,0,0 +2002,BruCap,112,M,0,0 +2002,BruCap,112,F,0,0 +2002,BruCap,113,M,0,0 +2002,BruCap,113,F,0,0 +2002,BruCap,114,M,0,0 +2002,BruCap,114,F,0,0 +2002,BruCap,115,M,0,0 +2002,BruCap,115,F,0,0 +2002,BruCap,116,M,0,0 +2002,BruCap,116,F,0,0 +2002,BruCap,117,M,0,0 +2002,BruCap,117,F,0,0 +2002,BruCap,118,M,0,0 +2002,BruCap,118,F,0,0 +2002,BruCap,119,M,0,0 +2002,BruCap,119,F,0,0 +2002,BruCap,120,M,0,0 +2002,BruCap,120,F,0,0 +2002,Fla,0,M,29395,1384 +2002,Fla,0,F,28085,1296 +2002,Fla,1,M,30244,1493 +2002,Fla,1,F,29018,1392 +2002,Fla,2,M,30343,1377 +2002,Fla,2,F,29386,1342 +2002,Fla,3,M,31275,1395 +2002,Fla,3,F,29752,1342 +2002,Fla,4,M,31974,1425 +2002,Fla,4,F,30765,1378 +2002,Fla,5,M,32223,1258 +2002,Fla,5,F,30891,1347 +2002,Fla,6,M,32327,1384 +2002,Fla,6,F,30936,1260 +2002,Fla,7,M,32735,1469 +2002,Fla,7,F,31120,1333 +2002,Fla,8,M,34050,1381 +2002,Fla,8,F,33136,1324 +2002,Fla,9,M,35391,1397 +2002,Fla,9,F,33933,1326 +2002,Fla,10,M,35921,1437 +2002,Fla,10,F,34047,1385 +2002,Fla,11,M,35484,1410 +2002,Fla,11,F,33869,1366 +2002,Fla,12,M,34438,1285 +2002,Fla,12,F,32788,1258 +2002,Fla,13,M,34058,1285 +2002,Fla,13,F,32517,1276 +2002,Fla,14,M,33705,1251 +2002,Fla,14,F,31887,1277 +2002,Fla,15,M,33815,1237 +2002,Fla,15,F,31842,1190 +2002,Fla,16,M,32777,1268 +2002,Fla,16,F,31304,1271 +2002,Fla,17,M,33518,1369 +2002,Fla,17,F,31919,1329 +2002,Fla,18,M,34503,1247 +2002,Fla,18,F,33137,1425 +2002,Fla,19,M,35392,1453 +2002,Fla,19,F,33525,1539 +2002,Fla,20,M,36519,1523 +2002,Fla,20,F,34412,1771 +2002,Fla,21,M,36070,1678 +2002,Fla,21,F,34716,1982 +2002,Fla,22,M,36414,1804 +2002,Fla,22,F,34522,2138 +2002,Fla,23,M,35476,1951 +2002,Fla,23,F,34216,2374 +2002,Fla,24,M,34620,2133 +2002,Fla,24,F,33644,2519 +2002,Fla,25,M,33821,2206 +2002,Fla,25,F,32421,2550 +2002,Fla,26,M,32900,2333 +2002,Fla,26,F,31470,2603 +2002,Fla,27,M,34107,2649 +2002,Fla,27,F,33015,2729 +2002,Fla,28,M,35448,2717 +2002,Fla,28,F,34171,2739 +2002,Fla,29,M,36967,2866 +2002,Fla,29,F,36090,2891 +2002,Fla,30,M,38770,2955 +2002,Fla,30,F,38080,2942 +2002,Fla,31,M,39985,3082 +2002,Fla,31,F,38821,3119 +2002,Fla,32,M,40080,3098 +2002,Fla,32,F,38992,2966 +2002,Fla,33,M,40574,3134 +2002,Fla,33,F,39430,2974 +2002,Fla,34,M,42118,2902 +2002,Fla,34,F,40281,2853 +2002,Fla,35,M,43413,3259 +2002,Fla,35,F,42246,3006 +2002,Fla,36,M,45015,3097 +2002,Fla,36,F,43544,2861 +2002,Fla,37,M,46927,3188 +2002,Fla,37,F,45786,2813 +2002,Fla,38,M,46649,2987 +2002,Fla,38,F,45387,2577 +2002,Fla,39,M,46126,2946 +2002,Fla,39,F,44795,2468 +2002,Fla,40,M,45817,2798 +2002,Fla,40,F,45162,2284 +2002,Fla,41,M,44919,2771 +2002,Fla,41,F,43991,2314 +2002,Fla,42,M,45692,2628 +2002,Fla,42,F,44776,2219 +2002,Fla,43,M,44850,2642 +2002,Fla,43,F,43579,2013 +2002,Fla,44,M,44213,2508 +2002,Fla,44,F,42927,1878 +2002,Fla,45,M,42941,2441 +2002,Fla,45,F,42379,1906 +2002,Fla,46,M,42300,2391 +2002,Fla,46,F,41915,1808 +2002,Fla,47,M,41538,2310 +2002,Fla,47,F,40737,1706 +2002,Fla,48,M,40592,2139 +2002,Fla,48,F,39404,1643 +2002,Fla,49,M,40499,2169 +2002,Fla,49,F,39169,1604 +2002,Fla,50,M,38600,2135 +2002,Fla,50,F,37692,1519 +2002,Fla,51,M,38017,2102 +2002,Fla,51,F,37572,1582 +2002,Fla,52,M,38162,2200 +2002,Fla,52,F,37284,1602 +2002,Fla,53,M,38026,2108 +2002,Fla,53,F,37709,1507 +2002,Fla,54,M,37693,2113 +2002,Fla,54,F,37244,1521 +2002,Fla,55,M,38601,2105 +2002,Fla,55,F,37855,1394 +2002,Fla,56,M,34133,1742 +2002,Fla,56,F,34069,1294 +2002,Fla,57,M,33801,1709 +2002,Fla,57,F,33802,1378 +2002,Fla,58,M,32220,1677 +2002,Fla,58,F,32441,1230 +2002,Fla,59,M,28022,1547 +2002,Fla,59,F,28251,1182 +2002,Fla,60,M,25065,1497 +2002,Fla,60,F,25954,1088 +2002,Fla,61,M,27585,1558 +2002,Fla,61,F,28756,1261 +2002,Fla,62,M,30044,1456 +2002,Fla,62,F,32064,1014 +2002,Fla,63,M,30953,1411 +2002,Fla,63,F,32735,1041 +2002,Fla,64,M,29788,1239 +2002,Fla,64,F,31540,959 +2002,Fla,65,M,28527,1215 +2002,Fla,65,F,30912,917 +2002,Fla,66,M,28147,1167 +2002,Fla,66,F,30769,828 +2002,Fla,67,M,28039,1072 +2002,Fla,67,F,31339,855 +2002,Fla,68,M,27707,1077 +2002,Fla,68,F,31067,836 +2002,Fla,69,M,27770,1002 +2002,Fla,69,F,32218,746 +2002,Fla,70,M,27245,919 +2002,Fla,70,F,32085,619 +2002,Fla,71,M,26277,864 +2002,Fla,71,F,31615,728 +2002,Fla,72,M,23745,760 +2002,Fla,72,F,29309,600 +2002,Fla,73,M,22371,713 +2002,Fla,73,F,28321,638 +2002,Fla,74,M,21055,623 +2002,Fla,74,F,27038,565 +2002,Fla,75,M,19887,566 +2002,Fla,75,F,27067,548 +2002,Fla,76,M,19317,552 +2002,Fla,76,F,26251,526 +2002,Fla,77,M,17895,522 +2002,Fla,77,F,25188,471 +2002,Fla,78,M,16598,479 +2002,Fla,78,F,24488,459 +2002,Fla,79,M,14804,405 +2002,Fla,79,F,22564,394 +2002,Fla,80,M,13624,361 +2002,Fla,80,F,21714,375 +2002,Fla,81,M,12325,310 +2002,Fla,81,F,20275,333 +2002,Fla,82,M,8432,203 +2002,Fla,82,F,14715,213 +2002,Fla,83,M,5075,147 +2002,Fla,83,F,9687,178 +2002,Fla,84,M,4365,128 +2002,Fla,84,F,8896,160 +2002,Fla,85,M,4456,116 +2002,Fla,85,F,9274,146 +2002,Fla,86,M,4635,103 +2002,Fla,86,F,10055,144 +2002,Fla,87,M,4354,85 +2002,Fla,87,F,10456,146 +2002,Fla,88,M,3598,67 +2002,Fla,88,F,9237,124 +2002,Fla,89,M,2861,42 +2002,Fla,89,F,7697,103 +2002,Fla,90,M,2164,47 +2002,Fla,90,F,6263,76 +2002,Fla,91,M,1666,26 +2002,Fla,91,F,5054,63 +2002,Fla,92,M,1180,22 +2002,Fla,92,F,3973,58 +2002,Fla,93,M,841,22 +2002,Fla,93,F,3304,35 +2002,Fla,94,M,613,11 +2002,Fla,94,F,2393,26 +2002,Fla,95,M,380,8 +2002,Fla,95,F,1689,17 +2002,Fla,96,M,298,8 +2002,Fla,96,F,1214,21 +2002,Fla,97,M,180,4 +2002,Fla,97,F,825,11 +2002,Fla,98,M,110,1 +2002,Fla,98,F,540,12 +2002,Fla,99,M,58,1 +2002,Fla,99,F,372,3 +2002,Fla,100,M,27,2 +2002,Fla,100,F,226,2 +2002,Fla,101,M,21,1 +2002,Fla,101,F,124,4 +2002,Fla,102,M,11,0 +2002,Fla,102,F,68,1 +2002,Fla,103,M,5,0 +2002,Fla,103,F,31,0 +2002,Fla,104,M,2,1 +2002,Fla,104,F,17,3 +2002,Fla,105,M,1,0 +2002,Fla,105,F,10,0 +2002,Fla,106,M,1,0 +2002,Fla,106,F,9,0 +2002,Fla,107,M,0,0 +2002,Fla,107,F,0,0 +2002,Fla,108,M,0,0 +2002,Fla,108,F,0,0 +2002,Fla,109,M,0,0 +2002,Fla,109,F,0,0 +2002,Fla,110,M,0,0 +2002,Fla,110,F,0,0 +2002,Fla,111,M,0,0 +2002,Fla,111,F,1,0 +2002,Fla,112,M,0,0 +2002,Fla,112,F,0,0 +2002,Fla,113,M,0,0 +2002,Fla,113,F,0,0 +2002,Fla,114,M,0,0 +2002,Fla,114,F,0,0 +2002,Fla,115,M,0,0 +2002,Fla,115,F,0,0 +2002,Fla,116,M,0,0 +2002,Fla,116,F,0,0 +2002,Fla,117,M,0,0 +2002,Fla,117,F,0,0 +2002,Fla,118,M,0,0 +2002,Fla,118,F,0,0 +2002,Fla,119,M,0,0 +2002,Fla,119,F,0,0 +2002,Fla,120,M,0,0 +2002,Fla,120,F,0,0 +2002,Wal,0,M,19064,731 +2002,Wal,0,F,18343,688 +2002,Wal,1,M,19592,828 +2002,Wal,1,F,18754,749 +2002,Wal,2,M,19175,787 +2002,Wal,2,F,18304,768 +2002,Wal,3,M,19256,807 +2002,Wal,3,F,18457,796 +2002,Wal,4,M,19337,880 +2002,Wal,4,F,18634,810 +2002,Wal,5,M,19668,936 +2002,Wal,5,F,18812,859 +2002,Wal,6,M,19160,944 +2002,Wal,6,F,18476,850 +2002,Wal,7,M,19400,972 +2002,Wal,7,F,18455,950 +2002,Wal,8,M,20192,1035 +2002,Wal,8,F,19093,1006 +2002,Wal,9,M,21213,1132 +2002,Wal,9,F,20271,1034 +2002,Wal,10,M,21764,1140 +2002,Wal,10,F,20925,1115 +2002,Wal,11,M,21427,1162 +2002,Wal,11,F,20599,1121 +2002,Wal,12,M,21542,1157 +2002,Wal,12,F,20526,1155 +2002,Wal,13,M,21390,1152 +2002,Wal,13,F,20278,1157 +2002,Wal,14,M,20631,1215 +2002,Wal,14,F,19659,1119 +2002,Wal,15,M,20575,1279 +2002,Wal,15,F,19500,1170 +2002,Wal,16,M,19761,1238 +2002,Wal,16,F,18917,1199 +2002,Wal,17,M,19477,1294 +2002,Wal,17,F,18726,1311 +2002,Wal,18,M,19378,1339 +2002,Wal,18,F,18060,1371 +2002,Wal,19,M,19553,1331 +2002,Wal,19,F,18794,1532 +2002,Wal,20,M,19651,1485 +2002,Wal,20,F,19145,1665 +2002,Wal,21,M,19632,1601 +2002,Wal,21,F,19050,1846 +2002,Wal,22,M,19177,1718 +2002,Wal,22,F,18082,1925 +2002,Wal,23,M,18605,1812 +2002,Wal,23,F,17824,1939 +2002,Wal,24,M,18556,1855 +2002,Wal,24,F,17678,2032 +2002,Wal,25,M,18651,1996 +2002,Wal,25,F,17894,2015 +2002,Wal,26,M,18444,2126 +2002,Wal,26,F,17934,2115 +2002,Wal,27,M,19057,2314 +2002,Wal,27,F,18398,2348 +2002,Wal,28,M,19791,2634 +2002,Wal,28,F,19340,2439 +2002,Wal,29,M,20493,2755 +2002,Wal,29,F,20069,2627 +2002,Wal,30,M,20858,2831 +2002,Wal,30,F,20663,2662 +2002,Wal,31,M,20494,2874 +2002,Wal,31,F,20166,2699 +2002,Wal,32,M,20459,2971 +2002,Wal,32,F,20349,2825 +2002,Wal,33,M,20120,2976 +2002,Wal,33,F,20260,2911 +2002,Wal,34,M,20644,3058 +2002,Wal,34,F,20612,2829 +2002,Wal,35,M,21044,3469 +2002,Wal,35,F,21150,3133 +2002,Wal,36,M,21906,3558 +2002,Wal,36,F,21988,3008 +2002,Wal,37,M,22796,3418 +2002,Wal,37,F,22873,3053 +2002,Wal,38,M,22353,3437 +2002,Wal,38,F,22771,2942 +2002,Wal,39,M,21844,3362 +2002,Wal,39,F,22352,2752 +2002,Wal,40,M,22431,3284 +2002,Wal,40,F,23002,2853 +2002,Wal,41,M,22324,3596 +2002,Wal,41,F,22533,2716 +2002,Wal,42,M,22380,3393 +2002,Wal,42,F,23320,2674 +2002,Wal,43,M,21979,3430 +2002,Wal,43,F,22944,2647 +2002,Wal,44,M,21761,3367 +2002,Wal,44,F,22379,2530 +2002,Wal,45,M,21314,3454 +2002,Wal,45,F,22189,2591 +2002,Wal,46,M,21069,3272 +2002,Wal,46,F,22151,2475 +2002,Wal,47,M,20919,3243 +2002,Wal,47,F,21969,2395 +2002,Wal,48,M,20872,3086 +2002,Wal,48,F,21682,2211 +2002,Wal,49,M,20667,2973 +2002,Wal,49,F,21354,2238 +2002,Wal,50,M,19892,2893 +2002,Wal,50,F,21031,2210 +2002,Wal,51,M,20727,2942 +2002,Wal,51,F,21153,2252 +2002,Wal,52,M,20578,2803 +2002,Wal,52,F,21094,2057 +2002,Wal,53,M,21005,2820 +2002,Wal,53,F,21806,2193 +2002,Wal,54,M,20908,2821 +2002,Wal,54,F,21625,2036 +2002,Wal,55,M,20403,2607 +2002,Wal,55,F,21436,1906 +2002,Wal,56,M,15136,2072 +2002,Wal,56,F,16403,1611 +2002,Wal,57,M,15044,2088 +2002,Wal,57,F,16046,1635 +2002,Wal,58,M,13998,1850 +2002,Wal,58,F,15167,1483 +2002,Wal,59,M,12129,1741 +2002,Wal,59,F,13255,1445 +2002,Wal,60,M,11290,1680 +2002,Wal,60,F,12525,1392 +2002,Wal,61,M,12590,1926 +2002,Wal,61,F,13968,1644 +2002,Wal,62,M,13597,1795 +2002,Wal,62,F,15388,1634 +2002,Wal,63,M,13601,1663 +2002,Wal,63,F,15609,1650 +2002,Wal,64,M,12993,1717 +2002,Wal,64,F,14775,1490 +2002,Wal,65,M,12499,1625 +2002,Wal,65,F,14733,1506 +2002,Wal,66,M,12158,1599 +2002,Wal,66,F,14589,1564 +2002,Wal,67,M,12562,1525 +2002,Wal,67,F,15140,1563 +2002,Wal,68,M,12545,1470 +2002,Wal,68,F,15142,1565 +2002,Wal,69,M,12971,1522 +2002,Wal,69,F,16388,1481 +2002,Wal,70,M,13029,1370 +2002,Wal,70,F,16759,1486 +2002,Wal,71,M,12505,1456 +2002,Wal,71,F,16736,1547 +2002,Wal,72,M,11598,1365 +2002,Wal,72,F,15748,1454 +2002,Wal,73,M,11065,1263 +2002,Wal,73,F,15781,1367 +2002,Wal,74,M,10552,1279 +2002,Wal,74,F,15283,1402 +2002,Wal,75,M,10130,1218 +2002,Wal,75,F,15082,1406 +2002,Wal,76,M,9685,1081 +2002,Wal,76,F,15345,1324 +2002,Wal,77,M,9004,1016 +2002,Wal,77,F,14673,1237 +2002,Wal,78,M,8219,935 +2002,Wal,78,F,13988,1141 +2002,Wal,79,M,7549,785 +2002,Wal,79,F,13523,1056 +2002,Wal,80,M,7017,640 +2002,Wal,80,F,13310,927 +2002,Wal,81,M,6221,539 +2002,Wal,81,F,12489,877 +2002,Wal,82,M,4085,318 +2002,Wal,82,F,8566,549 +2002,Wal,83,M,2495,200 +2002,Wal,83,F,5676,329 +2002,Wal,84,M,2139,172 +2002,Wal,84,F,5067,316 +2002,Wal,85,M,2132,159 +2002,Wal,85,F,5044,328 +2002,Wal,86,M,2037,155 +2002,Wal,86,F,5514,372 +2002,Wal,87,M,2060,143 +2002,Wal,87,F,5892,365 +2002,Wal,88,M,1670,132 +2002,Wal,88,F,4987,306 +2002,Wal,89,M,1247,112 +2002,Wal,89,F,4286,237 +2002,Wal,90,M,917,58 +2002,Wal,90,F,3368,194 +2002,Wal,91,M,734,42 +2002,Wal,91,F,2797,176 +2002,Wal,92,M,493,28 +2002,Wal,92,F,2188,136 +2002,Wal,93,M,341,28 +2002,Wal,93,F,1752,109 +2002,Wal,94,M,241,10 +2002,Wal,94,F,1365,64 +2002,Wal,95,M,181,9 +2002,Wal,95,F,935,61 +2002,Wal,96,M,109,8 +2002,Wal,96,F,667,38 +2002,Wal,97,M,63,4 +2002,Wal,97,F,453,40 +2002,Wal,98,M,49,3 +2002,Wal,98,F,300,14 +2002,Wal,99,M,25,3 +2002,Wal,99,F,171,20 +2002,Wal,100,M,16,0 +2002,Wal,100,F,126,8 +2002,Wal,101,M,8,2 +2002,Wal,101,F,67,9 +2002,Wal,102,M,7,1 +2002,Wal,102,F,32,2 +2002,Wal,103,M,1,0 +2002,Wal,103,F,19,0 +2002,Wal,104,M,2,0 +2002,Wal,104,F,13,2 +2002,Wal,105,M,0,0 +2002,Wal,105,F,4,0 +2002,Wal,106,M,0,0 +2002,Wal,106,F,5,0 +2002,Wal,107,M,0,0 +2002,Wal,107,F,0,0 +2002,Wal,108,M,1,0 +2002,Wal,108,F,1,0 +2002,Wal,109,M,0,0 +2002,Wal,109,F,1,0 +2002,Wal,110,M,0,0 +2002,Wal,110,F,0,0 +2002,Wal,111,M,0,0 +2002,Wal,111,F,0,0 +2002,Wal,112,M,0,0 +2002,Wal,112,F,0,0 +2002,Wal,113,M,0,0 +2002,Wal,113,F,0,0 +2002,Wal,114,M,0,0 +2002,Wal,114,F,0,0 +2002,Wal,115,M,0,0 +2002,Wal,115,F,0,0 +2002,Wal,116,M,0,0 +2002,Wal,116,F,0,0 +2002,Wal,117,M,0,0 +2002,Wal,117,F,0,0 +2002,Wal,118,M,0,0 +2002,Wal,118,F,0,0 +2002,Wal,119,M,0,0 +2002,Wal,119,F,0,0 +2002,Wal,120,M,0,0 +2002,Wal,120,F,0,0 +2003,BruCap,0,M,5719,1348 +2003,BruCap,0,F,5497,1376 +2003,BruCap,1,M,5742,1400 +2003,BruCap,1,F,5593,1375 +2003,BruCap,2,M,5503,1281 +2003,BruCap,2,F,5133,1272 +2003,BruCap,3,M,5211,1263 +2003,BruCap,3,F,4968,1241 +2003,BruCap,4,M,5088,1214 +2003,BruCap,4,F,4784,1259 +2003,BruCap,5,M,5037,1269 +2003,BruCap,5,F,4677,1124 +2003,BruCap,6,M,4754,1217 +2003,BruCap,6,F,4684,1147 +2003,BruCap,7,M,4625,1268 +2003,BruCap,7,F,4465,1154 +2003,BruCap,8,M,4703,1225 +2003,BruCap,8,F,4329,1103 +2003,BruCap,9,M,4672,1216 +2003,BruCap,9,F,4390,1133 +2003,BruCap,10,M,4621,1221 +2003,BruCap,10,F,4478,1078 +2003,BruCap,11,M,4597,1143 +2003,BruCap,11,F,4459,1067 +2003,BruCap,12,M,4612,1161 +2003,BruCap,12,F,4384,1104 +2003,BruCap,13,M,4476,1139 +2003,BruCap,13,F,4327,1066 +2003,BruCap,14,M,4488,1183 +2003,BruCap,14,F,4283,1055 +2003,BruCap,15,M,4308,1145 +2003,BruCap,15,F,4177,1117 +2003,BruCap,16,M,4253,1161 +2003,BruCap,16,F,4088,1116 +2003,BruCap,17,M,4205,1117 +2003,BruCap,17,F,3853,1149 +2003,BruCap,18,M,4220,1161 +2003,BruCap,18,F,4150,1347 +2003,BruCap,19,M,4168,1258 +2003,BruCap,19,F,4158,1448 +2003,BruCap,20,M,4276,1559 +2003,BruCap,20,F,4243,1798 +2003,BruCap,21,M,4566,1664 +2003,BruCap,21,F,4573,2000 +2003,BruCap,22,M,4608,1801 +2003,BruCap,22,F,4846,2325 +2003,BruCap,23,M,4686,2062 +2003,BruCap,23,F,4921,2449 +2003,BruCap,24,M,4877,2270 +2003,BruCap,24,F,5305,2755 +2003,BruCap,25,M,5136,2628 +2003,BruCap,25,F,5461,2899 +2003,BruCap,26,M,5091,2940 +2003,BruCap,26,F,5561,3073 +2003,BruCap,27,M,5288,2929 +2003,BruCap,27,F,5275,3101 +2003,BruCap,28,M,5289,3337 +2003,BruCap,28,F,5332,3255 +2003,BruCap,29,M,5483,3421 +2003,BruCap,29,F,5416,3305 +2003,BruCap,30,M,5555,3498 +2003,BruCap,30,F,5353,3402 +2003,BruCap,31,M,5455,3567 +2003,BruCap,31,F,5270,3365 +2003,BruCap,32,M,5369,3780 +2003,BruCap,32,F,5199,3231 +2003,BruCap,33,M,5303,3490 +2003,BruCap,33,F,4924,3230 +2003,BruCap,34,M,5067,3524 +2003,BruCap,34,F,4773,3058 +2003,BruCap,35,M,4944,3335 +2003,BruCap,35,F,4682,2902 +2003,BruCap,36,M,4932,3331 +2003,BruCap,36,F,4818,2828 +2003,BruCap,37,M,5155,3231 +2003,BruCap,37,F,4822,2829 +2003,BruCap,38,M,5101,3053 +2003,BruCap,38,F,4848,2750 +2003,BruCap,39,M,4981,2756 +2003,BruCap,39,F,4781,2476 +2003,BruCap,40,M,4738,2738 +2003,BruCap,40,F,4713,2381 +2003,BruCap,41,M,4651,2504 +2003,BruCap,41,F,4720,2224 +2003,BruCap,42,M,4764,2404 +2003,BruCap,42,F,4892,2228 +2003,BruCap,43,M,4719,2199 +2003,BruCap,43,F,4829,2050 +2003,BruCap,44,M,4565,2110 +2003,BruCap,44,F,4792,1840 +2003,BruCap,45,M,4482,1919 +2003,BruCap,45,F,4755,1865 +2003,BruCap,46,M,4332,1945 +2003,BruCap,46,F,4774,1828 +2003,BruCap,47,M,4373,1898 +2003,BruCap,47,F,4734,1732 +2003,BruCap,48,M,4303,1670 +2003,BruCap,48,F,4634,1667 +2003,BruCap,49,M,4372,1629 +2003,BruCap,49,F,4660,1557 +2003,BruCap,50,M,4381,1659 +2003,BruCap,50,F,4667,1622 +2003,BruCap,51,M,4123,1453 +2003,BruCap,51,F,4425,1390 +2003,BruCap,52,M,4088,1588 +2003,BruCap,52,F,4609,1516 +2003,BruCap,53,M,4048,1454 +2003,BruCap,53,F,4465,1370 +2003,BruCap,54,M,4067,1512 +2003,BruCap,54,F,4510,1366 +2003,BruCap,55,M,4047,1425 +2003,BruCap,55,F,4616,1316 +2003,BruCap,56,M,4053,1322 +2003,BruCap,56,F,4482,1300 +2003,BruCap,57,M,3465,1157 +2003,BruCap,57,F,3946,1108 +2003,BruCap,58,M,3561,1196 +2003,BruCap,58,F,4117,1130 +2003,BruCap,59,M,3439,1094 +2003,BruCap,59,F,3906,1053 +2003,BruCap,60,M,2996,1047 +2003,BruCap,60,F,3361,984 +2003,BruCap,61,M,2572,884 +2003,BruCap,61,F,2960,864 +2003,BruCap,62,M,2884,1056 +2003,BruCap,62,F,3340,1106 +2003,BruCap,63,M,2927,974 +2003,BruCap,63,F,3561,949 +2003,BruCap,64,M,2953,965 +2003,BruCap,64,F,3494,890 +2003,BruCap,65,M,2770,834 +2003,BruCap,65,F,3379,802 +2003,BruCap,66,M,2745,790 +2003,BruCap,66,F,3363,862 +2003,BruCap,67,M,2688,716 +2003,BruCap,67,F,3464,824 +2003,BruCap,68,M,2770,672 +2003,BruCap,68,F,3428,743 +2003,BruCap,69,M,2631,638 +2003,BruCap,69,F,3633,663 +2003,BruCap,70,M,2777,660 +2003,BruCap,70,F,3811,663 +2003,BruCap,71,M,2775,529 +2003,BruCap,71,F,3831,602 +2003,BruCap,72,M,2621,612 +2003,BruCap,72,F,4152,687 +2003,BruCap,73,M,2523,494 +2003,BruCap,73,F,3959,498 +2003,BruCap,74,M,2531,444 +2003,BruCap,74,F,3888,526 +2003,BruCap,75,M,2441,372 +2003,BruCap,75,F,3916,435 +2003,BruCap,76,M,2353,354 +2003,BruCap,76,F,3992,407 +2003,BruCap,77,M,2348,292 +2003,BruCap,77,F,4003,381 +2003,BruCap,78,M,2302,249 +2003,BruCap,78,F,4058,355 +2003,BruCap,79,M,2086,238 +2003,BruCap,79,F,4064,328 +2003,BruCap,80,M,1924,234 +2003,BruCap,80,F,3904,275 +2003,BruCap,81,M,1984,203 +2003,BruCap,81,F,3837,246 +2003,BruCap,82,M,1728,148 +2003,BruCap,82,F,3732,287 +2003,BruCap,83,M,1209,96 +2003,BruCap,83,F,2534,161 +2003,BruCap,84,M,702,83 +2003,BruCap,84,F,1754,131 +2003,BruCap,85,M,639,64 +2003,BruCap,85,F,1618,126 +2003,BruCap,86,M,548,44 +2003,BruCap,86,F,1619,97 +2003,BruCap,87,M,603,48 +2003,BruCap,87,F,1793,101 +2003,BruCap,88,M,654,44 +2003,BruCap,88,F,1884,107 +2003,BruCap,89,M,505,27 +2003,BruCap,89,F,1602,101 +2003,BruCap,90,M,374,35 +2003,BruCap,90,F,1343,92 +2003,BruCap,91,M,296,20 +2003,BruCap,91,F,1117,66 +2003,BruCap,92,M,226,20 +2003,BruCap,92,F,924,62 +2003,BruCap,93,M,162,9 +2003,BruCap,93,F,676,49 +2003,BruCap,94,M,114,9 +2003,BruCap,94,F,589,34 +2003,BruCap,95,M,67,7 +2003,BruCap,95,F,391,17 +2003,BruCap,96,M,54,3 +2003,BruCap,96,F,321,19 +2003,BruCap,97,M,46,1 +2003,BruCap,97,F,230,15 +2003,BruCap,98,M,27,5 +2003,BruCap,98,F,146,8 +2003,BruCap,99,M,15,2 +2003,BruCap,99,F,101,4 +2003,BruCap,100,M,8,1 +2003,BruCap,100,F,62,10 +2003,BruCap,101,M,6,2 +2003,BruCap,101,F,34,4 +2003,BruCap,102,M,1,2 +2003,BruCap,102,F,13,4 +2003,BruCap,103,M,1,0 +2003,BruCap,103,F,16,2 +2003,BruCap,104,M,0,1 +2003,BruCap,104,F,9,4 +2003,BruCap,105,M,0,0 +2003,BruCap,105,F,3,1 +2003,BruCap,106,M,0,0 +2003,BruCap,106,F,5,0 +2003,BruCap,107,M,0,0 +2003,BruCap,107,F,5,2 +2003,BruCap,108,M,0,0 +2003,BruCap,108,F,1,0 +2003,BruCap,109,M,0,0 +2003,BruCap,109,F,2,0 +2003,BruCap,110,M,0,0 +2003,BruCap,110,F,1,0 +2003,BruCap,111,M,0,0 +2003,BruCap,111,F,1,0 +2003,BruCap,112,M,1,0 +2003,BruCap,112,F,0,0 +2003,BruCap,113,M,0,0 +2003,BruCap,113,F,0,0 +2003,BruCap,114,M,0,0 +2003,BruCap,114,F,0,0 +2003,BruCap,115,M,0,0 +2003,BruCap,115,F,0,0 +2003,BruCap,116,M,0,0 +2003,BruCap,116,F,0,0 +2003,BruCap,117,M,0,0 +2003,BruCap,117,F,0,0 +2003,BruCap,118,M,0,0 +2003,BruCap,118,F,0,0 +2003,BruCap,119,M,0,0 +2003,BruCap,119,F,0,0 +2003,BruCap,120,M,0,0 +2003,BruCap,120,F,0,0 +2003,Fla,0,M,29280,1401 +2003,Fla,0,F,27721,1337 +2003,Fla,1,M,29635,1434 +2003,Fla,1,F,28413,1310 +2003,Fla,2,M,30501,1424 +2003,Fla,2,F,29276,1371 +2003,Fla,3,M,30569,1346 +2003,Fla,3,F,29627,1320 +2003,Fla,4,M,31487,1361 +2003,Fla,4,F,29968,1292 +2003,Fla,5,M,32184,1375 +2003,Fla,5,F,30951,1352 +2003,Fla,6,M,32340,1269 +2003,Fla,6,F,31104,1310 +2003,Fla,7,M,32482,1388 +2003,Fla,7,F,31128,1239 +2003,Fla,8,M,32938,1434 +2003,Fla,8,F,31328,1278 +2003,Fla,9,M,34241,1344 +2003,Fla,9,F,33284,1297 +2003,Fla,10,M,35573,1359 +2003,Fla,10,F,34120,1301 +2003,Fla,11,M,36105,1428 +2003,Fla,11,F,34246,1347 +2003,Fla,12,M,35734,1331 +2003,Fla,12,F,34099,1271 +2003,Fla,13,M,34571,1258 +2003,Fla,13,F,32919,1236 +2003,Fla,14,M,34171,1287 +2003,Fla,14,F,32654,1280 +2003,Fla,15,M,33854,1255 +2003,Fla,15,F,32030,1284 +2003,Fla,16,M,33937,1264 +2003,Fla,16,F,31955,1261 +2003,Fla,17,M,32907,1292 +2003,Fla,17,F,31465,1354 +2003,Fla,18,M,33694,1368 +2003,Fla,18,F,32124,1389 +2003,Fla,19,M,34550,1285 +2003,Fla,19,F,33251,1537 +2003,Fla,20,M,35449,1595 +2003,Fla,20,F,33650,1754 +2003,Fla,21,M,36568,1695 +2003,Fla,21,F,34471,2041 +2003,Fla,22,M,36039,1854 +2003,Fla,22,F,34772,2248 +2003,Fla,23,M,36379,2071 +2003,Fla,23,F,34517,2352 +2003,Fla,24,M,35376,2274 +2003,Fla,24,F,34195,2617 +2003,Fla,25,M,34463,2367 +2003,Fla,25,F,33570,2685 +2003,Fla,26,M,33799,2448 +2003,Fla,26,F,32450,2723 +2003,Fla,27,M,32892,2584 +2003,Fla,27,F,31611,2745 +2003,Fla,28,M,34128,2827 +2003,Fla,28,F,33187,2810 +2003,Fla,29,M,35507,2842 +2003,Fla,29,F,34337,2838 +2003,Fla,30,M,37079,3063 +2003,Fla,30,F,36305,3021 +2003,Fla,31,M,38822,3043 +2003,Fla,31,F,38300,3026 +2003,Fla,32,M,40117,3194 +2003,Fla,32,F,39037,3155 +2003,Fla,33,M,40180,3221 +2003,Fla,33,F,39221,3033 +2003,Fla,34,M,40771,3185 +2003,Fla,34,F,39639,2970 +2003,Fla,35,M,42262,2955 +2003,Fla,35,F,40445,2913 +2003,Fla,36,M,43536,3321 +2003,Fla,36,F,42376,3044 +2003,Fla,37,M,45133,3157 +2003,Fla,37,F,43715,2866 +2003,Fla,38,M,46993,3254 +2003,Fla,38,F,46015,2760 +2003,Fla,39,M,46788,3030 +2003,Fla,39,F,45574,2547 +2003,Fla,40,M,46228,2981 +2003,Fla,40,F,44945,2492 +2003,Fla,41,M,45852,2819 +2003,Fla,41,F,45275,2283 +2003,Fla,42,M,45010,2786 +2003,Fla,42,F,44121,2305 +2003,Fla,43,M,45724,2609 +2003,Fla,43,F,44875,2169 +2003,Fla,44,M,44832,2679 +2003,Fla,44,F,43681,1974 +2003,Fla,45,M,44215,2470 +2003,Fla,45,F,42947,1864 +2003,Fla,46,M,42909,2455 +2003,Fla,46,F,42429,1844 +2003,Fla,47,M,42241,2394 +2003,Fla,47,F,41950,1762 +2003,Fla,48,M,41458,2314 +2003,Fla,48,F,40758,1687 +2003,Fla,49,M,40506,2106 +2003,Fla,49,F,39444,1601 +2003,Fla,50,M,40373,2137 +2003,Fla,50,F,39151,1570 +2003,Fla,51,M,38483,2102 +2003,Fla,51,F,37662,1488 +2003,Fla,52,M,37931,2085 +2003,Fla,52,F,37521,1566 +2003,Fla,53,M,38025,2196 +2003,Fla,53,F,37232,1571 +2003,Fla,54,M,37919,2095 +2003,Fla,54,F,37629,1515 +2003,Fla,55,M,37513,2076 +2003,Fla,55,F,37155,1531 +2003,Fla,56,M,38371,2097 +2003,Fla,56,F,37732,1374 +2003,Fla,57,M,33873,1728 +2003,Fla,57,F,33962,1283 +2003,Fla,58,M,33550,1687 +2003,Fla,58,F,33706,1358 +2003,Fla,59,M,31988,1667 +2003,Fla,59,F,32322,1228 +2003,Fla,60,M,27781,1496 +2003,Fla,60,F,28134,1176 +2003,Fla,61,M,24846,1456 +2003,Fla,61,F,25841,1091 +2003,Fla,62,M,27313,1511 +2003,Fla,62,F,28636,1262 +2003,Fla,63,M,29717,1410 +2003,Fla,63,F,31885,1003 +2003,Fla,64,M,30574,1380 +2003,Fla,64,F,32536,1024 +2003,Fla,65,M,29396,1200 +2003,Fla,65,F,31340,953 +2003,Fla,66,M,28078,1159 +2003,Fla,66,F,30682,915 +2003,Fla,67,M,27679,1119 +2003,Fla,67,F,30535,814 +2003,Fla,68,M,27497,1030 +2003,Fla,68,F,31051,863 +2003,Fla,69,M,27087,1035 +2003,Fla,69,F,30776,806 +2003,Fla,70,M,27113,947 +2003,Fla,70,F,31859,732 +2003,Fla,71,M,26516,886 +2003,Fla,71,F,31658,623 +2003,Fla,72,M,25558,828 +2003,Fla,72,F,31151,731 +2003,Fla,73,M,22869,727 +2003,Fla,73,F,28818,600 +2003,Fla,74,M,21566,684 +2003,Fla,74,F,27825,618 +2003,Fla,75,M,20124,588 +2003,Fla,75,F,26464,554 +2003,Fla,76,M,18947,536 +2003,Fla,76,F,26381,536 +2003,Fla,77,M,18322,524 +2003,Fla,77,F,25486,502 +2003,Fla,78,M,16802,475 +2003,Fla,78,F,24329,461 +2003,Fla,79,M,15535,440 +2003,Fla,79,F,23613,449 +2003,Fla,80,M,13745,381 +2003,Fla,80,F,21606,379 +2003,Fla,81,M,12566,318 +2003,Fla,81,F,20659,357 +2003,Fla,82,M,11134,284 +2003,Fla,82,F,19090,314 +2003,Fla,83,M,7602,175 +2003,Fla,83,F,13692,197 +2003,Fla,84,M,4507,133 +2003,Fla,84,F,8927,163 +2003,Fla,85,M,3813,110 +2003,Fla,85,F,8132,135 +2003,Fla,86,M,3879,96 +2003,Fla,86,F,8372,132 +2003,Fla,87,M,3942,87 +2003,Fla,87,F,8939,130 +2003,Fla,88,M,3616,71 +2003,Fla,88,F,9164,131 +2003,Fla,89,M,2930,56 +2003,Fla,89,F,7968,102 +2003,Fla,90,M,2283,32 +2003,Fla,90,F,6574,86 +2003,Fla,91,M,1679,34 +2003,Fla,91,F,5153,67 +2003,Fla,92,M,1281,22 +2003,Fla,92,F,4096,53 +2003,Fla,93,M,849,19 +2003,Fla,93,F,3088,41 +2003,Fla,94,M,590,16 +2003,Fla,94,F,2535,28 +2003,Fla,95,M,419,8 +2003,Fla,95,F,1802,21 +2003,Fla,96,M,254,6 +2003,Fla,96,F,1234,13 +2003,Fla,97,M,201,6 +2003,Fla,97,F,863,15 +2003,Fla,98,M,117,4 +2003,Fla,98,F,586,8 +2003,Fla,99,M,64,1 +2003,Fla,99,F,343,8 +2003,Fla,100,M,35,1 +2003,Fla,100,F,246,3 +2003,Fla,101,M,18,1 +2003,Fla,101,F,142,2 +2003,Fla,102,M,10,1 +2003,Fla,102,F,70,2 +2003,Fla,103,M,5,0 +2003,Fla,103,F,44,2 +2003,Fla,104,M,3,0 +2003,Fla,104,F,19,0 +2003,Fla,105,M,0,1 +2003,Fla,105,F,9,2 +2003,Fla,106,M,1,0 +2003,Fla,106,F,5,0 +2003,Fla,107,M,0,0 +2003,Fla,107,F,7,0 +2003,Fla,108,M,0,0 +2003,Fla,108,F,0,0 +2003,Fla,109,M,0,0 +2003,Fla,109,F,0,0 +2003,Fla,110,M,0,0 +2003,Fla,110,F,0,0 +2003,Fla,111,M,0,0 +2003,Fla,111,F,0,0 +2003,Fla,112,M,0,0 +2003,Fla,112,F,0,0 +2003,Fla,113,M,0,0 +2003,Fla,113,F,0,0 +2003,Fla,114,M,0,0 +2003,Fla,114,F,0,0 +2003,Fla,115,M,0,0 +2003,Fla,115,F,0,0 +2003,Fla,116,M,0,0 +2003,Fla,116,F,0,0 +2003,Fla,117,M,0,0 +2003,Fla,117,F,0,0 +2003,Fla,118,M,0,0 +2003,Fla,118,F,0,0 +2003,Fla,119,M,0,0 +2003,Fla,119,F,0,0 +2003,Fla,120,M,0,0 +2003,Fla,120,F,0,0 +2003,Wal,0,M,18564,764 +2003,Wal,0,F,17607,707 +2003,Wal,1,M,19303,742 +2003,Wal,1,F,18620,698 +2003,Wal,2,M,19817,808 +2003,Wal,2,F,18929,764 +2003,Wal,3,M,19368,801 +2003,Wal,3,F,18467,786 +2003,Wal,4,M,19392,801 +2003,Wal,4,F,18582,796 +2003,Wal,5,M,19488,866 +2003,Wal,5,F,18732,829 +2003,Wal,6,M,19760,927 +2003,Wal,6,F,18899,845 +2003,Wal,7,M,19267,925 +2003,Wal,7,F,18573,860 +2003,Wal,8,M,19510,948 +2003,Wal,8,F,18537,940 +2003,Wal,9,M,20301,1015 +2003,Wal,9,F,19182,996 +2003,Wal,10,M,21304,1106 +2003,Wal,10,F,20372,1030 +2003,Wal,11,M,21845,1118 +2003,Wal,11,F,21015,1100 +2003,Wal,12,M,21569,1146 +2003,Wal,12,F,20696,1075 +2003,Wal,13,M,21641,1128 +2003,Wal,13,F,20620,1129 +2003,Wal,14,M,21476,1116 +2003,Wal,14,F,20319,1148 +2003,Wal,15,M,20690,1210 +2003,Wal,15,F,19753,1097 +2003,Wal,16,M,20670,1269 +2003,Wal,16,F,19561,1212 +2003,Wal,17,M,19811,1236 +2003,Wal,17,F,18957,1254 +2003,Wal,18,M,19590,1267 +2003,Wal,18,F,18808,1368 +2003,Wal,19,M,19463,1312 +2003,Wal,19,F,18108,1378 +2003,Wal,20,M,19574,1407 +2003,Wal,20,F,18799,1605 +2003,Wal,21,M,19589,1538 +2003,Wal,21,F,19106,1759 +2003,Wal,22,M,19554,1682 +2003,Wal,22,F,18941,1927 +2003,Wal,23,M,19084,1793 +2003,Wal,23,F,17916,2012 +2003,Wal,24,M,18390,1951 +2003,Wal,24,F,17661,1982 +2003,Wal,25,M,18389,1884 +2003,Wal,25,F,17559,2118 +2003,Wal,26,M,18445,2063 +2003,Wal,26,F,17850,1993 +2003,Wal,27,M,18366,2136 +2003,Wal,27,F,18035,2109 +2003,Wal,28,M,19050,2415 +2003,Wal,28,F,18509,2371 +2003,Wal,29,M,19839,2697 +2003,Wal,29,F,19449,2490 +2003,Wal,30,M,20601,2797 +2003,Wal,30,F,20270,2616 +2003,Wal,31,M,21025,2844 +2003,Wal,31,F,20843,2658 +2003,Wal,32,M,20633,2858 +2003,Wal,32,F,20350,2732 +2003,Wal,33,M,20584,2956 +2003,Wal,33,F,20485,2850 +2003,Wal,34,M,20270,2930 +2003,Wal,34,F,20420,2899 +2003,Wal,35,M,20722,3058 +2003,Wal,35,F,20767,2813 +2003,Wal,36,M,21159,3456 +2003,Wal,36,F,21310,3092 +2003,Wal,37,M,22001,3479 +2003,Wal,37,F,22135,2952 +2003,Wal,38,M,22844,3363 +2003,Wal,38,F,22971,3029 +2003,Wal,39,M,22449,3346 +2003,Wal,39,F,22844,2931 +2003,Wal,40,M,21903,3302 +2003,Wal,40,F,22425,2712 +2003,Wal,41,M,22491,3224 +2003,Wal,41,F,23061,2826 +2003,Wal,42,M,22361,3551 +2003,Wal,42,F,22627,2681 +2003,Wal,43,M,22406,3326 +2003,Wal,43,F,23367,2631 +2003,Wal,44,M,22012,3381 +2003,Wal,44,F,22958,2588 +2003,Wal,45,M,21769,3268 +2003,Wal,45,F,22415,2476 +2003,Wal,46,M,21278,3393 +2003,Wal,46,F,22243,2536 +2003,Wal,47,M,20993,3199 +2003,Wal,47,F,22152,2435 +2003,Wal,48,M,20950,3164 +2003,Wal,48,F,21987,2364 +2003,Wal,49,M,20776,3066 +2003,Wal,49,F,21652,2185 +2003,Wal,50,M,20589,2936 +2003,Wal,50,F,21348,2204 +2003,Wal,51,M,19828,2837 +2003,Wal,51,F,21007,2172 +2003,Wal,52,M,20625,2886 +2003,Wal,52,F,21122,2204 +2003,Wal,53,M,20479,2742 +2003,Wal,53,F,21057,2034 +2003,Wal,54,M,20835,2782 +2003,Wal,54,F,21727,2168 +2003,Wal,55,M,20762,2763 +2003,Wal,55,F,21541,2012 +2003,Wal,56,M,20200,2563 +2003,Wal,56,F,21340,1887 +2003,Wal,57,M,15035,2046 +2003,Wal,57,F,16368,1597 +2003,Wal,58,M,14905,2043 +2003,Wal,58,F,15999,1617 +2003,Wal,59,M,13859,1808 +2003,Wal,59,F,15120,1466 +2003,Wal,60,M,12011,1700 +2003,Wal,60,F,13206,1451 +2003,Wal,61,M,11137,1655 +2003,Wal,61,F,12447,1370 +2003,Wal,62,M,12420,1894 +2003,Wal,62,F,13874,1621 +2003,Wal,63,M,13385,1756 +2003,Wal,63,F,15293,1624 +2003,Wal,64,M,13378,1614 +2003,Wal,64,F,15489,1646 +2003,Wal,65,M,12758,1659 +2003,Wal,65,F,14666,1467 +2003,Wal,66,M,12211,1566 +2003,Wal,66,F,14590,1487 +2003,Wal,67,M,11895,1553 +2003,Wal,67,F,14449,1551 +2003,Wal,68,M,12270,1479 +2003,Wal,68,F,14953,1551 +2003,Wal,69,M,12215,1410 +2003,Wal,69,F,14948,1539 +2003,Wal,70,M,12573,1441 +2003,Wal,70,F,16171,1454 +2003,Wal,71,M,12592,1321 +2003,Wal,71,F,16467,1470 +2003,Wal,72,M,12074,1420 +2003,Wal,72,F,16474,1503 +2003,Wal,73,M,11111,1317 +2003,Wal,73,F,15449,1424 +2003,Wal,74,M,10587,1186 +2003,Wal,74,F,15387,1339 +2003,Wal,75,M,10010,1222 +2003,Wal,75,F,14894,1373 +2003,Wal,76,M,9508,1151 +2003,Wal,76,F,14650,1359 +2003,Wal,77,M,9050,1003 +2003,Wal,77,F,14829,1282 +2003,Wal,78,M,8400,930 +2003,Wal,78,F,14144,1178 +2003,Wal,79,M,7574,861 +2003,Wal,79,F,13428,1105 +2003,Wal,80,M,6919,711 +2003,Wal,80,F,12890,1018 +2003,Wal,81,M,6353,573 +2003,Wal,81,F,12579,862 +2003,Wal,82,M,5620,477 +2003,Wal,82,F,11725,826 +2003,Wal,83,M,3617,277 +2003,Wal,83,F,7981,517 +2003,Wal,84,M,2220,167 +2003,Wal,84,F,5220,299 +2003,Wal,85,M,1839,146 +2003,Wal,85,F,4640,296 +2003,Wal,86,M,1829,132 +2003,Wal,86,F,4525,292 +2003,Wal,87,M,1707,119 +2003,Wal,87,F,4862,336 +2003,Wal,88,M,1700,117 +2003,Wal,88,F,5099,320 +2003,Wal,89,M,1341,103 +2003,Wal,89,F,4240,262 +2003,Wal,90,M,979,81 +2003,Wal,90,F,3580,206 +2003,Wal,91,M,688,46 +2003,Wal,91,F,2735,168 +2003,Wal,92,M,534,30 +2003,Wal,92,F,2241,147 +2003,Wal,93,M,371,21 +2003,Wal,93,F,1725,99 +2003,Wal,94,M,245,21 +2003,Wal,94,F,1314,85 +2003,Wal,95,M,148,6 +2003,Wal,95,F,1021,46 +2003,Wal,96,M,117,8 +2003,Wal,96,F,664,42 +2003,Wal,97,M,75,6 +2003,Wal,97,F,477,22 +2003,Wal,98,M,44,1 +2003,Wal,98,F,299,25 +2003,Wal,99,M,21,2 +2003,Wal,99,F,212,11 +2003,Wal,100,M,14,1 +2003,Wal,100,F,111,12 +2003,Wal,101,M,10,0 +2003,Wal,101,F,71,6 +2003,Wal,102,M,4,1 +2003,Wal,102,F,40,4 +2003,Wal,103,M,3,0 +2003,Wal,103,F,20,1 +2003,Wal,104,M,1,0 +2003,Wal,104,F,9,0 +2003,Wal,105,M,1,0 +2003,Wal,105,F,6,2 +2003,Wal,106,M,0,0 +2003,Wal,106,F,1,0 +2003,Wal,107,M,0,0 +2003,Wal,107,F,4,0 +2003,Wal,108,M,0,0 +2003,Wal,108,F,0,0 +2003,Wal,109,M,1,0 +2003,Wal,109,F,0,0 +2003,Wal,110,M,0,0 +2003,Wal,110,F,0,0 +2003,Wal,111,M,0,0 +2003,Wal,111,F,0,0 +2003,Wal,112,M,0,0 +2003,Wal,112,F,0,0 +2003,Wal,113,M,0,0 +2003,Wal,113,F,0,0 +2003,Wal,114,M,0,0 +2003,Wal,114,F,0,0 +2003,Wal,115,M,0,0 +2003,Wal,115,F,0,0 +2003,Wal,116,M,0,0 +2003,Wal,116,F,0,0 +2003,Wal,117,M,0,0 +2003,Wal,117,F,0,0 +2003,Wal,118,M,0,0 +2003,Wal,118,F,0,0 +2003,Wal,119,M,0,0 +2003,Wal,119,F,0,0 +2003,Wal,120,M,0,0 +2003,Wal,120,F,0,0 +2004,BruCap,0,M,5871,1540 +2004,BruCap,0,F,5737,1461 +2004,BruCap,1,M,5630,1312 +2004,BruCap,1,F,5423,1374 +2004,BruCap,2,M,5619,1341 +2004,BruCap,2,F,5522,1334 +2004,BruCap,3,M,5396,1250 +2004,BruCap,3,F,5032,1204 +2004,BruCap,4,M,5185,1201 +2004,BruCap,4,F,4965,1154 +2004,BruCap,5,M,5027,1173 +2004,BruCap,5,F,4772,1207 +2004,BruCap,6,M,4987,1225 +2004,BruCap,6,F,4676,1076 +2004,BruCap,7,M,4737,1173 +2004,BruCap,7,F,4679,1130 +2004,BruCap,8,M,4607,1224 +2004,BruCap,8,F,4458,1112 +2004,BruCap,9,M,4712,1170 +2004,BruCap,9,F,4320,1082 +2004,BruCap,10,M,4656,1212 +2004,BruCap,10,F,4402,1114 +2004,BruCap,11,M,4610,1196 +2004,BruCap,11,F,4458,1068 +2004,BruCap,12,M,4611,1098 +2004,BruCap,12,F,4498,1023 +2004,BruCap,13,M,4626,1124 +2004,BruCap,13,F,4363,1103 +2004,BruCap,14,M,4500,1146 +2004,BruCap,14,F,4344,1055 +2004,BruCap,15,M,4514,1174 +2004,BruCap,15,F,4283,1078 +2004,BruCap,16,M,4337,1134 +2004,BruCap,16,F,4228,1106 +2004,BruCap,17,M,4319,1148 +2004,BruCap,17,F,4141,1144 +2004,BruCap,18,M,4279,1123 +2004,BruCap,18,F,3979,1242 +2004,BruCap,19,M,4314,1207 +2004,BruCap,19,F,4370,1495 +2004,BruCap,20,M,4260,1355 +2004,BruCap,20,F,4324,1695 +2004,BruCap,21,M,4379,1662 +2004,BruCap,21,F,4423,2032 +2004,BruCap,22,M,4673,1820 +2004,BruCap,22,F,4760,2313 +2004,BruCap,23,M,4789,2053 +2004,BruCap,23,F,5086,2647 +2004,BruCap,24,M,4948,2303 +2004,BruCap,24,F,5217,2789 +2004,BruCap,25,M,5144,2593 +2004,BruCap,25,F,5571,3051 +2004,BruCap,26,M,5334,2880 +2004,BruCap,26,F,5614,3117 +2004,BruCap,27,M,5258,3093 +2004,BruCap,27,F,5636,3269 +2004,BruCap,28,M,5328,3171 +2004,BruCap,28,F,5321,3255 +2004,BruCap,29,M,5335,3466 +2004,BruCap,29,F,5279,3377 +2004,BruCap,30,M,5477,3535 +2004,BruCap,30,F,5364,3373 +2004,BruCap,31,M,5511,3550 +2004,BruCap,31,F,5272,3417 +2004,BruCap,32,M,5441,3541 +2004,BruCap,32,F,5191,3358 +2004,BruCap,33,M,5397,3721 +2004,BruCap,33,F,5152,3237 +2004,BruCap,34,M,5232,3505 +2004,BruCap,34,F,4958,3200 +2004,BruCap,35,M,5093,3452 +2004,BruCap,35,F,4743,3034 +2004,BruCap,36,M,4950,3304 +2004,BruCap,36,F,4678,2872 +2004,BruCap,37,M,4953,3194 +2004,BruCap,37,F,4801,2732 +2004,BruCap,38,M,5143,3141 +2004,BruCap,38,F,4838,2752 +2004,BruCap,39,M,5087,2960 +2004,BruCap,39,F,4866,2645 +2004,BruCap,40,M,4971,2651 +2004,BruCap,40,F,4790,2413 +2004,BruCap,41,M,4688,2629 +2004,BruCap,41,F,4717,2308 +2004,BruCap,42,M,4615,2446 +2004,BruCap,42,F,4728,2134 +2004,BruCap,43,M,4765,2319 +2004,BruCap,43,F,4906,2167 +2004,BruCap,44,M,4705,2133 +2004,BruCap,44,F,4825,2001 +2004,BruCap,45,M,4510,2069 +2004,BruCap,45,F,4809,1801 +2004,BruCap,46,M,4431,1881 +2004,BruCap,46,F,4753,1837 +2004,BruCap,47,M,4355,1913 +2004,BruCap,47,F,4787,1760 +2004,BruCap,48,M,4325,1875 +2004,BruCap,48,F,4755,1694 +2004,BruCap,49,M,4288,1654 +2004,BruCap,49,F,4647,1637 +2004,BruCap,50,M,4338,1596 +2004,BruCap,50,F,4656,1527 +2004,BruCap,51,M,4319,1626 +2004,BruCap,51,F,4660,1590 +2004,BruCap,52,M,4105,1400 +2004,BruCap,52,F,4406,1380 +2004,BruCap,53,M,4034,1560 +2004,BruCap,53,F,4582,1500 +2004,BruCap,54,M,4016,1407 +2004,BruCap,54,F,4444,1349 +2004,BruCap,55,M,3990,1469 +2004,BruCap,55,F,4462,1351 +2004,BruCap,56,M,3999,1399 +2004,BruCap,56,F,4590,1319 +2004,BruCap,57,M,4008,1288 +2004,BruCap,57,F,4444,1262 +2004,BruCap,58,M,3425,1123 +2004,BruCap,58,F,3914,1117 +2004,BruCap,59,M,3512,1131 +2004,BruCap,59,F,4066,1124 +2004,BruCap,60,M,3357,1040 +2004,BruCap,60,F,3850,1011 +2004,BruCap,61,M,2946,1007 +2004,BruCap,61,F,3337,965 +2004,BruCap,62,M,2488,839 +2004,BruCap,62,F,2934,844 +2004,BruCap,63,M,2847,999 +2004,BruCap,63,F,3312,1076 +2004,BruCap,64,M,2874,907 +2004,BruCap,64,F,3525,936 +2004,BruCap,65,M,2893,902 +2004,BruCap,65,F,3441,881 +2004,BruCap,66,M,2737,787 +2004,BruCap,66,F,3346,791 +2004,BruCap,67,M,2700,733 +2004,BruCap,67,F,3341,838 +2004,BruCap,68,M,2628,674 +2004,BruCap,68,F,3420,820 +2004,BruCap,69,M,2676,656 +2004,BruCap,69,F,3390,742 +2004,BruCap,70,M,2558,611 +2004,BruCap,70,F,3573,648 +2004,BruCap,71,M,2673,628 +2004,BruCap,71,F,3737,664 +2004,BruCap,72,M,2664,503 +2004,BruCap,72,F,3751,588 +2004,BruCap,73,M,2523,582 +2004,BruCap,73,F,4040,701 +2004,BruCap,74,M,2417,478 +2004,BruCap,74,F,3861,491 +2004,BruCap,75,M,2405,412 +2004,BruCap,75,F,3789,531 +2004,BruCap,76,M,2315,355 +2004,BruCap,76,F,3789,437 +2004,BruCap,77,M,2203,334 +2004,BruCap,77,F,3863,398 +2004,BruCap,78,M,2176,271 +2004,BruCap,78,F,3836,376 +2004,BruCap,79,M,2146,240 +2004,BruCap,79,F,3880,345 +2004,BruCap,80,M,1927,216 +2004,BruCap,80,F,3858,316 +2004,BruCap,81,M,1774,215 +2004,BruCap,81,F,3711,268 +2004,BruCap,82,M,1838,189 +2004,BruCap,82,F,3591,235 +2004,BruCap,83,M,1547,129 +2004,BruCap,83,F,3478,275 +2004,BruCap,84,M,1080,88 +2004,BruCap,84,F,2333,157 +2004,BruCap,85,M,621,71 +2004,BruCap,85,F,1612,124 +2004,BruCap,86,M,549,58 +2004,BruCap,86,F,1434,121 +2004,BruCap,87,M,450,36 +2004,BruCap,87,F,1439,87 +2004,BruCap,88,M,513,40 +2004,BruCap,88,F,1556,94 +2004,BruCap,89,M,511,37 +2004,BruCap,89,F,1614,100 +2004,BruCap,90,M,406,23 +2004,BruCap,90,F,1336,87 +2004,BruCap,91,M,294,33 +2004,BruCap,91,F,1111,75 +2004,BruCap,92,M,229,15 +2004,BruCap,92,F,901,52 +2004,BruCap,93,M,169,14 +2004,BruCap,93,F,759,57 +2004,BruCap,94,M,116,8 +2004,BruCap,94,F,513,40 +2004,BruCap,95,M,77,9 +2004,BruCap,95,F,439,29 +2004,BruCap,96,M,41,5 +2004,BruCap,96,F,270,12 +2004,BruCap,97,M,39,3 +2004,BruCap,97,F,235,11 +2004,BruCap,98,M,35,1 +2004,BruCap,98,F,154,9 +2004,BruCap,99,M,16,3 +2004,BruCap,99,F,108,6 +2004,BruCap,100,M,9,0 +2004,BruCap,100,F,68,2 +2004,BruCap,101,M,2,1 +2004,BruCap,101,F,38,8 +2004,BruCap,102,M,1,1 +2004,BruCap,102,F,19,2 +2004,BruCap,103,M,0,2 +2004,BruCap,103,F,7,3 +2004,BruCap,104,M,1,0 +2004,BruCap,104,F,10,1 +2004,BruCap,105,M,0,1 +2004,BruCap,105,F,4,3 +2004,BruCap,106,M,0,0 +2004,BruCap,106,F,1,0 +2004,BruCap,107,M,0,0 +2004,BruCap,107,F,4,0 +2004,BruCap,108,M,0,0 +2004,BruCap,108,F,3,1 +2004,BruCap,109,M,0,0 +2004,BruCap,109,F,1,0 +2004,BruCap,110,M,0,0 +2004,BruCap,110,F,2,0 +2004,BruCap,111,M,0,0 +2004,BruCap,111,F,0,0 +2004,BruCap,112,M,0,0 +2004,BruCap,112,F,0,0 +2004,BruCap,113,M,0,0 +2004,BruCap,113,F,0,0 +2004,BruCap,114,M,0,0 +2004,BruCap,114,F,0,0 +2004,BruCap,115,M,0,0 +2004,BruCap,115,F,0,0 +2004,BruCap,116,M,0,0 +2004,BruCap,116,F,0,0 +2004,BruCap,117,M,0,0 +2004,BruCap,117,F,0,0 +2004,BruCap,118,M,0,0 +2004,BruCap,118,F,0,0 +2004,BruCap,119,M,0,0 +2004,BruCap,119,F,0,0 +2004,BruCap,120,M,0,0 +2004,BruCap,120,F,0,0 +2004,Fla,0,M,29223,1519 +2004,Fla,0,F,27872,1407 +2004,Fla,1,M,29518,1479 +2004,Fla,1,F,27949,1385 +2004,Fla,2,M,29834,1477 +2004,Fla,2,F,28600,1311 +2004,Fla,3,M,30706,1459 +2004,Fla,3,F,29501,1441 +2004,Fla,4,M,30739,1402 +2004,Fla,4,F,29751,1341 +2004,Fla,5,M,31664,1391 +2004,Fla,5,F,30112,1368 +2004,Fla,6,M,32355,1412 +2004,Fla,6,F,31049,1396 +2004,Fla,7,M,32461,1298 +2004,Fla,7,F,31238,1357 +2004,Fla,8,M,32621,1420 +2004,Fla,8,F,31251,1287 +2004,Fla,9,M,33057,1490 +2004,Fla,9,F,31477,1289 +2004,Fla,10,M,34406,1343 +2004,Fla,10,F,33395,1342 +2004,Fla,11,M,35732,1363 +2004,Fla,11,F,34248,1309 +2004,Fla,12,M,36280,1413 +2004,Fla,12,F,34408,1342 +2004,Fla,13,M,35860,1363 +2004,Fla,13,F,34221,1309 +2004,Fla,14,M,34663,1300 +2004,Fla,14,F,33012,1286 +2004,Fla,15,M,34238,1342 +2004,Fla,15,F,32755,1315 +2004,Fla,16,M,33957,1307 +2004,Fla,16,F,32101,1350 +2004,Fla,17,M,34042,1315 +2004,Fla,17,F,32085,1370 +2004,Fla,18,M,33023,1341 +2004,Fla,18,F,31603,1550 +2004,Fla,19,M,33767,1374 +2004,Fla,19,F,32217,1583 +2004,Fla,20,M,34611,1438 +2004,Fla,20,F,33299,1830 +2004,Fla,21,M,35493,1713 +2004,Fla,21,F,33668,2024 +2004,Fla,22,M,36595,1865 +2004,Fla,22,F,34514,2302 +2004,Fla,23,M,36014,2100 +2004,Fla,23,F,34805,2571 +2004,Fla,24,M,36295,2248 +2004,Fla,24,F,34403,2558 +2004,Fla,25,M,35234,2461 +2004,Fla,25,F,34147,2770 +2004,Fla,26,M,34340,2536 +2004,Fla,26,F,33644,2776 +2004,Fla,27,M,33791,2580 +2004,Fla,27,F,32509,2860 +2004,Fla,28,M,32877,2697 +2004,Fla,28,F,31735,2817 +2004,Fla,29,M,34168,2908 +2004,Fla,29,F,33327,2859 +2004,Fla,30,M,35598,2892 +2004,Fla,30,F,34460,2883 +2004,Fla,31,M,37166,3124 +2004,Fla,31,F,36505,3083 +2004,Fla,32,M,38901,3065 +2004,Fla,32,F,38446,3112 +2004,Fla,33,M,40216,3206 +2004,Fla,33,F,39209,3288 +2004,Fla,34,M,40374,3263 +2004,Fla,34,F,39429,3088 +2004,Fla,35,M,40844,3200 +2004,Fla,35,F,39804,3025 +2004,Fla,36,M,42394,2993 +2004,Fla,36,F,40593,2951 +2004,Fla,37,M,43643,3334 +2004,Fla,37,F,42557,3031 +2004,Fla,38,M,45237,3164 +2004,Fla,38,F,43873,2864 +2004,Fla,39,M,47076,3291 +2004,Fla,39,F,46124,2787 +2004,Fla,40,M,46844,3032 +2004,Fla,40,F,45685,2546 +2004,Fla,41,M,46236,2974 +2004,Fla,41,F,44999,2515 +2004,Fla,42,M,45894,2832 +2004,Fla,42,F,45338,2292 +2004,Fla,43,M,44993,2799 +2004,Fla,43,F,44225,2315 +2004,Fla,44,M,45767,2614 +2004,Fla,44,F,44896,2176 +2004,Fla,45,M,44870,2667 +2004,Fla,45,F,43687,1945 +2004,Fla,46,M,44155,2471 +2004,Fla,46,F,42941,1878 +2004,Fla,47,M,42822,2459 +2004,Fla,47,F,42439,1845 +2004,Fla,48,M,42190,2374 +2004,Fla,48,F,41964,1743 +2004,Fla,49,M,41368,2299 +2004,Fla,49,F,40736,1688 +2004,Fla,50,M,40376,2105 +2004,Fla,50,F,39419,1604 +2004,Fla,51,M,40260,2141 +2004,Fla,51,F,39132,1581 +2004,Fla,52,M,38345,2092 +2004,Fla,52,F,37617,1498 +2004,Fla,53,M,37793,2048 +2004,Fla,53,F,37494,1549 +2004,Fla,54,M,37864,2189 +2004,Fla,54,F,37159,1581 +2004,Fla,55,M,37764,2090 +2004,Fla,55,F,37543,1538 +2004,Fla,56,M,37283,2061 +2004,Fla,56,F,37062,1528 +2004,Fla,57,M,38165,2092 +2004,Fla,57,F,37633,1408 +2004,Fla,58,M,33620,1726 +2004,Fla,58,F,33856,1282 +2004,Fla,59,M,33309,1679 +2004,Fla,59,F,33580,1360 +2004,Fla,60,M,31679,1634 +2004,Fla,60,F,32174,1232 +2004,Fla,61,M,27522,1490 +2004,Fla,61,F,28000,1168 +2004,Fla,62,M,24602,1419 +2004,Fla,62,F,25708,1070 +2004,Fla,63,M,27035,1458 +2004,Fla,63,F,28523,1265 +2004,Fla,64,M,29425,1389 +2004,Fla,64,F,31703,1003 +2004,Fla,65,M,30167,1330 +2004,Fla,65,F,32334,1022 +2004,Fla,66,M,28954,1173 +2004,Fla,66,F,31114,959 +2004,Fla,67,M,27629,1128 +2004,Fla,67,F,30426,929 +2004,Fla,68,M,27128,1087 +2004,Fla,68,F,30237,805 +2004,Fla,69,M,26914,996 +2004,Fla,69,F,30713,860 +2004,Fla,70,M,26456,1010 +2004,Fla,70,F,30410,808 +2004,Fla,71,M,26413,899 +2004,Fla,71,F,31453,725 +2004,Fla,72,M,25704,859 +2004,Fla,72,F,31185,626 +2004,Fla,73,M,24742,807 +2004,Fla,73,F,30659,741 +2004,Fla,74,M,22012,706 +2004,Fla,74,F,28265,595 +2004,Fla,75,M,20661,646 +2004,Fla,75,F,27197,603 +2004,Fla,76,M,19215,559 +2004,Fla,76,F,25839,541 +2004,Fla,77,M,17903,504 +2004,Fla,77,F,25626,541 +2004,Fla,78,M,17301,499 +2004,Fla,78,F,24642,479 +2004,Fla,79,M,15691,435 +2004,Fla,79,F,23374,447 +2004,Fla,80,M,14385,399 +2004,Fla,80,F,22607,433 +2004,Fla,81,M,12627,341 +2004,Fla,81,F,20495,352 +2004,Fla,82,M,11446,286 +2004,Fla,82,F,19483,333 +2004,Fla,83,M,9954,255 +2004,Fla,83,F,17801,294 +2004,Fla,84,M,6713,163 +2004,Fla,84,F,12626,175 +2004,Fla,85,M,3980,125 +2004,Fla,85,F,8175,151 +2004,Fla,86,M,3277,95 +2004,Fla,86,F,7258,126 +2004,Fla,87,M,3271,82 +2004,Fla,87,F,7382,112 +2004,Fla,88,M,3320,71 +2004,Fla,88,F,7741,116 +2004,Fla,89,M,2969,61 +2004,Fla,89,F,7887,112 +2004,Fla,90,M,2268,44 +2004,Fla,90,F,6746,91 +2004,Fla,91,M,1765,26 +2004,Fla,91,F,5422,75 +2004,Fla,92,M,1262,26 +2004,Fla,92,F,4144,54 +2004,Fla,93,M,910,18 +2004,Fla,93,F,3203,40 +2004,Fla,94,M,598,11 +2004,Fla,94,F,2346,32 +2004,Fla,95,M,405,13 +2004,Fla,95,F,1857,21 +2004,Fla,96,M,271,6 +2004,Fla,96,F,1297,15 +2004,Fla,97,M,166,3 +2004,Fla,97,F,859,10 +2004,Fla,98,M,135,3 +2004,Fla,98,F,589,12 +2004,Fla,99,M,65,3 +2004,Fla,99,F,372,5 +2004,Fla,100,M,39,1 +2004,Fla,100,F,219,7 +2004,Fla,101,M,22,1 +2004,Fla,101,F,141,2 +2004,Fla,102,M,7,1 +2004,Fla,102,F,85,2 +2004,Fla,103,M,5,0 +2004,Fla,103,F,37,0 +2004,Fla,104,M,3,0 +2004,Fla,104,F,27,2 +2004,Fla,105,M,0,0 +2004,Fla,105,F,8,0 +2004,Fla,106,M,0,1 +2004,Fla,106,F,5,1 +2004,Fla,107,M,0,0 +2004,Fla,107,F,4,0 +2004,Fla,108,M,0,0 +2004,Fla,108,F,3,1 +2004,Fla,109,M,0,0 +2004,Fla,109,F,0,0 +2004,Fla,110,M,0,0 +2004,Fla,110,F,0,0 +2004,Fla,111,M,0,0 +2004,Fla,111,F,0,0 +2004,Fla,112,M,0,0 +2004,Fla,112,F,0,0 +2004,Fla,113,M,0,0 +2004,Fla,113,F,0,0 +2004,Fla,114,M,0,0 +2004,Fla,114,F,0,0 +2004,Fla,115,M,0,0 +2004,Fla,115,F,0,0 +2004,Fla,116,M,0,0 +2004,Fla,116,F,0,0 +2004,Fla,117,M,0,0 +2004,Fla,117,F,0,0 +2004,Fla,118,M,0,0 +2004,Fla,118,F,0,0 +2004,Fla,119,M,0,0 +2004,Fla,119,F,0,0 +2004,Fla,120,M,0,0 +2004,Fla,120,F,0,0 +2004,Wal,0,M,18476,735 +2004,Wal,0,F,17798,659 +2004,Wal,1,M,18779,775 +2004,Wal,1,F,17880,721 +2004,Wal,2,M,19535,745 +2004,Wal,2,F,18766,739 +2004,Wal,3,M,19965,813 +2004,Wal,3,F,19054,774 +2004,Wal,4,M,19506,791 +2004,Wal,4,F,18596,802 +2004,Wal,5,M,19540,800 +2004,Wal,5,F,18643,814 +2004,Wal,6,M,19595,886 +2004,Wal,6,F,18831,851 +2004,Wal,7,M,19848,927 +2004,Wal,7,F,18962,850 +2004,Wal,8,M,19357,946 +2004,Wal,8,F,18676,853 +2004,Wal,9,M,19609,982 +2004,Wal,9,F,18608,954 +2004,Wal,10,M,20386,1010 +2004,Wal,10,F,19283,973 +2004,Wal,11,M,21406,1103 +2004,Wal,11,F,20479,1018 +2004,Wal,12,M,21949,1080 +2004,Wal,12,F,21153,1042 +2004,Wal,13,M,21657,1146 +2004,Wal,13,F,20786,1063 +2004,Wal,14,M,21724,1123 +2004,Wal,14,F,20686,1124 +2004,Wal,15,M,21563,1136 +2004,Wal,15,F,20387,1158 +2004,Wal,16,M,20760,1231 +2004,Wal,16,F,19818,1154 +2004,Wal,17,M,20738,1286 +2004,Wal,17,F,19628,1293 +2004,Wal,18,M,19931,1207 +2004,Wal,18,F,19066,1307 +2004,Wal,19,M,19643,1219 +2004,Wal,19,F,18873,1369 +2004,Wal,20,M,19461,1363 +2004,Wal,20,F,18157,1446 +2004,Wal,21,M,19548,1519 +2004,Wal,21,F,18789,1763 +2004,Wal,22,M,19535,1629 +2004,Wal,22,F,19096,1909 +2004,Wal,23,M,19431,1793 +2004,Wal,23,F,18838,2085 +2004,Wal,24,M,18902,1936 +2004,Wal,24,F,17799,2133 +2004,Wal,25,M,18243,2035 +2004,Wal,25,F,17487,2100 +2004,Wal,26,M,18264,1993 +2004,Wal,26,F,17495,2149 +2004,Wal,27,M,18377,2147 +2004,Wal,27,F,17883,2062 +2004,Wal,28,M,18433,2206 +2004,Wal,28,F,18126,2170 +2004,Wal,29,M,19136,2458 +2004,Wal,29,F,18686,2461 +2004,Wal,30,M,19938,2732 +2004,Wal,30,F,19640,2556 +2004,Wal,31,M,20767,2858 +2004,Wal,31,F,20472,2664 +2004,Wal,32,M,21157,2873 +2004,Wal,32,F,21063,2675 +2004,Wal,33,M,20774,2859 +2004,Wal,33,F,20527,2774 +2004,Wal,34,M,20768,2998 +2004,Wal,34,F,20641,2843 +2004,Wal,35,M,20363,2984 +2004,Wal,35,F,20587,2925 +2004,Wal,36,M,20811,3076 +2004,Wal,36,F,20918,2755 +2004,Wal,37,M,21282,3423 +2004,Wal,37,F,21407,3107 +2004,Wal,38,M,22084,3457 +2004,Wal,38,F,22229,2953 +2004,Wal,39,M,22943,3303 +2004,Wal,39,F,23092,2994 +2004,Wal,40,M,22500,3296 +2004,Wal,40,F,22929,2893 +2004,Wal,41,M,22005,3204 +2004,Wal,41,F,22510,2697 +2004,Wal,42,M,22573,3167 +2004,Wal,42,F,23129,2798 +2004,Wal,43,M,22382,3493 +2004,Wal,43,F,22670,2654 +2004,Wal,44,M,22457,3228 +2004,Wal,44,F,23438,2602 +2004,Wal,45,M,22022,3304 +2004,Wal,45,F,23018,2534 +2004,Wal,46,M,21803,3204 +2004,Wal,46,F,22504,2413 +2004,Wal,47,M,21266,3313 +2004,Wal,47,F,22304,2457 +2004,Wal,48,M,20983,3150 +2004,Wal,48,F,22172,2397 +2004,Wal,49,M,20887,3100 +2004,Wal,49,F,22010,2326 +2004,Wal,50,M,20754,2983 +2004,Wal,50,F,21640,2157 +2004,Wal,51,M,20540,2909 +2004,Wal,51,F,21335,2152 +2004,Wal,52,M,19738,2806 +2004,Wal,52,F,20935,2135 +2004,Wal,53,M,20526,2815 +2004,Wal,53,F,21076,2194 +2004,Wal,54,M,20379,2716 +2004,Wal,54,F,21031,2012 +2004,Wal,55,M,20716,2750 +2004,Wal,55,F,21706,2160 +2004,Wal,56,M,20588,2714 +2004,Wal,56,F,21458,1988 +2004,Wal,57,M,20022,2534 +2004,Wal,57,F,21282,1853 +2004,Wal,58,M,14876,2009 +2004,Wal,58,F,16300,1579 +2004,Wal,59,M,14773,2012 +2004,Wal,59,F,15939,1591 +2004,Wal,60,M,13726,1772 +2004,Wal,60,F,15013,1449 +2004,Wal,61,M,11883,1682 +2004,Wal,61,F,13115,1447 +2004,Wal,62,M,11010,1622 +2004,Wal,62,F,12351,1365 +2004,Wal,63,M,12249,1852 +2004,Wal,63,F,13776,1610 +2004,Wal,64,M,13165,1719 +2004,Wal,64,F,15155,1617 +2004,Wal,65,M,13123,1575 +2004,Wal,65,F,15355,1648 +2004,Wal,66,M,12510,1603 +2004,Wal,66,F,14500,1457 +2004,Wal,67,M,11919,1523 +2004,Wal,67,F,14443,1456 +2004,Wal,68,M,11583,1508 +2004,Wal,68,F,14270,1535 +2004,Wal,69,M,11936,1438 +2004,Wal,69,F,14753,1531 +2004,Wal,70,M,11870,1363 +2004,Wal,70,F,14751,1527 +2004,Wal,71,M,12145,1386 +2004,Wal,71,F,15904,1433 +2004,Wal,72,M,12150,1270 +2004,Wal,72,F,16192,1451 +2004,Wal,73,M,11615,1352 +2004,Wal,73,F,16149,1480 +2004,Wal,74,M,10584,1266 +2004,Wal,74,F,15105,1403 +2004,Wal,75,M,10067,1121 +2004,Wal,75,F,14998,1301 +2004,Wal,76,M,9458,1147 +2004,Wal,76,F,14452,1321 +2004,Wal,77,M,8945,1061 +2004,Wal,77,F,14146,1316 +2004,Wal,78,M,8470,937 +2004,Wal,78,F,14279,1239 +2004,Wal,79,M,7767,865 +2004,Wal,79,F,13527,1133 +2004,Wal,80,M,6974,775 +2004,Wal,80,F,12815,1069 +2004,Wal,81,M,6325,651 +2004,Wal,81,F,12182,968 +2004,Wal,82,M,5680,514 +2004,Wal,82,F,11752,809 +2004,Wal,83,M,4993,416 +2004,Wal,83,F,10866,781 +2004,Wal,84,M,3193,236 +2004,Wal,84,F,7313,475 +2004,Wal,85,M,1918,139 +2004,Wal,85,F,4718,276 +2004,Wal,86,M,1525,116 +2004,Wal,86,F,4178,264 +2004,Wal,87,M,1513,115 +2004,Wal,87,F,4010,254 +2004,Wal,88,M,1385,104 +2004,Wal,88,F,4262,302 +2004,Wal,89,M,1401,97 +2004,Wal,89,F,4375,268 +2004,Wal,90,M,1060,78 +2004,Wal,90,F,3535,217 +2004,Wal,91,M,763,63 +2004,Wal,91,F,2921,167 +2004,Wal,92,M,497,34 +2004,Wal,92,F,2167,141 +2004,Wal,93,M,394,22 +2004,Wal,93,F,1736,98 +2004,Wal,94,M,254,11 +2004,Wal,94,F,1266,84 +2004,Wal,95,M,165,17 +2004,Wal,95,F,974,70 +2004,Wal,96,M,94,4 +2004,Wal,96,F,731,36 +2004,Wal,97,M,69,2 +2004,Wal,97,F,478,24 +2004,Wal,98,M,54,4 +2004,Wal,98,F,311,16 +2004,Wal,99,M,18,0 +2004,Wal,99,F,179,14 +2004,Wal,100,M,13,1 +2004,Wal,100,F,141,8 +2004,Wal,101,M,6,0 +2004,Wal,101,F,63,6 +2004,Wal,102,M,3,0 +2004,Wal,102,F,42,4 +2004,Wal,103,M,3,0 +2004,Wal,103,F,19,4 +2004,Wal,104,M,2,0 +2004,Wal,104,F,13,1 +2004,Wal,105,M,0,0 +2004,Wal,105,F,7,0 +2004,Wal,106,M,0,0 +2004,Wal,106,F,5,1 +2004,Wal,107,M,0,0 +2004,Wal,107,F,0,0 +2004,Wal,108,M,0,0 +2004,Wal,108,F,2,0 +2004,Wal,109,M,0,0 +2004,Wal,109,F,0,0 +2004,Wal,110,M,0,0 +2004,Wal,110,F,0,0 +2004,Wal,111,M,0,0 +2004,Wal,111,F,0,0 +2004,Wal,112,M,0,0 +2004,Wal,112,F,0,0 +2004,Wal,113,M,0,0 +2004,Wal,113,F,0,0 +2004,Wal,114,M,0,0 +2004,Wal,114,F,0,0 +2004,Wal,115,M,0,0 +2004,Wal,115,F,0,0 +2004,Wal,116,M,0,0 +2004,Wal,116,F,0,0 +2004,Wal,117,M,0,0 +2004,Wal,117,F,0,0 +2004,Wal,118,M,0,0 +2004,Wal,118,F,0,0 +2004,Wal,119,M,0,0 +2004,Wal,119,F,0,0 +2004,Wal,120,M,0,0 +2004,Wal,120,F,0,0 +2005,BruCap,0,M,6164,1601 +2005,BruCap,0,F,5868,1506 +2005,BruCap,1,M,5758,1502 +2005,BruCap,1,F,5682,1418 +2005,BruCap,2,M,5538,1255 +2005,BruCap,2,F,5305,1318 +2005,BruCap,3,M,5481,1321 +2005,BruCap,3,F,5446,1258 +2005,BruCap,4,M,5307,1203 +2005,BruCap,4,F,5005,1129 +2005,BruCap,5,M,5131,1156 +2005,BruCap,5,F,4930,1077 +2005,BruCap,6,M,4960,1139 +2005,BruCap,6,F,4747,1170 +2005,BruCap,7,M,4982,1187 +2005,BruCap,7,F,4668,1019 +2005,BruCap,8,M,4696,1148 +2005,BruCap,8,F,4668,1081 +2005,BruCap,9,M,4663,1160 +2005,BruCap,9,F,4439,1048 +2005,BruCap,10,M,4719,1154 +2005,BruCap,10,F,4357,1052 +2005,BruCap,11,M,4660,1148 +2005,BruCap,11,F,4409,1055 +2005,BruCap,12,M,4644,1126 +2005,BruCap,12,F,4491,1015 +2005,BruCap,13,M,4639,1079 +2005,BruCap,13,F,4525,978 +2005,BruCap,14,M,4639,1101 +2005,BruCap,14,F,4398,1067 +2005,BruCap,15,M,4544,1106 +2005,BruCap,15,F,4412,1067 +2005,BruCap,16,M,4549,1135 +2005,BruCap,16,F,4318,1057 +2005,BruCap,17,M,4379,1114 +2005,BruCap,17,F,4311,1140 +2005,BruCap,18,M,4387,1188 +2005,BruCap,18,F,4252,1300 +2005,BruCap,19,M,4341,1184 +2005,BruCap,19,F,4116,1529 +2005,BruCap,20,M,4353,1392 +2005,BruCap,20,F,4455,1802 +2005,BruCap,21,M,4386,1474 +2005,BruCap,21,F,4471,2082 +2005,BruCap,22,M,4457,1807 +2005,BruCap,22,F,4592,2368 +2005,BruCap,23,M,4817,2048 +2005,BruCap,23,F,4996,2635 +2005,BruCap,24,M,5056,2273 +2005,BruCap,24,F,5423,2956 +2005,BruCap,25,M,5264,2530 +2005,BruCap,25,F,5494,3062 +2005,BruCap,26,M,5389,2810 +2005,BruCap,26,F,5803,3260 +2005,BruCap,27,M,5450,3088 +2005,BruCap,27,F,5677,3285 +2005,BruCap,28,M,5327,3273 +2005,BruCap,28,F,5574,3396 +2005,BruCap,29,M,5322,3299 +2005,BruCap,29,F,5223,3410 +2005,BruCap,30,M,5325,3510 +2005,BruCap,30,F,5204,3404 +2005,BruCap,31,M,5430,3532 +2005,BruCap,31,F,5312,3413 +2005,BruCap,32,M,5506,3542 +2005,BruCap,32,F,5182,3395 +2005,BruCap,33,M,5370,3499 +2005,BruCap,33,F,5119,3317 +2005,BruCap,34,M,5396,3663 +2005,BruCap,34,F,5125,3208 +2005,BruCap,35,M,5196,3412 +2005,BruCap,35,F,4907,3160 +2005,BruCap,36,M,5119,3348 +2005,BruCap,36,F,4729,3008 +2005,BruCap,37,M,4930,3180 +2005,BruCap,37,F,4656,2768 +2005,BruCap,38,M,4903,3055 +2005,BruCap,38,F,4806,2657 +2005,BruCap,39,M,5148,2992 +2005,BruCap,39,F,4850,2619 +2005,BruCap,40,M,5091,2896 +2005,BruCap,40,F,4895,2541 +2005,BruCap,41,M,4935,2546 +2005,BruCap,41,F,4799,2360 +2005,BruCap,42,M,4687,2508 +2005,BruCap,42,F,4760,2201 +2005,BruCap,43,M,4606,2373 +2005,BruCap,43,F,4743,2075 +2005,BruCap,44,M,4828,2241 +2005,BruCap,44,F,4927,2069 +2005,BruCap,45,M,4704,2089 +2005,BruCap,45,F,4834,1977 +2005,BruCap,46,M,4488,1987 +2005,BruCap,46,F,4836,1741 +2005,BruCap,47,M,4431,1820 +2005,BruCap,47,F,4739,1778 +2005,BruCap,48,M,4343,1860 +2005,BruCap,48,F,4772,1685 +2005,BruCap,49,M,4320,1776 +2005,BruCap,49,F,4785,1628 +2005,BruCap,50,M,4289,1591 +2005,BruCap,50,F,4661,1584 +2005,BruCap,51,M,4306,1553 +2005,BruCap,51,F,4662,1479 +2005,BruCap,52,M,4301,1544 +2005,BruCap,52,F,4648,1554 +2005,BruCap,53,M,4061,1362 +2005,BruCap,53,F,4378,1358 +2005,BruCap,54,M,3996,1498 +2005,BruCap,54,F,4541,1493 +2005,BruCap,55,M,3967,1354 +2005,BruCap,55,F,4377,1329 +2005,BruCap,56,M,3962,1391 +2005,BruCap,56,F,4414,1311 +2005,BruCap,57,M,3944,1349 +2005,BruCap,57,F,4545,1282 +2005,BruCap,58,M,3940,1260 +2005,BruCap,58,F,4374,1249 +2005,BruCap,59,M,3365,1058 +2005,BruCap,59,F,3878,1088 +2005,BruCap,60,M,3458,1082 +2005,BruCap,60,F,3984,1092 +2005,BruCap,61,M,3265,974 +2005,BruCap,61,F,3784,985 +2005,BruCap,62,M,2898,959 +2005,BruCap,62,F,3308,925 +2005,BruCap,63,M,2445,805 +2005,BruCap,63,F,2886,826 +2005,BruCap,64,M,2809,961 +2005,BruCap,64,F,3255,1074 +2005,BruCap,65,M,2804,864 +2005,BruCap,65,F,3473,870 +2005,BruCap,66,M,2817,828 +2005,BruCap,66,F,3396,862 +2005,BruCap,67,M,2675,731 +2005,BruCap,67,F,3309,771 +2005,BruCap,68,M,2614,698 +2005,BruCap,68,F,3308,830 +2005,BruCap,69,M,2543,646 +2005,BruCap,69,F,3363,806 +2005,BruCap,70,M,2600,622 +2005,BruCap,70,F,3341,729 +2005,BruCap,71,M,2489,584 +2005,BruCap,71,F,3513,628 +2005,BruCap,72,M,2577,596 +2005,BruCap,72,F,3662,653 +2005,BruCap,73,M,2559,473 +2005,BruCap,73,F,3666,584 +2005,BruCap,74,M,2419,546 +2005,BruCap,74,F,3940,686 +2005,BruCap,75,M,2304,453 +2005,BruCap,75,F,3778,482 +2005,BruCap,76,M,2278,396 +2005,BruCap,76,F,3672,521 +2005,BruCap,77,M,2181,331 +2005,BruCap,77,F,3641,426 +2005,BruCap,78,M,2068,312 +2005,BruCap,78,F,3708,387 +2005,BruCap,79,M,2030,247 +2005,BruCap,79,F,3644,357 +2005,BruCap,80,M,2001,223 +2005,BruCap,80,F,3711,334 +2005,BruCap,81,M,1792,197 +2005,BruCap,81,F,3665,297 +2005,BruCap,82,M,1637,193 +2005,BruCap,82,F,3514,249 +2005,BruCap,83,M,1659,168 +2005,BruCap,83,F,3362,215 +2005,BruCap,84,M,1379,116 +2005,BruCap,84,F,3191,251 +2005,BruCap,85,M,962,78 +2005,BruCap,85,F,2146,148 +2005,BruCap,86,M,540,65 +2005,BruCap,86,F,1475,113 +2005,BruCap,87,M,473,50 +2005,BruCap,87,F,1278,111 +2005,BruCap,88,M,366,33 +2005,BruCap,88,F,1273,84 +2005,BruCap,89,M,421,32 +2005,BruCap,89,F,1329,88 +2005,BruCap,90,M,393,32 +2005,BruCap,90,F,1360,86 +2005,BruCap,91,M,317,17 +2005,BruCap,91,F,1125,67 +2005,BruCap,92,M,237,25 +2005,BruCap,92,F,906,61 +2005,BruCap,93,M,176,11 +2005,BruCap,93,F,695,41 +2005,BruCap,94,M,120,11 +2005,BruCap,94,F,610,41 +2005,BruCap,95,M,78,6 +2005,BruCap,95,F,399,31 +2005,BruCap,96,M,45,5 +2005,BruCap,96,F,326,21 +2005,BruCap,97,M,27,3 +2005,BruCap,97,F,191,7 +2005,BruCap,98,M,27,1 +2005,BruCap,98,F,165,9 +2005,BruCap,99,M,25,1 +2005,BruCap,99,F,100,4 +2005,BruCap,100,M,11,3 +2005,BruCap,100,F,75,4 +2005,BruCap,101,M,4,0 +2005,BruCap,101,F,40,2 +2005,BruCap,102,M,1,1 +2005,BruCap,102,F,22,6 +2005,BruCap,103,M,0,1 +2005,BruCap,103,F,11,2 +2005,BruCap,104,M,0,2 +2005,BruCap,104,F,5,2 +2005,BruCap,105,M,1,0 +2005,BruCap,105,F,3,0 +2005,BruCap,106,M,0,0 +2005,BruCap,106,F,2,0 +2005,BruCap,107,M,0,0 +2005,BruCap,107,F,1,0 +2005,BruCap,108,M,0,0 +2005,BruCap,108,F,0,0 +2005,BruCap,109,M,0,0 +2005,BruCap,109,F,0,0 +2005,BruCap,110,M,0,0 +2005,BruCap,110,F,0,0 +2005,BruCap,111,M,0,0 +2005,BruCap,111,F,0,0 +2005,BruCap,112,M,0,0 +2005,BruCap,112,F,0,0 +2005,BruCap,113,M,0,0 +2005,BruCap,113,F,0,0 +2005,BruCap,114,M,0,0 +2005,BruCap,114,F,0,0 +2005,BruCap,115,M,0,0 +2005,BruCap,115,F,0,0 +2005,BruCap,116,M,0,0 +2005,BruCap,116,F,0,0 +2005,BruCap,117,M,0,0 +2005,BruCap,117,F,0,0 +2005,BruCap,118,M,0,0 +2005,BruCap,118,F,0,0 +2005,BruCap,119,M,0,0 +2005,BruCap,119,F,0,0 +2005,BruCap,120,M,0,0 +2005,BruCap,120,F,0,0 +2005,Fla,0,M,30459,1632 +2005,Fla,0,F,28780,1604 +2005,Fla,1,M,29540,1559 +2005,Fla,1,F,28241,1474 +2005,Fla,2,M,29713,1514 +2005,Fla,2,F,28196,1437 +2005,Fla,3,M,30026,1498 +2005,Fla,3,F,28772,1384 +2005,Fla,4,M,30918,1496 +2005,Fla,4,F,29617,1468 +2005,Fla,5,M,30911,1423 +2005,Fla,5,F,29901,1408 +2005,Fla,6,M,31839,1405 +2005,Fla,6,F,30260,1392 +2005,Fla,7,M,32467,1482 +2005,Fla,7,F,31188,1450 +2005,Fla,8,M,32609,1356 +2005,Fla,8,F,31409,1399 +2005,Fla,9,M,32721,1437 +2005,Fla,9,F,31401,1328 +2005,Fla,10,M,33196,1525 +2005,Fla,10,F,31555,1328 +2005,Fla,11,M,34537,1409 +2005,Fla,11,F,33495,1339 +2005,Fla,12,M,35869,1345 +2005,Fla,12,F,34370,1304 +2005,Fla,13,M,36373,1450 +2005,Fla,13,F,34545,1370 +2005,Fla,14,M,35961,1400 +2005,Fla,14,F,34309,1323 +2005,Fla,15,M,34750,1334 +2005,Fla,15,F,33089,1319 +2005,Fla,16,M,34363,1401 +2005,Fla,16,F,32882,1346 +2005,Fla,17,M,34059,1383 +2005,Fla,17,F,32194,1437 +2005,Fla,18,M,34190,1364 +2005,Fla,18,F,32211,1457 +2005,Fla,19,M,33034,1407 +2005,Fla,19,F,31689,1692 +2005,Fla,20,M,33794,1511 +2005,Fla,20,F,32286,1882 +2005,Fla,21,M,34594,1583 +2005,Fla,21,F,33344,2190 +2005,Fla,22,M,35533,1817 +2005,Fla,22,F,33725,2414 +2005,Fla,23,M,36558,2089 +2005,Fla,23,F,34568,2517 +2005,Fla,24,M,35910,2303 +2005,Fla,24,F,34768,2824 +2005,Fla,25,M,36181,2480 +2005,Fla,25,F,34399,2788 +2005,Fla,26,M,35149,2630 +2005,Fla,26,F,34195,2900 +2005,Fla,27,M,34378,2665 +2005,Fla,27,F,33738,2912 +2005,Fla,28,M,33841,2739 +2005,Fla,28,F,32640,2979 +2005,Fla,29,M,32975,2797 +2005,Fla,29,F,31909,2962 +2005,Fla,30,M,34255,3015 +2005,Fla,30,F,33527,2971 +2005,Fla,31,M,35732,3006 +2005,Fla,31,F,34663,2985 +2005,Fla,32,M,37318,3228 +2005,Fla,32,F,36705,3173 +2005,Fla,33,M,39037,3135 +2005,Fla,33,F,38670,3141 +2005,Fla,34,M,40361,3293 +2005,Fla,34,F,39419,3335 +2005,Fla,35,M,40496,3331 +2005,Fla,35,F,39576,3187 +2005,Fla,36,M,41007,3254 +2005,Fla,36,F,39972,3090 +2005,Fla,37,M,42519,3049 +2005,Fla,37,F,40768,2952 +2005,Fla,38,M,43753,3359 +2005,Fla,38,F,42679,3027 +2005,Fla,39,M,45309,3215 +2005,Fla,39,F,44006,2887 +2005,Fla,40,M,47101,3350 +2005,Fla,40,F,46204,2842 +2005,Fla,41,M,46909,3024 +2005,Fla,41,F,45715,2572 +2005,Fla,42,M,46309,2967 +2005,Fla,42,F,45057,2514 +2005,Fla,43,M,45911,2850 +2005,Fla,43,F,45382,2321 +2005,Fla,44,M,44972,2800 +2005,Fla,44,F,44289,2321 +2005,Fla,45,M,45738,2601 +2005,Fla,45,F,44937,2175 +2005,Fla,46,M,44851,2673 +2005,Fla,46,F,43697,1943 +2005,Fla,47,M,44092,2455 +2005,Fla,47,F,42973,1882 +2005,Fla,48,M,42764,2414 +2005,Fla,48,F,42464,1826 +2005,Fla,49,M,42120,2372 +2005,Fla,49,F,41923,1737 +2005,Fla,50,M,41283,2313 +2005,Fla,50,F,40707,1689 +2005,Fla,51,M,40270,2110 +2005,Fla,51,F,39353,1618 +2005,Fla,52,M,40121,2139 +2005,Fla,52,F,39078,1605 +2005,Fla,53,M,38204,2083 +2005,Fla,53,F,37553,1544 +2005,Fla,54,M,37651,2041 +2005,Fla,54,F,37414,1561 +2005,Fla,55,M,37686,2181 +2005,Fla,55,F,37053,1572 +2005,Fla,56,M,37509,2075 +2005,Fla,56,F,37452,1530 +2005,Fla,57,M,37073,2030 +2005,Fla,57,F,36952,1556 +2005,Fla,58,M,37900,2064 +2005,Fla,58,F,37518,1398 +2005,Fla,59,M,33397,1710 +2005,Fla,59,F,33734,1268 +2005,Fla,60,M,33037,1643 +2005,Fla,60,F,33452,1375 +2005,Fla,61,M,31390,1623 +2005,Fla,61,F,32026,1215 +2005,Fla,62,M,27255,1465 +2005,Fla,62,F,27913,1176 +2005,Fla,63,M,24350,1394 +2005,Fla,63,F,25588,1056 +2005,Fla,64,M,26660,1418 +2005,Fla,64,F,28349,1264 +2005,Fla,65,M,29015,1335 +2005,Fla,65,F,31518,1006 +2005,Fla,66,M,29730,1296 +2005,Fla,66,F,32129,1008 +2005,Fla,67,M,28528,1150 +2005,Fla,67,F,30886,952 +2005,Fla,68,M,27186,1097 +2005,Fla,68,F,30174,952 +2005,Fla,69,M,26611,1070 +2005,Fla,69,F,29937,802 +2005,Fla,70,M,26354,955 +2005,Fla,70,F,30407,854 +2005,Fla,71,M,25792,975 +2005,Fla,71,F,30051,798 +2005,Fla,72,M,25714,876 +2005,Fla,72,F,31017,716 +2005,Fla,73,M,24908,830 +2005,Fla,73,F,30686,617 +2005,Fla,74,M,23824,774 +2005,Fla,74,F,30131,721 +2005,Fla,75,M,21151,672 +2005,Fla,75,F,27715,592 +2005,Fla,76,M,19750,612 +2005,Fla,76,F,26571,598 +2005,Fla,77,M,18305,531 +2005,Fla,77,F,25131,528 +2005,Fla,78,M,16905,462 +2005,Fla,78,F,24806,520 +2005,Fla,79,M,16247,478 +2005,Fla,79,F,23756,468 +2005,Fla,80,M,14591,406 +2005,Fla,80,F,22448,435 +2005,Fla,81,M,13244,357 +2005,Fla,81,F,21581,421 +2005,Fla,82,M,11578,317 +2005,Fla,82,F,19376,337 +2005,Fla,83,M,10347,266 +2005,Fla,83,F,18224,312 +2005,Fla,84,M,8897,231 +2005,Fla,84,F,16543,269 +2005,Fla,85,M,5943,143 +2005,Fla,85,F,11618,172 +2005,Fla,86,M,3426,110 +2005,Fla,86,F,7439,141 +2005,Fla,87,M,2789,74 +2005,Fla,87,F,6480,118 +2005,Fla,88,M,2753,61 +2005,Fla,88,F,6522,104 +2005,Fla,89,M,2725,59 +2005,Fla,89,F,6716,96 +2005,Fla,90,M,2412,50 +2005,Fla,90,F,6685,99 +2005,Fla,91,M,1789,34 +2005,Fla,91,F,5650,73 +2005,Fla,92,M,1349,22 +2005,Fla,92,F,4440,67 +2005,Fla,93,M,920,19 +2005,Fla,93,F,3253,36 +2005,Fla,94,M,673,15 +2005,Fla,94,F,2474,34 +2005,Fla,95,M,422,7 +2005,Fla,95,F,1753,29 +2005,Fla,96,M,277,8 +2005,Fla,96,F,1373,18 +2005,Fla,97,M,185,4 +2005,Fla,97,F,935,10 +2005,Fla,98,M,108,2 +2005,Fla,98,F,601,7 +2005,Fla,99,M,84,2 +2005,Fla,99,F,403,12 +2005,Fla,100,M,48,2 +2005,Fla,100,F,264,3 +2005,Fla,101,M,19,1 +2005,Fla,101,F,147,5 +2005,Fla,102,M,13,1 +2005,Fla,102,F,89,2 +2005,Fla,103,M,1,1 +2005,Fla,103,F,49,1 +2005,Fla,104,M,3,0 +2005,Fla,104,F,20,0 +2005,Fla,105,M,2,0 +2005,Fla,105,F,15,1 +2005,Fla,106,M,0,0 +2005,Fla,106,F,5,0 +2005,Fla,107,M,0,0 +2005,Fla,107,F,2,0 +2005,Fla,108,M,0,0 +2005,Fla,108,F,2,0 +2005,Fla,109,M,0,0 +2005,Fla,109,F,0,1 +2005,Fla,110,M,0,0 +2005,Fla,110,F,0,0 +2005,Fla,111,M,0,0 +2005,Fla,111,F,0,0 +2005,Fla,112,M,0,0 +2005,Fla,112,F,0,0 +2005,Fla,113,M,0,0 +2005,Fla,113,F,0,0 +2005,Fla,114,M,0,0 +2005,Fla,114,F,0,0 +2005,Fla,115,M,0,0 +2005,Fla,115,F,0,0 +2005,Fla,116,M,0,0 +2005,Fla,116,F,0,0 +2005,Fla,117,M,0,0 +2005,Fla,117,F,0,0 +2005,Fla,118,M,0,0 +2005,Fla,118,F,0,0 +2005,Fla,119,M,0,0 +2005,Fla,119,F,0,0 +2005,Fla,120,M,0,0 +2005,Fla,120,F,0,0 +2005,Wal,0,M,18957,733 +2005,Wal,0,F,17837,747 +2005,Wal,1,M,18743,764 +2005,Wal,1,F,18129,693 +2005,Wal,2,M,19026,808 +2005,Wal,2,F,18104,735 +2005,Wal,3,M,19714,786 +2005,Wal,3,F,18964,765 +2005,Wal,4,M,20180,811 +2005,Wal,4,F,19188,782 +2005,Wal,5,M,19639,805 +2005,Wal,5,F,18707,831 +2005,Wal,6,M,19675,842 +2005,Wal,6,F,18753,815 +2005,Wal,7,M,19692,892 +2005,Wal,7,F,18915,867 +2005,Wal,8,M,19980,928 +2005,Wal,8,F,19064,855 +2005,Wal,9,M,19463,945 +2005,Wal,9,F,18734,857 +2005,Wal,10,M,19688,975 +2005,Wal,10,F,18718,927 +2005,Wal,11,M,20493,981 +2005,Wal,11,F,19391,980 +2005,Wal,12,M,21553,1078 +2005,Wal,12,F,20584,1023 +2005,Wal,13,M,22019,1092 +2005,Wal,13,F,21236,1050 +2005,Wal,14,M,21737,1161 +2005,Wal,14,F,20871,1069 +2005,Wal,15,M,21769,1138 +2005,Wal,15,F,20750,1128 +2005,Wal,16,M,21601,1152 +2005,Wal,16,F,20457,1234 +2005,Wal,17,M,20834,1228 +2005,Wal,17,F,19860,1235 +2005,Wal,18,M,20808,1295 +2005,Wal,18,F,19735,1328 +2005,Wal,19,M,19986,1174 +2005,Wal,19,F,19087,1354 +2005,Wal,20,M,19641,1304 +2005,Wal,20,F,18908,1467 +2005,Wal,21,M,19442,1438 +2005,Wal,21,F,18128,1614 +2005,Wal,22,M,19486,1611 +2005,Wal,22,F,18728,1910 +2005,Wal,23,M,19402,1735 +2005,Wal,23,F,18929,2030 +2005,Wal,24,M,19248,1918 +2005,Wal,24,F,18647,2126 +2005,Wal,25,M,18713,2047 +2005,Wal,25,F,17692,2223 +2005,Wal,26,M,18121,2093 +2005,Wal,26,F,17416,2148 +2005,Wal,27,M,18221,2076 +2005,Wal,27,F,17589,2196 +2005,Wal,28,M,18376,2217 +2005,Wal,28,F,18032,2113 +2005,Wal,29,M,18471,2252 +2005,Wal,29,F,18287,2286 +2005,Wal,30,M,19240,2502 +2005,Wal,30,F,18880,2484 +2005,Wal,31,M,20087,2754 +2005,Wal,31,F,19851,2602 +2005,Wal,32,M,20896,2905 +2005,Wal,32,F,20675,2725 +2005,Wal,33,M,21273,2911 +2005,Wal,33,F,21262,2716 +2005,Wal,34,M,20969,2878 +2005,Wal,34,F,20677,2789 +2005,Wal,35,M,20879,2959 +2005,Wal,35,F,20849,2837 +2005,Wal,36,M,20493,2999 +2005,Wal,36,F,20751,2914 +2005,Wal,37,M,20928,3031 +2005,Wal,37,F,21074,2759 +2005,Wal,38,M,21421,3393 +2005,Wal,38,F,21529,3093 +2005,Wal,39,M,22214,3434 +2005,Wal,39,F,22350,2933 +2005,Wal,40,M,23006,3256 +2005,Wal,40,F,23217,2939 +2005,Wal,41,M,22578,3272 +2005,Wal,41,F,23018,2880 +2005,Wal,42,M,22055,3130 +2005,Wal,42,F,22602,2672 +2005,Wal,43,M,22580,3122 +2005,Wal,43,F,23197,2740 +2005,Wal,44,M,22426,3461 +2005,Wal,44,F,22744,2606 +2005,Wal,45,M,22409,3216 +2005,Wal,45,F,23486,2548 +2005,Wal,46,M,22077,3232 +2005,Wal,46,F,23089,2474 +2005,Wal,47,M,21794,3179 +2005,Wal,47,F,22565,2340 +2005,Wal,48,M,21199,3270 +2005,Wal,48,F,22317,2439 +2005,Wal,49,M,20958,3099 +2005,Wal,49,F,22189,2352 +2005,Wal,50,M,20848,3052 +2005,Wal,50,F,22014,2310 +2005,Wal,51,M,20691,2938 +2005,Wal,51,F,21634,2149 +2005,Wal,52,M,20460,2863 +2005,Wal,52,F,21292,2150 +2005,Wal,53,M,19652,2781 +2005,Wal,53,F,20911,2133 +2005,Wal,54,M,20426,2777 +2005,Wal,54,F,21041,2174 +2005,Wal,55,M,20247,2702 +2005,Wal,55,F,21004,1989 +2005,Wal,56,M,20601,2713 +2005,Wal,56,F,21672,2144 +2005,Wal,57,M,20417,2685 +2005,Wal,57,F,21362,1967 +2005,Wal,58,M,19855,2480 +2005,Wal,58,F,21226,1838 +2005,Wal,59,M,14708,1983 +2005,Wal,59,F,16236,1562 +2005,Wal,60,M,14613,1958 +2005,Wal,60,F,15882,1572 +2005,Wal,61,M,13542,1738 +2005,Wal,61,F,14924,1447 +2005,Wal,62,M,11734,1651 +2005,Wal,62,F,13034,1425 +2005,Wal,63,M,10850,1590 +2005,Wal,63,F,12271,1334 +2005,Wal,64,M,12039,1805 +2005,Wal,64,F,13706,1597 +2005,Wal,65,M,12941,1682 +2005,Wal,65,F,15031,1617 +2005,Wal,66,M,12844,1529 +2005,Wal,66,F,15239,1634 +2005,Wal,67,M,12266,1559 +2005,Wal,67,F,14375,1453 +2005,Wal,68,M,11656,1477 +2005,Wal,68,F,14276,1438 +2005,Wal,69,M,11288,1463 +2005,Wal,69,F,14112,1521 +2005,Wal,70,M,11599,1390 +2005,Wal,70,F,14558,1508 +2005,Wal,71,M,11515,1330 +2005,Wal,71,F,14541,1517 +2005,Wal,72,M,11730,1333 +2005,Wal,72,F,15641,1401 +2005,Wal,73,M,11684,1206 +2005,Wal,73,F,15860,1429 +2005,Wal,74,M,11091,1273 +2005,Wal,74,F,15807,1471 +2005,Wal,75,M,10102,1178 +2005,Wal,75,F,14768,1364 +2005,Wal,76,M,9508,1065 +2005,Wal,76,F,14584,1280 +2005,Wal,77,M,8891,1064 +2005,Wal,77,F,14008,1278 +2005,Wal,78,M,8402,980 +2005,Wal,78,F,13709,1270 +2005,Wal,79,M,7890,843 +2005,Wal,79,F,13705,1203 +2005,Wal,80,M,7176,784 +2005,Wal,80,F,12921,1074 +2005,Wal,81,M,6364,708 +2005,Wal,81,F,12148,1013 +2005,Wal,82,M,5717,574 +2005,Wal,82,F,11471,907 +2005,Wal,83,M,5105,460 +2005,Wal,83,F,10986,754 +2005,Wal,84,M,4440,364 +2005,Wal,84,F,10043,730 +2005,Wal,85,M,2774,209 +2005,Wal,85,F,6707,451 +2005,Wal,86,M,1636,118 +2005,Wal,86,F,4251,257 +2005,Wal,87,M,1326,93 +2005,Wal,87,F,3693,237 +2005,Wal,88,M,1235,92 +2005,Wal,88,F,3516,223 +2005,Wal,89,M,1123,83 +2005,Wal,89,F,3705,249 +2005,Wal,90,M,1138,86 +2005,Wal,90,F,3750,229 +2005,Wal,91,M,839,63 +2005,Wal,91,F,2907,185 +2005,Wal,92,M,568,52 +2005,Wal,92,F,2369,134 +2005,Wal,93,M,363,26 +2005,Wal,93,F,1737,111 +2005,Wal,94,M,283,15 +2005,Wal,94,F,1330,88 +2005,Wal,95,M,186,5 +2005,Wal,95,F,969,71 +2005,Wal,96,M,115,8 +2005,Wal,96,F,731,47 +2005,Wal,97,M,58,4 +2005,Wal,97,F,528,26 +2005,Wal,98,M,40,0 +2005,Wal,98,F,320,16 +2005,Wal,99,M,32,4 +2005,Wal,99,F,218,13 +2005,Wal,100,M,11,0 +2005,Wal,100,F,122,9 +2005,Wal,101,M,9,1 +2005,Wal,101,F,93,6 +2005,Wal,102,M,4,0 +2005,Wal,102,F,38,3 +2005,Wal,103,M,2,0 +2005,Wal,103,F,23,2 +2005,Wal,104,M,1,0 +2005,Wal,104,F,10,2 +2005,Wal,105,M,0,0 +2005,Wal,105,F,8,0 +2005,Wal,106,M,0,0 +2005,Wal,106,F,5,0 +2005,Wal,107,M,0,0 +2005,Wal,107,F,1,1 +2005,Wal,108,M,0,0 +2005,Wal,108,F,0,0 +2005,Wal,109,M,0,0 +2005,Wal,109,F,0,0 +2005,Wal,110,M,0,0 +2005,Wal,110,F,0,0 +2005,Wal,111,M,0,0 +2005,Wal,111,F,0,0 +2005,Wal,112,M,0,0 +2005,Wal,112,F,0,0 +2005,Wal,113,M,0,0 +2005,Wal,113,F,0,0 +2005,Wal,114,M,0,0 +2005,Wal,114,F,0,0 +2005,Wal,115,M,0,0 +2005,Wal,115,F,0,0 +2005,Wal,116,M,0,0 +2005,Wal,116,F,0,0 +2005,Wal,117,M,0,0 +2005,Wal,117,F,0,0 +2005,Wal,118,M,0,0 +2005,Wal,118,F,0,0 +2005,Wal,119,M,0,0 +2005,Wal,119,F,0,0 +2005,Wal,120,M,0,0 +2005,Wal,120,F,0,0 +2006,BruCap,0,M,6171,1724 +2006,BruCap,0,F,6008,1593 +2006,BruCap,1,M,6070,1631 +2006,BruCap,1,F,5814,1497 +2006,BruCap,2,M,5636,1496 +2006,BruCap,2,F,5549,1437 +2006,BruCap,3,M,5421,1282 +2006,BruCap,3,F,5235,1337 +2006,BruCap,4,M,5364,1307 +2006,BruCap,4,F,5345,1250 +2006,BruCap,5,M,5217,1276 +2006,BruCap,5,F,4926,1154 +2006,BruCap,6,M,5061,1193 +2006,BruCap,6,F,4878,1104 +2006,BruCap,7,M,4885,1186 +2006,BruCap,7,F,4685,1211 +2006,BruCap,8,M,4956,1200 +2006,BruCap,8,F,4620,1083 +2006,BruCap,9,M,4695,1192 +2006,BruCap,9,F,4605,1105 +2006,BruCap,10,M,4651,1197 +2006,BruCap,10,F,4421,1074 +2006,BruCap,11,M,4707,1147 +2006,BruCap,11,F,4339,1085 +2006,BruCap,12,M,4674,1140 +2006,BruCap,12,F,4430,1058 +2006,BruCap,13,M,4649,1153 +2006,BruCap,13,F,4490,1032 +2006,BruCap,14,M,4657,1101 +2006,BruCap,14,F,4510,1021 +2006,BruCap,15,M,4633,1125 +2006,BruCap,15,F,4417,1079 +2006,BruCap,16,M,4542,1128 +2006,BruCap,16,F,4431,1101 +2006,BruCap,17,M,4585,1161 +2006,BruCap,17,F,4368,1063 +2006,BruCap,18,M,4435,1151 +2006,BruCap,18,F,4431,1353 +2006,BruCap,19,M,4465,1343 +2006,BruCap,19,F,4409,1634 +2006,BruCap,20,M,4414,1370 +2006,BruCap,20,F,4249,1896 +2006,BruCap,21,M,4453,1580 +2006,BruCap,21,F,4612,2154 +2006,BruCap,22,M,4505,1665 +2006,BruCap,22,F,4642,2429 +2006,BruCap,23,M,4623,2012 +2006,BruCap,23,F,4855,2720 +2006,BruCap,24,M,5037,2311 +2006,BruCap,24,F,5261,3026 +2006,BruCap,25,M,5303,2581 +2006,BruCap,25,F,5653,3394 +2006,BruCap,26,M,5472,2860 +2006,BruCap,26,F,5613,3463 +2006,BruCap,27,M,5457,3138 +2006,BruCap,27,F,5795,3510 +2006,BruCap,28,M,5431,3307 +2006,BruCap,28,F,5602,3578 +2006,BruCap,29,M,5325,3540 +2006,BruCap,29,F,5541,3558 +2006,BruCap,30,M,5303,3498 +2006,BruCap,30,F,5146,3642 +2006,BruCap,31,M,5272,3617 +2006,BruCap,31,F,5088,3573 +2006,BruCap,32,M,5371,3608 +2006,BruCap,32,F,5241,3482 +2006,BruCap,33,M,5426,3582 +2006,BruCap,33,F,5122,3427 +2006,BruCap,34,M,5331,3548 +2006,BruCap,34,F,5069,3252 +2006,BruCap,35,M,5342,3663 +2006,BruCap,35,F,5083,3246 +2006,BruCap,36,M,5206,3430 +2006,BruCap,36,F,4903,3122 +2006,BruCap,37,M,5081,3374 +2006,BruCap,37,F,4684,2928 +2006,BruCap,38,M,4981,3149 +2006,BruCap,38,F,4624,2734 +2006,BruCap,39,M,4911,3040 +2006,BruCap,39,F,4779,2651 +2006,BruCap,40,M,5154,2960 +2006,BruCap,40,F,4841,2570 +2006,BruCap,41,M,5085,2878 +2006,BruCap,41,F,4863,2519 +2006,BruCap,42,M,4898,2532 +2006,BruCap,42,F,4816,2305 +2006,BruCap,43,M,4699,2494 +2006,BruCap,43,F,4749,2137 +2006,BruCap,44,M,4581,2386 +2006,BruCap,44,F,4749,2074 +2006,BruCap,45,M,4792,2181 +2006,BruCap,45,F,4936,2066 +2006,BruCap,46,M,4655,2067 +2006,BruCap,46,F,4825,1936 +2006,BruCap,47,M,4474,1969 +2006,BruCap,47,F,4835,1709 +2006,BruCap,48,M,4389,1804 +2006,BruCap,48,F,4738,1755 +2006,BruCap,49,M,4319,1833 +2006,BruCap,49,F,4736,1689 +2006,BruCap,50,M,4335,1761 +2006,BruCap,50,F,4781,1580 +2006,BruCap,51,M,4240,1562 +2006,BruCap,51,F,4655,1547 +2006,BruCap,52,M,4287,1513 +2006,BruCap,52,F,4665,1437 +2006,BruCap,53,M,4288,1506 +2006,BruCap,53,F,4628,1514 +2006,BruCap,54,M,4023,1322 +2006,BruCap,54,F,4365,1333 +2006,BruCap,55,M,3928,1461 +2006,BruCap,55,F,4525,1449 +2006,BruCap,56,M,3920,1302 +2006,BruCap,56,F,4359,1278 +2006,BruCap,57,M,3887,1338 +2006,BruCap,57,F,4367,1277 +2006,BruCap,58,M,3862,1305 +2006,BruCap,58,F,4488,1235 +2006,BruCap,59,M,3864,1217 +2006,BruCap,59,F,4312,1237 +2006,BruCap,60,M,3272,1017 +2006,BruCap,60,F,3826,1060 +2006,BruCap,61,M,3410,1015 +2006,BruCap,61,F,3930,1064 +2006,BruCap,62,M,3173,934 +2006,BruCap,62,F,3710,959 +2006,BruCap,63,M,2835,908 +2006,BruCap,63,F,3247,894 +2006,BruCap,64,M,2389,799 +2006,BruCap,64,F,2818,795 +2006,BruCap,65,M,2746,872 +2006,BruCap,65,F,3218,1020 +2006,BruCap,66,M,2721,803 +2006,BruCap,66,F,3437,830 +2006,BruCap,67,M,2725,778 +2006,BruCap,67,F,3366,826 +2006,BruCap,68,M,2606,697 +2006,BruCap,68,F,3243,767 +2006,BruCap,69,M,2537,665 +2006,BruCap,69,F,3275,810 +2006,BruCap,70,M,2473,602 +2006,BruCap,70,F,3304,788 +2006,BruCap,71,M,2525,585 +2006,BruCap,71,F,3289,715 +2006,BruCap,72,M,2403,545 +2006,BruCap,72,F,3463,610 +2006,BruCap,73,M,2480,557 +2006,BruCap,73,F,3586,636 +2006,BruCap,74,M,2442,455 +2006,BruCap,74,F,3565,575 +2006,BruCap,75,M,2321,520 +2006,BruCap,75,F,3840,652 +2006,BruCap,76,M,2196,422 +2006,BruCap,76,F,3660,463 +2006,BruCap,77,M,2170,362 +2006,BruCap,77,F,3589,494 +2006,BruCap,78,M,2046,308 +2006,BruCap,78,F,3508,423 +2006,BruCap,79,M,1951,295 +2006,BruCap,79,F,3573,365 +2006,BruCap,80,M,1867,226 +2006,BruCap,80,F,3491,332 +2006,BruCap,81,M,1837,200 +2006,BruCap,81,F,3522,313 +2006,BruCap,82,M,1643,176 +2006,BruCap,82,F,3455,282 +2006,BruCap,83,M,1494,178 +2006,BruCap,83,F,3277,228 +2006,BruCap,84,M,1482,140 +2006,BruCap,84,F,3119,201 +2006,BruCap,85,M,1234,103 +2006,BruCap,85,F,2927,234 +2006,BruCap,86,M,838,73 +2006,BruCap,86,F,1963,132 +2006,BruCap,87,M,454,54 +2006,BruCap,87,F,1315,99 +2006,BruCap,88,M,414,34 +2006,BruCap,88,F,1111,97 +2006,BruCap,89,M,305,24 +2006,BruCap,89,F,1107,76 +2006,BruCap,90,M,345,30 +2006,BruCap,90,F,1154,74 +2006,BruCap,91,M,326,30 +2006,BruCap,91,F,1126,77 +2006,BruCap,92,M,236,14 +2006,BruCap,92,F,923,54 +2006,BruCap,93,M,176,17 +2006,BruCap,93,F,741,51 +2006,BruCap,94,M,126,11 +2006,BruCap,94,F,529,33 +2006,BruCap,95,M,89,7 +2006,BruCap,95,F,464,31 +2006,BruCap,96,M,48,5 +2006,BruCap,96,F,285,25 +2006,BruCap,97,M,29,5 +2006,BruCap,97,F,219,15 +2006,BruCap,98,M,14,3 +2006,BruCap,98,F,133,1 +2006,BruCap,99,M,16,2 +2006,BruCap,99,F,118,7 +2006,BruCap,100,M,15,0 +2006,BruCap,100,F,68,2 +2006,BruCap,101,M,6,1 +2006,BruCap,101,F,49,3 +2006,BruCap,102,M,1,0 +2006,BruCap,102,F,26,1 +2006,BruCap,103,M,0,0 +2006,BruCap,103,F,10,5 +2006,BruCap,104,M,0,0 +2006,BruCap,104,F,6,1 +2006,BruCap,105,M,0,0 +2006,BruCap,105,F,2,1 +2006,BruCap,106,M,1,0 +2006,BruCap,106,F,1,0 +2006,BruCap,107,M,0,0 +2006,BruCap,107,F,2,0 +2006,BruCap,108,M,0,0 +2006,BruCap,108,F,0,0 +2006,BruCap,109,M,0,0 +2006,BruCap,109,F,0,0 +2006,BruCap,110,M,0,0 +2006,BruCap,110,F,0,0 +2006,BruCap,111,M,0,0 +2006,BruCap,111,F,0,0 +2006,BruCap,112,M,0,0 +2006,BruCap,112,F,0,0 +2006,BruCap,113,M,0,0 +2006,BruCap,113,F,0,0 +2006,BruCap,114,M,0,0 +2006,BruCap,114,F,0,0 +2006,BruCap,115,M,0,0 +2006,BruCap,115,F,0,0 +2006,BruCap,116,M,0,0 +2006,BruCap,116,F,0,0 +2006,BruCap,117,M,0,0 +2006,BruCap,117,F,0,0 +2006,BruCap,118,M,0,0 +2006,BruCap,118,F,0,0 +2006,BruCap,119,M,0,0 +2006,BruCap,119,F,0,0 +2006,BruCap,120,M,0,0 +2006,BruCap,120,F,0,0 +2006,Fla,0,M,31247,1777 +2006,Fla,0,F,29385,1701 +2006,Fla,1,M,30754,1772 +2006,Fla,1,F,29125,1714 +2006,Fla,2,M,29757,1698 +2006,Fla,2,F,28458,1593 +2006,Fla,3,M,29897,1627 +2006,Fla,3,F,28429,1547 +2006,Fla,4,M,30243,1613 +2006,Fla,4,F,28963,1500 +2006,Fla,5,M,31088,1608 +2006,Fla,5,F,29812,1610 +2006,Fla,6,M,31018,1566 +2006,Fla,6,F,30065,1523 +2006,Fla,7,M,32004,1494 +2006,Fla,7,F,30413,1487 +2006,Fla,8,M,32577,1598 +2006,Fla,8,F,31309,1569 +2006,Fla,9,M,32715,1457 +2006,Fla,9,F,31537,1473 +2006,Fla,10,M,32851,1528 +2006,Fla,10,F,31534,1420 +2006,Fla,11,M,33340,1648 +2006,Fla,11,F,31677,1399 +2006,Fla,12,M,34706,1452 +2006,Fla,12,F,33621,1436 +2006,Fla,13,M,35988,1423 +2006,Fla,13,F,34478,1428 +2006,Fla,14,M,36478,1537 +2006,Fla,14,F,34669,1431 +2006,Fla,15,M,36053,1524 +2006,Fla,15,F,34427,1397 +2006,Fla,16,M,34899,1455 +2006,Fla,16,F,33190,1389 +2006,Fla,17,M,34487,1543 +2006,Fla,17,F,32978,1506 +2006,Fla,18,M,34172,1464 +2006,Fla,18,F,32285,1635 +2006,Fla,19,M,34195,1474 +2006,Fla,19,F,32285,1774 +2006,Fla,20,M,33051,1584 +2006,Fla,20,F,31726,2086 +2006,Fla,21,M,33741,1755 +2006,Fla,21,F,32337,2257 +2006,Fla,22,M,34549,1827 +2006,Fla,22,F,33422,2661 +2006,Fla,23,M,35496,2139 +2006,Fla,23,F,33735,2828 +2006,Fla,24,M,36498,2377 +2006,Fla,24,F,34554,2862 +2006,Fla,25,M,35770,2602 +2006,Fla,25,F,34804,3149 +2006,Fla,26,M,36136,2761 +2006,Fla,26,F,34463,3054 +2006,Fla,27,M,35173,2845 +2006,Fla,27,F,34323,3144 +2006,Fla,28,M,34400,2925 +2006,Fla,28,F,33852,3111 +2006,Fla,29,M,33907,2986 +2006,Fla,29,F,32804,3215 +2006,Fla,30,M,33082,3035 +2006,Fla,30,F,32082,3150 +2006,Fla,31,M,34386,3213 +2006,Fla,31,F,33751,3106 +2006,Fla,32,M,35812,3225 +2006,Fla,32,F,34817,3161 +2006,Fla,33,M,37424,3385 +2006,Fla,33,F,36856,3304 +2006,Fla,34,M,39218,3290 +2006,Fla,34,F,38883,3282 +2006,Fla,35,M,40558,3463 +2006,Fla,35,F,39624,3445 +2006,Fla,36,M,40619,3469 +2006,Fla,36,F,39714,3307 +2006,Fla,37,M,41108,3402 +2006,Fla,37,F,40170,3206 +2006,Fla,38,M,42598,3188 +2006,Fla,38,F,40886,3092 +2006,Fla,39,M,43860,3489 +2006,Fla,39,F,42805,3106 +2006,Fla,40,M,45349,3347 +2006,Fla,40,F,44134,2973 +2006,Fla,41,M,47143,3455 +2006,Fla,41,F,46287,2881 +2006,Fla,42,M,46980,3086 +2006,Fla,42,F,45775,2615 +2006,Fla,43,M,46306,3061 +2006,Fla,43,F,45113,2565 +2006,Fla,44,M,45874,2910 +2006,Fla,44,F,45428,2394 +2006,Fla,45,M,44973,2868 +2006,Fla,45,F,44336,2359 +2006,Fla,46,M,45664,2636 +2006,Fla,46,F,44959,2226 +2006,Fla,47,M,44776,2742 +2006,Fla,47,F,43691,1993 +2006,Fla,48,M,44020,2484 +2006,Fla,48,F,42961,1923 +2006,Fla,49,M,42687,2460 +2006,Fla,49,F,42431,1825 +2006,Fla,50,M,41999,2405 +2006,Fla,50,F,41868,1769 +2006,Fla,51,M,41123,2332 +2006,Fla,51,F,40649,1719 +2006,Fla,52,M,40139,2160 +2006,Fla,52,F,39262,1630 +2006,Fla,53,M,39959,2146 +2006,Fla,53,F,38987,1629 +2006,Fla,54,M,38064,2088 +2006,Fla,54,F,37462,1564 +2006,Fla,55,M,37467,2052 +2006,Fla,55,F,37317,1604 +2006,Fla,56,M,37454,2179 +2006,Fla,56,F,36941,1571 +2006,Fla,57,M,37307,2069 +2006,Fla,57,F,37351,1533 +2006,Fla,58,M,36826,2024 +2006,Fla,58,F,36852,1554 +2006,Fla,59,M,37598,2059 +2006,Fla,59,F,37379,1425 +2006,Fla,60,M,33125,1679 +2006,Fla,60,F,33603,1268 +2006,Fla,61,M,32705,1667 +2006,Fla,61,F,33291,1369 +2006,Fla,62,M,31043,1635 +2006,Fla,62,F,31886,1218 +2006,Fla,63,M,26967,1453 +2006,Fla,63,F,27793,1159 +2006,Fla,64,M,24052,1368 +2006,Fla,64,F,25441,1047 +2006,Fla,65,M,26291,1392 +2006,Fla,65,F,28170,1248 +2006,Fla,66,M,28620,1284 +2006,Fla,66,F,31304,1011 +2006,Fla,67,M,29276,1270 +2006,Fla,67,F,31885,1000 +2006,Fla,68,M,28021,1121 +2006,Fla,68,F,30608,957 +2006,Fla,69,M,26662,1062 +2006,Fla,69,F,29853,929 +2006,Fla,70,M,26028,1041 +2006,Fla,70,F,29639,803 +2006,Fla,71,M,25726,939 +2006,Fla,71,F,30006,845 +2006,Fla,72,M,25059,945 +2006,Fla,72,F,29633,799 +2006,Fla,73,M,24916,851 +2006,Fla,73,F,30555,705 +2006,Fla,74,M,24106,809 +2006,Fla,74,F,30129,608 +2006,Fla,75,M,22943,746 +2006,Fla,75,F,29522,697 +2006,Fla,76,M,20276,639 +2006,Fla,76,F,27094,578 +2006,Fla,77,M,18838,576 +2006,Fla,77,F,25890,579 +2006,Fla,78,M,17327,497 +2006,Fla,78,F,24385,510 +2006,Fla,79,M,15911,437 +2006,Fla,79,F,23927,500 +2006,Fla,80,M,15125,446 +2006,Fla,80,F,22805,447 +2006,Fla,81,M,13554,375 +2006,Fla,81,F,21406,409 +2006,Fla,82,M,12144,336 +2006,Fla,82,F,20441,396 +2006,Fla,83,M,10546,291 +2006,Fla,83,F,18226,311 +2006,Fla,84,M,9238,235 +2006,Fla,84,F,16948,289 +2006,Fla,85,M,7845,206 +2006,Fla,85,F,15227,249 +2006,Fla,86,M,5156,122 +2006,Fla,86,F,10550,159 +2006,Fla,87,M,2917,91 +2006,Fla,87,F,6650,126 +2006,Fla,88,M,2344,60 +2006,Fla,88,F,5705,105 +2006,Fla,89,M,2248,50 +2006,Fla,89,F,5678,87 +2006,Fla,90,M,2215,45 +2006,Fla,90,F,5695,80 +2006,Fla,91,M,1900,38 +2006,Fla,91,F,5509,80 +2006,Fla,92,M,1346,25 +2006,Fla,92,F,4625,62 +2006,Fla,93,M,992,17 +2006,Fla,93,F,3569,61 +2006,Fla,94,M,671,15 +2006,Fla,94,F,2525,27 +2006,Fla,95,M,482,11 +2006,Fla,95,F,1899,29 +2006,Fla,96,M,278,7 +2006,Fla,96,F,1302,21 +2006,Fla,97,M,185,7 +2006,Fla,97,F,991,14 +2006,Fla,98,M,127,2 +2006,Fla,98,F,670,8 +2006,Fla,99,M,59,1 +2006,Fla,99,F,391,6 +2006,Fla,100,M,52,2 +2006,Fla,100,F,274,12 +2006,Fla,101,M,25,1 +2006,Fla,101,F,165,1 +2006,Fla,102,M,10,1 +2006,Fla,102,F,77,3 +2006,Fla,103,M,3,0 +2006,Fla,103,F,51,2 +2006,Fla,104,M,0,0 +2006,Fla,104,F,31,1 +2006,Fla,105,M,2,0 +2006,Fla,105,F,11,0 +2006,Fla,106,M,1,0 +2006,Fla,106,F,6,0 +2006,Fla,107,M,0,0 +2006,Fla,107,F,4,0 +2006,Fla,108,M,0,0 +2006,Fla,108,F,2,0 +2006,Fla,109,M,0,0 +2006,Fla,109,F,0,0 +2006,Fla,110,M,0,0 +2006,Fla,110,F,0,1 +2006,Fla,111,M,0,0 +2006,Fla,111,F,0,0 +2006,Fla,112,M,0,0 +2006,Fla,112,F,0,0 +2006,Fla,113,M,0,0 +2006,Fla,113,F,0,0 +2006,Fla,114,M,0,0 +2006,Fla,114,F,0,0 +2006,Fla,115,M,0,0 +2006,Fla,115,F,0,0 +2006,Fla,116,M,0,0 +2006,Fla,116,F,0,0 +2006,Fla,117,M,0,0 +2006,Fla,117,F,0,0 +2006,Fla,118,M,0,0 +2006,Fla,118,F,0,0 +2006,Fla,119,M,0,0 +2006,Fla,119,F,0,0 +2006,Fla,120,M,0,0 +2006,Fla,120,F,0,0 +2006,Wal,0,M,19047,781 +2006,Wal,0,F,18153,779 +2006,Wal,1,M,19191,776 +2006,Wal,1,F,18069,858 +2006,Wal,2,M,18948,866 +2006,Wal,2,F,18362,762 +2006,Wal,3,M,19170,883 +2006,Wal,3,F,18255,811 +2006,Wal,4,M,19867,852 +2006,Wal,4,F,19146,825 +2006,Wal,5,M,20281,893 +2006,Wal,5,F,19292,873 +2006,Wal,6,M,19770,878 +2006,Wal,6,F,18802,903 +2006,Wal,7,M,19755,904 +2006,Wal,7,F,18838,880 +2006,Wal,8,M,19795,938 +2006,Wal,8,F,19011,927 +2006,Wal,9,M,20072,997 +2006,Wal,9,F,19141,898 +2006,Wal,10,M,19557,1009 +2006,Wal,10,F,18804,917 +2006,Wal,11,M,19784,1055 +2006,Wal,11,F,18805,972 +2006,Wal,12,M,20574,1041 +2006,Wal,12,F,19482,1023 +2006,Wal,13,M,21622,1117 +2006,Wal,13,F,20664,1099 +2006,Wal,14,M,22097,1125 +2006,Wal,14,F,21303,1101 +2006,Wal,15,M,21812,1219 +2006,Wal,15,F,20920,1118 +2006,Wal,16,M,21835,1179 +2006,Wal,16,F,20857,1181 +2006,Wal,17,M,21633,1235 +2006,Wal,17,F,20542,1332 +2006,Wal,18,M,20904,1278 +2006,Wal,18,F,19924,1345 +2006,Wal,19,M,20835,1342 +2006,Wal,19,F,19782,1345 +2006,Wal,20,M,19973,1243 +2006,Wal,20,F,19101,1508 +2006,Wal,21,M,19628,1403 +2006,Wal,21,F,18883,1679 +2006,Wal,22,M,19387,1581 +2006,Wal,22,F,18046,1745 +2006,Wal,23,M,19350,1699 +2006,Wal,23,F,18614,2058 +2006,Wal,24,M,19219,1814 +2006,Wal,24,F,18749,2189 +2006,Wal,25,M,19028,2050 +2006,Wal,25,F,18466,2209 +2006,Wal,26,M,18582,2120 +2006,Wal,26,F,17698,2294 +2006,Wal,27,M,18092,2217 +2006,Wal,27,F,17548,2253 +2006,Wal,28,M,18231,2218 +2006,Wal,28,F,17750,2300 +2006,Wal,29,M,18420,2317 +2006,Wal,29,F,18211,2216 +2006,Wal,30,M,18541,2308 +2006,Wal,30,F,18452,2363 +2006,Wal,31,M,19364,2602 +2006,Wal,31,F,19102,2564 +2006,Wal,32,M,20271,2829 +2006,Wal,32,F,20052,2668 +2006,Wal,33,M,20987,2988 +2006,Wal,33,F,20860,2790 +2006,Wal,34,M,21336,3014 +2006,Wal,34,F,21434,2810 +2006,Wal,35,M,21079,2941 +2006,Wal,35,F,20807,2862 +2006,Wal,36,M,20993,3012 +2006,Wal,36,F,21022,2859 +2006,Wal,37,M,20567,3035 +2006,Wal,37,F,20903,2954 +2006,Wal,38,M,21049,3071 +2006,Wal,38,F,21191,2808 +2006,Wal,39,M,21475,3372 +2006,Wal,39,F,21635,3145 +2006,Wal,40,M,22254,3448 +2006,Wal,40,F,22488,2938 +2006,Wal,41,M,23043,3269 +2006,Wal,41,F,23270,2959 +2006,Wal,42,M,22621,3270 +2006,Wal,42,F,23079,2894 +2006,Wal,43,M,22032,3140 +2006,Wal,43,F,22678,2697 +2006,Wal,44,M,22595,3103 +2006,Wal,44,F,23240,2726 +2006,Wal,45,M,22434,3399 +2006,Wal,45,F,22784,2607 +2006,Wal,46,M,22441,3217 +2006,Wal,46,F,23515,2531 +2006,Wal,47,M,22065,3204 +2006,Wal,47,F,23104,2468 +2006,Wal,48,M,21713,3133 +2006,Wal,48,F,22559,2341 +2006,Wal,49,M,21149,3241 +2006,Wal,49,F,22325,2419 +2006,Wal,50,M,20887,3067 +2006,Wal,50,F,22192,2334 +2006,Wal,51,M,20820,3008 +2006,Wal,51,F,21990,2284 +2006,Wal,52,M,20592,2915 +2006,Wal,52,F,21633,2141 +2006,Wal,53,M,20309,2835 +2006,Wal,53,F,21271,2143 +2006,Wal,54,M,19568,2734 +2006,Wal,54,F,20868,2134 +2006,Wal,55,M,20297,2731 +2006,Wal,55,F,20989,2148 +2006,Wal,56,M,20081,2660 +2006,Wal,56,F,20960,1987 +2006,Wal,57,M,20457,2672 +2006,Wal,57,F,21590,2143 +2006,Wal,58,M,20251,2660 +2006,Wal,58,F,21272,1962 +2006,Wal,59,M,19634,2437 +2006,Wal,59,F,21142,1827 +2006,Wal,60,M,14518,1948 +2006,Wal,60,F,16156,1552 +2006,Wal,61,M,14440,1930 +2006,Wal,61,F,15805,1572 +2006,Wal,62,M,13336,1713 +2006,Wal,62,F,14844,1429 +2006,Wal,63,M,11552,1622 +2006,Wal,63,F,12945,1397 +2006,Wal,64,M,10666,1565 +2006,Wal,64,F,12187,1335 +2006,Wal,65,M,11871,1749 +2006,Wal,65,F,13605,1605 +2006,Wal,66,M,12681,1636 +2006,Wal,66,F,14898,1595 +2006,Wal,67,M,12555,1484 +2006,Wal,67,F,15088,1613 +2006,Wal,68,M,12001,1525 +2006,Wal,68,F,14214,1448 +2006,Wal,69,M,11405,1421 +2006,Wal,69,F,14106,1420 +2006,Wal,70,M,10955,1405 +2006,Wal,70,F,13920,1493 +2006,Wal,71,M,11250,1342 +2006,Wal,71,F,14314,1491 +2006,Wal,72,M,11113,1268 +2006,Wal,72,F,14317,1485 +2006,Wal,73,M,11281,1273 +2006,Wal,73,F,15378,1375 +2006,Wal,74,M,11193,1145 +2006,Wal,74,F,15512,1394 +2006,Wal,75,M,10568,1200 +2006,Wal,75,F,15461,1430 +2006,Wal,76,M,9580,1107 +2006,Wal,76,F,14364,1339 +2006,Wal,77,M,8966,998 +2006,Wal,77,F,14181,1248 +2006,Wal,78,M,8343,995 +2006,Wal,78,F,13535,1227 +2006,Wal,79,M,7792,905 +2006,Wal,79,F,13197,1229 +2006,Wal,80,M,7294,774 +2006,Wal,80,F,13090,1160 +2006,Wal,81,M,6580,715 +2006,Wal,81,F,12243,1024 +2006,Wal,82,M,5739,633 +2006,Wal,82,F,11443,954 +2006,Wal,83,M,5127,522 +2006,Wal,83,F,10731,855 +2006,Wal,84,M,4520,406 +2006,Wal,84,F,10177,711 +2006,Wal,85,M,3880,319 +2006,Wal,85,F,9174,667 +2006,Wal,86,M,2391,177 +2006,Wal,86,F,6028,415 +2006,Wal,87,M,1364,97 +2006,Wal,87,F,3789,230 +2006,Wal,88,M,1096,77 +2006,Wal,88,F,3246,203 +2006,Wal,89,M,1009,75 +2006,Wal,89,F,2990,189 +2006,Wal,90,M,921,57 +2006,Wal,90,F,3134,207 +2006,Wal,91,M,880,67 +2006,Wal,91,F,3127,198 +2006,Wal,92,M,633,46 +2006,Wal,92,F,2329,149 +2006,Wal,93,M,419,38 +2006,Wal,93,F,1867,115 +2006,Wal,94,M,244,18 +2006,Wal,94,F,1323,82 +2006,Wal,95,M,207,11 +2006,Wal,95,F,984,75 +2006,Wal,96,M,128,4 +2006,Wal,96,F,686,54 +2006,Wal,97,M,63,7 +2006,Wal,97,F,504,29 +2006,Wal,98,M,42,2 +2006,Wal,98,F,348,18 +2006,Wal,99,M,24,0 +2006,Wal,99,F,214,10 +2006,Wal,100,M,17,3 +2006,Wal,100,F,137,10 +2006,Wal,101,M,4,0 +2006,Wal,101,F,70,5 +2006,Wal,102,M,3,1 +2006,Wal,102,F,50,4 +2006,Wal,103,M,1,0 +2006,Wal,103,F,20,3 +2006,Wal,104,M,0,0 +2006,Wal,104,F,15,1 +2006,Wal,105,M,0,0 +2006,Wal,105,F,4,2 +2006,Wal,106,M,0,0 +2006,Wal,106,F,7,0 +2006,Wal,107,M,0,0 +2006,Wal,107,F,2,0 +2006,Wal,108,M,0,0 +2006,Wal,108,F,0,0 +2006,Wal,109,M,0,0 +2006,Wal,109,F,0,0 +2006,Wal,110,M,0,0 +2006,Wal,110,F,0,0 +2006,Wal,111,M,0,0 +2006,Wal,111,F,0,0 +2006,Wal,112,M,0,0 +2006,Wal,112,F,0,0 +2006,Wal,113,M,0,0 +2006,Wal,113,F,0,0 +2006,Wal,114,M,0,0 +2006,Wal,114,F,0,0 +2006,Wal,115,M,0,0 +2006,Wal,115,F,0,0 +2006,Wal,116,M,0,0 +2006,Wal,116,F,0,0 +2006,Wal,117,M,0,0 +2006,Wal,117,F,0,0 +2006,Wal,118,M,0,0 +2006,Wal,118,F,0,0 +2006,Wal,119,M,0,0 +2006,Wal,119,F,0,0 +2006,Wal,120,M,0,0 +2006,Wal,120,F,0,0 +2007,BruCap,0,M,6562,1797 +2007,BruCap,0,F,6123,1753 +2007,BruCap,1,M,6103,1726 +2007,BruCap,1,F,5857,1629 +2007,BruCap,2,M,5896,1658 +2007,BruCap,2,F,5680,1553 +2007,BruCap,3,M,5482,1516 +2007,BruCap,3,F,5400,1444 +2007,BruCap,4,M,5304,1344 +2007,BruCap,4,F,5159,1364 +2007,BruCap,5,M,5304,1368 +2007,BruCap,5,F,5221,1257 +2007,BruCap,6,M,5128,1304 +2007,BruCap,6,F,4818,1231 +2007,BruCap,7,M,4992,1220 +2007,BruCap,7,F,4795,1150 +2007,BruCap,8,M,4802,1195 +2007,BruCap,8,F,4619,1211 +2007,BruCap,9,M,4885,1198 +2007,BruCap,9,F,4560,1106 +2007,BruCap,10,M,4660,1193 +2007,BruCap,10,F,4545,1147 +2007,BruCap,11,M,4611,1206 +2007,BruCap,11,F,4393,1104 +2007,BruCap,12,M,4689,1139 +2007,BruCap,12,F,4315,1091 +2007,BruCap,13,M,4647,1154 +2007,BruCap,13,F,4427,1058 +2007,BruCap,14,M,4650,1150 +2007,BruCap,14,F,4456,1072 +2007,BruCap,15,M,4652,1114 +2007,BruCap,15,F,4529,1050 +2007,BruCap,16,M,4647,1147 +2007,BruCap,16,F,4439,1081 +2007,BruCap,17,M,4575,1135 +2007,BruCap,17,F,4462,1131 +2007,BruCap,18,M,4619,1200 +2007,BruCap,18,F,4436,1237 +2007,BruCap,19,M,4533,1286 +2007,BruCap,19,F,4543,1678 +2007,BruCap,20,M,4512,1512 +2007,BruCap,20,F,4499,1976 +2007,BruCap,21,M,4461,1572 +2007,BruCap,21,F,4332,2299 +2007,BruCap,22,M,4569,1817 +2007,BruCap,22,F,4735,2525 +2007,BruCap,23,M,4617,1956 +2007,BruCap,23,F,4812,2777 +2007,BruCap,24,M,4821,2370 +2007,BruCap,24,F,5147,3056 +2007,BruCap,25,M,5258,2630 +2007,BruCap,25,F,5548,3359 +2007,BruCap,26,M,5479,3028 +2007,BruCap,26,F,5769,3759 +2007,BruCap,27,M,5553,3214 +2007,BruCap,27,F,5652,3783 +2007,BruCap,28,M,5487,3458 +2007,BruCap,28,F,5657,3773 +2007,BruCap,29,M,5420,3547 +2007,BruCap,29,F,5514,3771 +2007,BruCap,30,M,5305,3799 +2007,BruCap,30,F,5431,3669 +2007,BruCap,31,M,5264,3637 +2007,BruCap,31,F,5049,3733 +2007,BruCap,32,M,5228,3723 +2007,BruCap,32,F,4974,3622 +2007,BruCap,33,M,5321,3685 +2007,BruCap,33,F,5203,3477 +2007,BruCap,34,M,5333,3673 +2007,BruCap,34,F,5012,3420 +2007,BruCap,35,M,5282,3598 +2007,BruCap,35,F,4993,3252 +2007,BruCap,36,M,5273,3703 +2007,BruCap,36,F,5007,3225 +2007,BruCap,37,M,5156,3397 +2007,BruCap,37,F,4836,3135 +2007,BruCap,38,M,5053,3386 +2007,BruCap,38,F,4648,2919 +2007,BruCap,39,M,4945,3168 +2007,BruCap,39,F,4590,2697 +2007,BruCap,40,M,4867,3072 +2007,BruCap,40,F,4763,2597 +2007,BruCap,41,M,5093,2933 +2007,BruCap,41,F,4833,2514 +2007,BruCap,42,M,5056,2894 +2007,BruCap,42,F,4881,2438 +2007,BruCap,43,M,4849,2583 +2007,BruCap,43,F,4767,2285 +2007,BruCap,44,M,4684,2478 +2007,BruCap,44,F,4756,2108 +2007,BruCap,45,M,4608,2372 +2007,BruCap,45,F,4717,2046 +2007,BruCap,46,M,4767,2195 +2007,BruCap,46,F,4942,2071 +2007,BruCap,47,M,4636,2083 +2007,BruCap,47,F,4828,1912 +2007,BruCap,48,M,4447,1990 +2007,BruCap,48,F,4847,1697 +2007,BruCap,49,M,4362,1790 +2007,BruCap,49,F,4708,1702 +2007,BruCap,50,M,4291,1806 +2007,BruCap,50,F,4719,1650 +2007,BruCap,51,M,4323,1747 +2007,BruCap,51,F,4734,1559 +2007,BruCap,52,M,4222,1549 +2007,BruCap,52,F,4659,1511 +2007,BruCap,53,M,4265,1476 +2007,BruCap,53,F,4612,1451 +2007,BruCap,54,M,4215,1490 +2007,BruCap,54,F,4613,1476 +2007,BruCap,55,M,3974,1306 +2007,BruCap,55,F,4316,1303 +2007,BruCap,56,M,3897,1439 +2007,BruCap,56,F,4478,1396 +2007,BruCap,57,M,3860,1306 +2007,BruCap,57,F,4336,1270 +2007,BruCap,58,M,3841,1310 +2007,BruCap,58,F,4314,1249 +2007,BruCap,59,M,3787,1262 +2007,BruCap,59,F,4444,1210 +2007,BruCap,60,M,3748,1162 +2007,BruCap,60,F,4257,1194 +2007,BruCap,61,M,3205,972 +2007,BruCap,61,F,3781,1052 +2007,BruCap,62,M,3341,971 +2007,BruCap,62,F,3846,1030 +2007,BruCap,63,M,3106,898 +2007,BruCap,63,F,3661,934 +2007,BruCap,64,M,2745,877 +2007,BruCap,64,F,3192,868 +2007,BruCap,65,M,2339,751 +2007,BruCap,65,F,2768,769 +2007,BruCap,66,M,2675,814 +2007,BruCap,66,F,3211,991 +2007,BruCap,67,M,2641,768 +2007,BruCap,67,F,3383,793 +2007,BruCap,68,M,2649,753 +2007,BruCap,68,F,3338,800 +2007,BruCap,69,M,2542,667 +2007,BruCap,69,F,3181,750 +2007,BruCap,70,M,2454,637 +2007,BruCap,70,F,3226,786 +2007,BruCap,71,M,2395,581 +2007,BruCap,71,F,3262,772 +2007,BruCap,72,M,2440,563 +2007,BruCap,72,F,3245,689 +2007,BruCap,73,M,2330,515 +2007,BruCap,73,F,3389,606 +2007,BruCap,74,M,2376,530 +2007,BruCap,74,F,3518,601 +2007,BruCap,75,M,2334,436 +2007,BruCap,75,F,3488,549 +2007,BruCap,76,M,2211,481 +2007,BruCap,76,F,3740,632 +2007,BruCap,77,M,2070,395 +2007,BruCap,77,F,3560,447 +2007,BruCap,78,M,2054,333 +2007,BruCap,78,F,3488,474 +2007,BruCap,79,M,1919,277 +2007,BruCap,79,F,3375,402 +2007,BruCap,80,M,1812,267 +2007,BruCap,80,F,3439,352 +2007,BruCap,81,M,1717,209 +2007,BruCap,81,F,3326,308 +2007,BruCap,82,M,1699,187 +2007,BruCap,82,F,3334,305 +2007,BruCap,83,M,1477,162 +2007,BruCap,83,F,3261,260 +2007,BruCap,84,M,1352,158 +2007,BruCap,84,F,3053,210 +2007,BruCap,85,M,1306,128 +2007,BruCap,85,F,2862,186 +2007,BruCap,86,M,1083,90 +2007,BruCap,86,F,2660,222 +2007,BruCap,87,M,719,65 +2007,BruCap,87,F,1755,126 +2007,BruCap,88,M,401,43 +2007,BruCap,88,F,1162,94 +2007,BruCap,89,M,340,30 +2007,BruCap,89,F,976,86 +2007,BruCap,90,M,252,23 +2007,BruCap,90,F,967,72 +2007,BruCap,91,M,271,25 +2007,BruCap,91,F,965,64 +2007,BruCap,92,M,257,25 +2007,BruCap,92,F,952,62 +2007,BruCap,93,M,177,10 +2007,BruCap,93,F,724,40 +2007,BruCap,94,M,132,15 +2007,BruCap,94,F,584,43 +2007,BruCap,95,M,99,10 +2007,BruCap,95,F,395,29 +2007,BruCap,96,M,65,5 +2007,BruCap,96,F,334,22 +2007,BruCap,97,M,34,3 +2007,BruCap,97,F,203,20 +2007,BruCap,98,M,21,2 +2007,BruCap,98,F,154,11 +2007,BruCap,99,M,9,3 +2007,BruCap,99,F,94,1 +2007,BruCap,100,M,8,0 +2007,BruCap,100,F,83,3 +2007,BruCap,101,M,9,0 +2007,BruCap,101,F,37,1 +2007,BruCap,102,M,5,0 +2007,BruCap,102,F,36,3 +2007,BruCap,103,M,1,0 +2007,BruCap,103,F,13,0 +2007,BruCap,104,M,0,0 +2007,BruCap,104,F,6,3 +2007,BruCap,105,M,0,0 +2007,BruCap,105,F,5,1 +2007,BruCap,106,M,0,0 +2007,BruCap,106,F,1,0 +2007,BruCap,107,M,1,0 +2007,BruCap,107,F,1,0 +2007,BruCap,108,M,0,0 +2007,BruCap,108,F,2,0 +2007,BruCap,109,M,0,0 +2007,BruCap,109,F,0,0 +2007,BruCap,110,M,0,0 +2007,BruCap,110,F,0,0 +2007,BruCap,111,M,0,0 +2007,BruCap,111,F,0,0 +2007,BruCap,112,M,0,0 +2007,BruCap,112,F,0,0 +2007,BruCap,113,M,0,0 +2007,BruCap,113,F,0,0 +2007,BruCap,114,M,0,0 +2007,BruCap,114,F,0,0 +2007,BruCap,115,M,0,0 +2007,BruCap,115,F,0,0 +2007,BruCap,116,M,0,0 +2007,BruCap,116,F,0,0 +2007,BruCap,117,M,0,0 +2007,BruCap,117,F,0,0 +2007,BruCap,118,M,0,0 +2007,BruCap,118,F,0,0 +2007,BruCap,119,M,0,0 +2007,BruCap,119,F,0,0 +2007,BruCap,120,M,0,0 +2007,BruCap,120,F,0,0 +2007,Fla,0,M,31544,1985 +2007,Fla,0,F,30323,1910 +2007,Fla,1,M,31539,1935 +2007,Fla,1,F,29724,1854 +2007,Fla,2,M,31061,1892 +2007,Fla,2,F,29389,1859 +2007,Fla,3,M,29984,1848 +2007,Fla,3,F,28658,1699 +2007,Fla,4,M,30078,1743 +2007,Fla,4,F,28587,1634 +2007,Fla,5,M,30407,1705 +2007,Fla,5,F,29135,1617 +2007,Fla,6,M,31207,1717 +2007,Fla,6,F,29956,1707 +2007,Fla,7,M,31166,1619 +2007,Fla,7,F,30195,1601 +2007,Fla,8,M,32134,1626 +2007,Fla,8,F,30548,1593 +2007,Fla,9,M,32732,1698 +2007,Fla,9,F,31419,1662 +2007,Fla,10,M,32822,1579 +2007,Fla,10,F,31682,1547 +2007,Fla,11,M,32995,1565 +2007,Fla,11,F,31659,1487 +2007,Fla,12,M,33499,1698 +2007,Fla,12,F,31813,1473 +2007,Fla,13,M,34820,1537 +2007,Fla,13,F,33728,1503 +2007,Fla,14,M,36079,1554 +2007,Fla,14,F,34586,1491 +2007,Fla,15,M,36576,1585 +2007,Fla,15,F,34753,1450 +2007,Fla,16,M,36180,1570 +2007,Fla,16,F,34502,1481 +2007,Fla,17,M,35008,1533 +2007,Fla,17,F,33272,1552 +2007,Fla,18,M,34575,1635 +2007,Fla,18,F,33066,1730 +2007,Fla,19,M,34243,1563 +2007,Fla,19,F,32383,1907 +2007,Fla,20,M,34219,1668 +2007,Fla,20,F,32332,2193 +2007,Fla,21,M,33060,1818 +2007,Fla,21,F,31837,2602 +2007,Fla,22,M,33740,2027 +2007,Fla,22,F,32399,2747 +2007,Fla,23,M,34528,2160 +2007,Fla,23,F,33441,3043 +2007,Fla,24,M,35413,2574 +2007,Fla,24,F,33709,3206 +2007,Fla,25,M,36436,2742 +2007,Fla,25,F,34550,3235 +2007,Fla,26,M,35717,2964 +2007,Fla,26,F,34870,3495 +2007,Fla,27,M,36126,3076 +2007,Fla,27,F,34550,3376 +2007,Fla,28,M,35279,3088 +2007,Fla,28,F,34519,3379 +2007,Fla,29,M,34510,3212 +2007,Fla,29,F,34052,3358 +2007,Fla,30,M,34002,3259 +2007,Fla,30,F,33038,3422 +2007,Fla,31,M,33188,3282 +2007,Fla,31,F,32299,3320 +2007,Fla,32,M,34580,3434 +2007,Fla,32,F,33966,3213 +2007,Fla,33,M,35980,3426 +2007,Fla,33,F,35002,3306 +2007,Fla,34,M,37585,3559 +2007,Fla,34,F,37066,3466 +2007,Fla,35,M,39371,3501 +2007,Fla,35,F,39066,3393 +2007,Fla,36,M,40598,3700 +2007,Fla,36,F,39842,3553 +2007,Fla,37,M,40739,3630 +2007,Fla,37,F,39900,3351 +2007,Fla,38,M,41166,3602 +2007,Fla,38,F,40330,3260 +2007,Fla,39,M,42665,3345 +2007,Fla,39,F,41004,3120 +2007,Fla,40,M,43935,3595 +2007,Fla,40,F,42936,3155 +2007,Fla,41,M,45432,3492 +2007,Fla,41,F,44229,3029 +2007,Fla,42,M,47174,3530 +2007,Fla,42,F,46367,2957 +2007,Fla,43,M,47018,3193 +2007,Fla,43,F,45847,2643 +2007,Fla,44,M,46337,3084 +2007,Fla,44,F,45153,2608 +2007,Fla,45,M,45835,2969 +2007,Fla,45,F,45452,2416 +2007,Fla,46,M,44951,2935 +2007,Fla,46,F,44382,2374 +2007,Fla,47,M,45616,2683 +2007,Fla,47,F,44948,2233 +2007,Fla,48,M,44698,2792 +2007,Fla,48,F,43687,1998 +2007,Fla,49,M,43936,2533 +2007,Fla,49,F,42938,1950 +2007,Fla,50,M,42658,2455 +2007,Fla,50,F,42385,1848 +2007,Fla,51,M,41891,2426 +2007,Fla,51,F,41838,1760 +2007,Fla,52,M,40972,2357 +2007,Fla,52,F,40609,1754 +2007,Fla,53,M,40002,2180 +2007,Fla,53,F,39190,1689 +2007,Fla,54,M,39842,2164 +2007,Fla,54,F,38892,1648 +2007,Fla,55,M,37885,2099 +2007,Fla,55,F,37367,1551 +2007,Fla,56,M,37273,2042 +2007,Fla,56,F,37207,1614 +2007,Fla,57,M,37280,2169 +2007,Fla,57,F,36802,1566 +2007,Fla,58,M,37068,2068 +2007,Fla,58,F,37216,1537 +2007,Fla,59,M,36573,1994 +2007,Fla,59,F,36724,1554 +2007,Fla,60,M,37288,2005 +2007,Fla,60,F,37252,1422 +2007,Fla,61,M,32772,1667 +2007,Fla,61,F,33426,1258 +2007,Fla,62,M,32356,1637 +2007,Fla,62,F,33165,1354 +2007,Fla,63,M,30719,1601 +2007,Fla,63,F,31733,1212 +2007,Fla,64,M,26668,1447 +2007,Fla,64,F,27671,1141 +2007,Fla,65,M,23726,1353 +2007,Fla,65,F,25277,1052 +2007,Fla,66,M,25892,1360 +2007,Fla,66,F,27990,1223 +2007,Fla,67,M,28203,1261 +2007,Fla,67,F,31074,1012 +2007,Fla,68,M,28778,1240 +2007,Fla,68,F,31611,984 +2007,Fla,69,M,27535,1091 +2007,Fla,69,F,30347,952 +2007,Fla,70,M,26139,1041 +2007,Fla,70,F,29537,915 +2007,Fla,71,M,25442,1008 +2007,Fla,71,F,29315,799 +2007,Fla,72,M,25050,902 +2007,Fla,72,F,29624,836 +2007,Fla,73,M,24320,907 +2007,Fla,73,F,29228,780 +2007,Fla,74,M,24127,817 +2007,Fla,74,F,30030,692 +2007,Fla,75,M,23234,769 +2007,Fla,75,F,29568,584 +2007,Fla,76,M,21984,705 +2007,Fla,76,F,28876,675 +2007,Fla,77,M,19394,594 +2007,Fla,77,F,26414,558 +2007,Fla,78,M,17856,541 +2007,Fla,78,F,25199,567 +2007,Fla,79,M,16312,455 +2007,Fla,79,F,23550,488 +2007,Fla,80,M,14894,394 +2007,Fla,80,F,22970,479 +2007,Fla,81,M,14056,416 +2007,Fla,81,F,21853,426 +2007,Fla,82,M,12487,336 +2007,Fla,82,F,20292,389 +2007,Fla,83,M,11034,298 +2007,Fla,83,F,19249,372 +2007,Fla,84,M,9507,259 +2007,Fla,84,F,17008,284 +2007,Fla,85,M,8179,208 +2007,Fla,85,F,15647,266 +2007,Fla,86,M,6871,178 +2007,Fla,86,F,13828,229 +2007,Fla,87,M,4442,105 +2007,Fla,87,F,9429,134 +2007,Fla,88,M,2458,78 +2007,Fla,88,F,5870,112 +2007,Fla,89,M,1974,51 +2007,Fla,89,F,4940,100 +2007,Fla,90,M,1805,45 +2007,Fla,90,F,4845,76 +2007,Fla,91,M,1774,40 +2007,Fla,91,F,4807,68 +2007,Fla,92,M,1462,30 +2007,Fla,92,F,4560,70 +2007,Fla,93,M,1027,19 +2007,Fla,93,F,3707,51 +2007,Fla,94,M,742,9 +2007,Fla,94,F,2788,49 +2007,Fla,95,M,491,12 +2007,Fla,95,F,1936,21 +2007,Fla,96,M,330,8 +2007,Fla,96,F,1370,18 +2007,Fla,97,M,185,6 +2007,Fla,97,F,948,15 +2007,Fla,98,M,130,4 +2007,Fla,98,F,679,10 +2007,Fla,99,M,83,2 +2007,Fla,99,F,437,7 +2007,Fla,100,M,34,0 +2007,Fla,100,F,260,6 +2007,Fla,101,M,29,2 +2007,Fla,101,F,177,7 +2007,Fla,102,M,20,1 +2007,Fla,102,F,95,1 +2007,Fla,103,M,6,1 +2007,Fla,103,F,42,2 +2007,Fla,104,M,2,0 +2007,Fla,104,F,28,1 +2007,Fla,105,M,0,0 +2007,Fla,105,F,16,0 +2007,Fla,106,M,2,0 +2007,Fla,106,F,5,0 +2007,Fla,107,M,0,0 +2007,Fla,107,F,4,0 +2007,Fla,108,M,0,0 +2007,Fla,108,F,3,0 +2007,Fla,109,M,0,0 +2007,Fla,109,F,1,0 +2007,Fla,110,M,0,0 +2007,Fla,110,F,0,0 +2007,Fla,111,M,0,0 +2007,Fla,111,F,0,1 +2007,Fla,112,M,0,0 +2007,Fla,112,F,0,0 +2007,Fla,113,M,0,0 +2007,Fla,113,F,0,0 +2007,Fla,114,M,0,0 +2007,Fla,114,F,0,0 +2007,Fla,115,M,0,0 +2007,Fla,115,F,0,0 +2007,Fla,116,M,0,0 +2007,Fla,116,F,0,0 +2007,Fla,117,M,0,0 +2007,Fla,117,F,0,0 +2007,Fla,118,M,0,0 +2007,Fla,118,F,0,0 +2007,Fla,119,M,0,0 +2007,Fla,119,F,0,0 +2007,Fla,120,M,0,0 +2007,Fla,120,F,0,0 +2007,Wal,0,M,19286,910 +2007,Wal,0,F,18628,897 +2007,Wal,1,M,19255,848 +2007,Wal,1,F,18460,865 +2007,Wal,2,M,19378,839 +2007,Wal,2,F,18312,909 +2007,Wal,3,M,19113,961 +2007,Wal,3,F,18557,835 +2007,Wal,4,M,19312,941 +2007,Wal,4,F,18385,869 +2007,Wal,5,M,20005,915 +2007,Wal,5,F,19261,872 +2007,Wal,6,M,20382,936 +2007,Wal,6,F,19382,928 +2007,Wal,7,M,19873,943 +2007,Wal,7,F,18892,965 +2007,Wal,8,M,19854,957 +2007,Wal,8,F,18914,957 +2007,Wal,9,M,19893,995 +2007,Wal,9,F,19132,996 +2007,Wal,10,M,20138,1035 +2007,Wal,10,F,19239,943 +2007,Wal,11,M,19659,1044 +2007,Wal,11,F,18890,951 +2007,Wal,12,M,19891,1083 +2007,Wal,12,F,18914,1030 +2007,Wal,13,M,20686,1044 +2007,Wal,13,F,19575,1051 +2007,Wal,14,M,21706,1145 +2007,Wal,14,F,20749,1116 +2007,Wal,15,M,22209,1173 +2007,Wal,15,F,21375,1124 +2007,Wal,16,M,21887,1254 +2007,Wal,16,F,21011,1207 +2007,Wal,17,M,21908,1245 +2007,Wal,17,F,20919,1321 +2007,Wal,18,M,21712,1304 +2007,Wal,18,F,20639,1441 +2007,Wal,19,M,20938,1304 +2007,Wal,19,F,19952,1419 +2007,Wal,20,M,20852,1393 +2007,Wal,20,F,19825,1500 +2007,Wal,21,M,19938,1375 +2007,Wal,21,F,19117,1720 +2007,Wal,22,M,19527,1513 +2007,Wal,22,F,18841,1889 +2007,Wal,23,M,19263,1732 +2007,Wal,23,F,17945,1964 +2007,Wal,24,M,19179,1796 +2007,Wal,24,F,18449,2233 +2007,Wal,25,M,19053,1953 +2007,Wal,25,F,18584,2320 +2007,Wal,26,M,18882,2175 +2007,Wal,26,F,18400,2361 +2007,Wal,27,M,18527,2245 +2007,Wal,27,F,17766,2421 +2007,Wal,28,M,18117,2366 +2007,Wal,28,F,17687,2383 +2007,Wal,29,M,18289,2337 +2007,Wal,29,F,17863,2441 +2007,Wal,30,M,18496,2384 +2007,Wal,30,F,18404,2320 +2007,Wal,31,M,18671,2406 +2007,Wal,31,F,18648,2512 +2007,Wal,32,M,19457,2690 +2007,Wal,32,F,19315,2604 +2007,Wal,33,M,20408,2967 +2007,Wal,33,F,20256,2732 +2007,Wal,34,M,21165,3051 +2007,Wal,34,F,21101,2843 +2007,Wal,35,M,21509,3076 +2007,Wal,35,F,21585,2839 +2007,Wal,36,M,21310,3034 +2007,Wal,36,F,20967,2928 +2007,Wal,37,M,21129,3039 +2007,Wal,37,F,21163,2857 +2007,Wal,38,M,20726,2992 +2007,Wal,38,F,21068,2954 +2007,Wal,39,M,21172,3089 +2007,Wal,39,F,21334,2827 +2007,Wal,40,M,21594,3399 +2007,Wal,40,F,21765,3124 +2007,Wal,41,M,22381,3434 +2007,Wal,41,F,22596,2906 +2007,Wal,42,M,23132,3247 +2007,Wal,42,F,23372,2957 +2007,Wal,43,M,22689,3276 +2007,Wal,43,F,23202,2894 +2007,Wal,44,M,22080,3150 +2007,Wal,44,F,22760,2633 +2007,Wal,45,M,22569,3114 +2007,Wal,45,F,23301,2699 +2007,Wal,46,M,22479,3381 +2007,Wal,46,F,22853,2589 +2007,Wal,47,M,22440,3173 +2007,Wal,47,F,23581,2497 +2007,Wal,48,M,22057,3149 +2007,Wal,48,F,23113,2447 +2007,Wal,49,M,21687,3088 +2007,Wal,49,F,22583,2324 +2007,Wal,50,M,21094,3187 +2007,Wal,50,F,22372,2378 +2007,Wal,51,M,20822,3058 +2007,Wal,51,F,22193,2309 +2007,Wal,52,M,20776,3006 +2007,Wal,52,F,21965,2273 +2007,Wal,53,M,20502,2861 +2007,Wal,53,F,21614,2126 +2007,Wal,54,M,20201,2825 +2007,Wal,54,F,21227,2135 +2007,Wal,55,M,19474,2687 +2007,Wal,55,F,20875,2113 +2007,Wal,56,M,20196,2683 +2007,Wal,56,F,20959,2125 +2007,Wal,57,M,19927,2615 +2007,Wal,57,F,20931,1959 +2007,Wal,58,M,20294,2634 +2007,Wal,58,F,21526,2129 +2007,Wal,59,M,20054,2598 +2007,Wal,59,F,21187,1952 +2007,Wal,60,M,19431,2419 +2007,Wal,60,F,21043,1812 +2007,Wal,61,M,14372,1917 +2007,Wal,61,F,16091,1536 +2007,Wal,62,M,14242,1912 +2007,Wal,62,F,15697,1556 +2007,Wal,63,M,13137,1698 +2007,Wal,63,F,14734,1432 +2007,Wal,64,M,11399,1589 +2007,Wal,64,F,12853,1383 +2007,Wal,65,M,10496,1519 +2007,Wal,65,F,12100,1326 +2007,Wal,66,M,11655,1698 +2007,Wal,66,F,13488,1586 +2007,Wal,67,M,12428,1603 +2007,Wal,67,F,14791,1589 +2007,Wal,68,M,12280,1441 +2007,Wal,68,F,14922,1594 +2007,Wal,69,M,11743,1474 +2007,Wal,69,F,14061,1431 +2007,Wal,70,M,11116,1371 +2007,Wal,70,F,13931,1410 +2007,Wal,71,M,10620,1342 +2007,Wal,71,F,13697,1458 +2007,Wal,72,M,10889,1310 +2007,Wal,72,F,14110,1481 +2007,Wal,73,M,10724,1223 +2007,Wal,73,F,14040,1469 +2007,Wal,74,M,10864,1214 +2007,Wal,74,F,15082,1359 +2007,Wal,75,M,10730,1095 +2007,Wal,75,F,15172,1373 +2007,Wal,76,M,10066,1137 +2007,Wal,76,F,15050,1392 +2007,Wal,77,M,9082,1031 +2007,Wal,77,F,13917,1295 +2007,Wal,78,M,8429,927 +2007,Wal,78,F,13675,1214 +2007,Wal,79,M,7846,904 +2007,Wal,79,F,13022,1175 +2007,Wal,80,M,7181,832 +2007,Wal,80,F,12618,1169 +2007,Wal,81,M,6726,699 +2007,Wal,81,F,12467,1098 +2007,Wal,82,M,6015,652 +2007,Wal,82,F,11542,962 +2007,Wal,83,M,5160,565 +2007,Wal,83,F,10722,897 +2007,Wal,84,M,4563,465 +2007,Wal,84,F,9947,793 +2007,Wal,85,M,4012,370 +2007,Wal,85,F,9335,655 +2007,Wal,86,M,3321,264 +2007,Wal,86,F,8312,621 +2007,Wal,87,M,2066,154 +2007,Wal,87,F,5474,379 +2007,Wal,88,M,1150,85 +2007,Wal,88,F,3306,195 +2007,Wal,89,M,885,66 +2007,Wal,89,F,2802,183 +2007,Wal,90,M,827,58 +2007,Wal,90,F,2540,158 +2007,Wal,91,M,695,44 +2007,Wal,91,F,2648,179 +2007,Wal,92,M,662,49 +2007,Wal,92,F,2562,152 +2007,Wal,93,M,484,27 +2007,Wal,93,F,1871,125 +2007,Wal,94,M,291,32 +2007,Wal,94,F,1453,104 +2007,Wal,95,M,177,14 +2007,Wal,95,F,995,64 +2007,Wal,96,M,136,9 +2007,Wal,96,F,719,60 +2007,Wal,97,M,82,4 +2007,Wal,97,F,500,39 +2007,Wal,98,M,44,3 +2007,Wal,98,F,338,18 +2007,Wal,99,M,27,1 +2007,Wal,99,F,227,11 +2007,Wal,100,M,13,0 +2007,Wal,100,F,137,9 +2007,Wal,101,M,11,2 +2007,Wal,101,F,86,4 +2007,Wal,102,M,1,0 +2007,Wal,102,F,42,2 +2007,Wal,103,M,2,0 +2007,Wal,103,F,32,3 +2007,Wal,104,M,1,0 +2007,Wal,104,F,13,1 +2007,Wal,105,M,0,0 +2007,Wal,105,F,7,1 +2007,Wal,106,M,0,0 +2007,Wal,106,F,2,1 +2007,Wal,107,M,0,0 +2007,Wal,107,F,3,0 +2007,Wal,108,M,0,0 +2007,Wal,108,F,0,0 +2007,Wal,109,M,0,0 +2007,Wal,109,F,0,0 +2007,Wal,110,M,0,0 +2007,Wal,110,F,0,0 +2007,Wal,111,M,0,0 +2007,Wal,111,F,0,0 +2007,Wal,112,M,0,0 +2007,Wal,112,F,0,0 +2007,Wal,113,M,0,0 +2007,Wal,113,F,0,0 +2007,Wal,114,M,0,0 +2007,Wal,114,F,0,0 +2007,Wal,115,M,0,0 +2007,Wal,115,F,0,0 +2007,Wal,116,M,0,0 +2007,Wal,116,F,0,0 +2007,Wal,117,M,0,0 +2007,Wal,117,F,0,0 +2007,Wal,118,M,0,0 +2007,Wal,118,F,0,0 +2007,Wal,119,M,0,0 +2007,Wal,119,F,0,0 +2007,Wal,120,M,0,0 +2007,Wal,120,F,0,0 +2008,BruCap,0,M,6370,1911 +2008,BruCap,0,F,6029,1862 +2008,BruCap,1,M,6438,1837 +2008,BruCap,1,F,6087,1735 +2008,BruCap,2,M,5989,1726 +2008,BruCap,2,F,5810,1646 +2008,BruCap,3,M,5834,1619 +2008,BruCap,3,F,5570,1545 +2008,BruCap,4,M,5426,1511 +2008,BruCap,4,F,5321,1421 +2008,BruCap,5,M,5209,1364 +2008,BruCap,5,F,5119,1357 +2008,BruCap,6,M,5259,1331 +2008,BruCap,6,F,5151,1279 +2008,BruCap,7,M,5089,1302 +2008,BruCap,7,F,4774,1240 +2008,BruCap,8,M,4954,1249 +2008,BruCap,8,F,4751,1185 +2008,BruCap,9,M,4742,1201 +2008,BruCap,9,F,4613,1198 +2008,BruCap,10,M,4856,1188 +2008,BruCap,10,F,4510,1173 +2008,BruCap,11,M,4628,1213 +2008,BruCap,11,F,4514,1165 +2008,BruCap,12,M,4597,1208 +2008,BruCap,12,F,4361,1114 +2008,BruCap,13,M,4715,1137 +2008,BruCap,13,F,4317,1085 +2008,BruCap,14,M,4617,1159 +2008,BruCap,14,F,4454,1074 +2008,BruCap,15,M,4654,1156 +2008,BruCap,15,F,4469,1094 +2008,BruCap,16,M,4676,1150 +2008,BruCap,16,F,4569,1051 +2008,BruCap,17,M,4681,1165 +2008,BruCap,17,F,4492,1124 +2008,BruCap,18,M,4648,1201 +2008,BruCap,18,F,4578,1274 +2008,BruCap,19,M,4712,1350 +2008,BruCap,19,F,4543,1562 +2008,BruCap,20,M,4590,1507 +2008,BruCap,20,F,4657,1991 +2008,BruCap,21,M,4638,1657 +2008,BruCap,21,F,4632,2280 +2008,BruCap,22,M,4597,1818 +2008,BruCap,22,F,4498,2619 +2008,BruCap,23,M,4704,2146 +2008,BruCap,23,F,4941,2959 +2008,BruCap,24,M,4806,2322 +2008,BruCap,24,F,5036,3196 +2008,BruCap,25,M,5103,2804 +2008,BruCap,25,F,5443,3532 +2008,BruCap,26,M,5439,3025 +2008,BruCap,26,F,5681,3783 +2008,BruCap,27,M,5629,3469 +2008,BruCap,27,F,5820,4136 +2008,BruCap,28,M,5628,3619 +2008,BruCap,28,F,5620,4155 +2008,BruCap,29,M,5480,3816 +2008,BruCap,29,F,5609,4028 +2008,BruCap,30,M,5454,3867 +2008,BruCap,30,F,5500,3975 +2008,BruCap,31,M,5331,4038 +2008,BruCap,31,F,5324,3847 +2008,BruCap,32,M,5249,3826 +2008,BruCap,32,F,4978,3814 +2008,BruCap,33,M,5260,3805 +2008,BruCap,33,F,4941,3738 +2008,BruCap,34,M,5287,3792 +2008,BruCap,34,F,5079,3541 +2008,BruCap,35,M,5271,3761 +2008,BruCap,35,F,4978,3493 +2008,BruCap,36,M,5298,3638 +2008,BruCap,36,F,4950,3287 +2008,BruCap,37,M,5285,3740 +2008,BruCap,37,F,5016,3212 +2008,BruCap,38,M,5151,3482 +2008,BruCap,38,F,4845,3147 +2008,BruCap,39,M,5067,3425 +2008,BruCap,39,F,4634,2897 +2008,BruCap,40,M,4900,3193 +2008,BruCap,40,F,4615,2703 +2008,BruCap,41,M,4848,3100 +2008,BruCap,41,F,4771,2594 +2008,BruCap,42,M,5074,2884 +2008,BruCap,42,F,4839,2480 +2008,BruCap,43,M,5070,2884 +2008,BruCap,43,F,4886,2435 +2008,BruCap,44,M,4843,2590 +2008,BruCap,44,F,4787,2251 +2008,BruCap,45,M,4712,2466 +2008,BruCap,45,F,4762,2089 +2008,BruCap,46,M,4597,2351 +2008,BruCap,46,F,4741,2030 +2008,BruCap,47,M,4770,2224 +2008,BruCap,47,F,5001,2005 +2008,BruCap,48,M,4630,2095 +2008,BruCap,48,F,4847,1905 +2008,BruCap,49,M,4445,1998 +2008,BruCap,49,F,4834,1728 +2008,BruCap,50,M,4349,1773 +2008,BruCap,50,F,4731,1680 +2008,BruCap,51,M,4254,1825 +2008,BruCap,51,F,4735,1642 +2008,BruCap,52,M,4304,1737 +2008,BruCap,52,F,4724,1549 +2008,BruCap,53,M,4187,1572 +2008,BruCap,53,F,4649,1484 +2008,BruCap,54,M,4228,1451 +2008,BruCap,54,F,4601,1433 +2008,BruCap,55,M,4191,1469 +2008,BruCap,55,F,4601,1451 +2008,BruCap,56,M,3910,1275 +2008,BruCap,56,F,4281,1288 +2008,BruCap,57,M,3869,1419 +2008,BruCap,57,F,4449,1374 +2008,BruCap,58,M,3807,1275 +2008,BruCap,58,F,4300,1257 +2008,BruCap,59,M,3769,1260 +2008,BruCap,59,F,4299,1221 +2008,BruCap,60,M,3724,1213 +2008,BruCap,60,F,4392,1172 +2008,BruCap,61,M,3670,1121 +2008,BruCap,61,F,4220,1135 +2008,BruCap,62,M,3110,920 +2008,BruCap,62,F,3757,1023 +2008,BruCap,63,M,3290,931 +2008,BruCap,63,F,3812,981 +2008,BruCap,64,M,3039,856 +2008,BruCap,64,F,3607,899 +2008,BruCap,65,M,2680,818 +2008,BruCap,65,F,3146,832 +2008,BruCap,66,M,2264,707 +2008,BruCap,66,F,2756,751 +2008,BruCap,67,M,2598,779 +2008,BruCap,67,F,3186,959 +2008,BruCap,68,M,2569,728 +2008,BruCap,68,F,3337,792 +2008,BruCap,69,M,2576,707 +2008,BruCap,69,F,3281,778 +2008,BruCap,70,M,2447,642 +2008,BruCap,70,F,3147,735 +2008,BruCap,71,M,2382,598 +2008,BruCap,71,F,3189,775 +2008,BruCap,72,M,2321,560 +2008,BruCap,72,F,3212,738 +2008,BruCap,73,M,2367,527 +2008,BruCap,73,F,3197,677 +2008,BruCap,74,M,2246,482 +2008,BruCap,74,F,3321,586 +2008,BruCap,75,M,2283,494 +2008,BruCap,75,F,3423,564 +2008,BruCap,76,M,2230,419 +2008,BruCap,76,F,3394,531 +2008,BruCap,77,M,2114,446 +2008,BruCap,77,F,3641,615 +2008,BruCap,78,M,1971,368 +2008,BruCap,78,F,3444,414 +2008,BruCap,79,M,1940,308 +2008,BruCap,79,F,3352,447 +2008,BruCap,80,M,1797,253 +2008,BruCap,80,F,3243,385 +2008,BruCap,81,M,1687,248 +2008,BruCap,81,F,3275,338 +2008,BruCap,82,M,1552,192 +2008,BruCap,82,F,3166,284 +2008,BruCap,83,M,1564,165 +2008,BruCap,83,F,3116,286 +2008,BruCap,84,M,1325,142 +2008,BruCap,84,F,3062,239 +2008,BruCap,85,M,1218,144 +2008,BruCap,85,F,2842,196 +2008,BruCap,86,M,1155,109 +2008,BruCap,86,F,2617,166 +2008,BruCap,87,M,930,84 +2008,BruCap,87,F,2382,194 +2008,BruCap,88,M,609,56 +2008,BruCap,88,F,1550,112 +2008,BruCap,89,M,337,41 +2008,BruCap,89,F,1022,86 +2008,BruCap,90,M,284,22 +2008,BruCap,90,F,853,77 +2008,BruCap,91,M,206,17 +2008,BruCap,91,F,829,67 +2008,BruCap,92,M,209,19 +2008,BruCap,92,F,801,51 +2008,BruCap,93,M,209,18 +2008,BruCap,93,F,793,53 +2008,BruCap,94,M,132,8 +2008,BruCap,94,F,579,35 +2008,BruCap,95,M,97,9 +2008,BruCap,95,F,450,34 +2008,BruCap,96,M,70,9 +2008,BruCap,96,F,292,24 +2008,BruCap,97,M,48,5 +2008,BruCap,97,F,250,18 +2008,BruCap,98,M,24,1 +2008,BruCap,98,F,148,16 +2008,BruCap,99,M,11,1 +2008,BruCap,99,F,105,10 +2008,BruCap,100,M,3,1 +2008,BruCap,100,F,66,1 +2008,BruCap,101,M,5,0 +2008,BruCap,101,F,47,3 +2008,BruCap,102,M,4,0 +2008,BruCap,102,F,22,1 +2008,BruCap,103,M,4,0 +2008,BruCap,103,F,21,3 +2008,BruCap,104,M,0,0 +2008,BruCap,104,F,9,0 +2008,BruCap,105,M,0,0 +2008,BruCap,105,F,3,2 +2008,BruCap,106,M,0,0 +2008,BruCap,106,F,3,1 +2008,BruCap,107,M,0,0 +2008,BruCap,107,F,0,0 +2008,BruCap,108,M,0,0 +2008,BruCap,108,F,0,0 +2008,BruCap,109,M,0,0 +2008,BruCap,109,F,2,0 +2008,BruCap,110,M,0,0 +2008,BruCap,110,F,0,0 +2008,BruCap,111,M,0,0 +2008,BruCap,111,F,0,0 +2008,BruCap,112,M,0,0 +2008,BruCap,112,F,0,0 +2008,BruCap,113,M,0,0 +2008,BruCap,113,F,0,0 +2008,BruCap,114,M,0,0 +2008,BruCap,114,F,0,0 +2008,BruCap,115,M,0,0 +2008,BruCap,115,F,0,0 +2008,BruCap,116,M,0,0 +2008,BruCap,116,F,0,0 +2008,BruCap,117,M,0,0 +2008,BruCap,117,F,0,0 +2008,BruCap,118,M,0,0 +2008,BruCap,118,F,0,0 +2008,BruCap,119,M,0,0 +2008,BruCap,119,F,0,0 +2008,BruCap,120,M,0,0 +2008,BruCap,120,F,0,0 +2008,Fla,0,M,31377,2150 +2008,Fla,0,F,30194,2140 +2008,Fla,1,M,31862,2180 +2008,Fla,1,F,30650,2038 +2008,Fla,2,M,31783,2020 +2008,Fla,2,F,29962,1893 +2008,Fla,3,M,31287,1999 +2008,Fla,3,F,29613,1960 +2008,Fla,4,M,30182,1979 +2008,Fla,4,F,28890,1813 +2008,Fla,5,M,30259,1851 +2008,Fla,5,F,28710,1802 +2008,Fla,6,M,30584,1822 +2008,Fla,6,F,29344,1727 +2008,Fla,7,M,31357,1856 +2008,Fla,7,F,30065,1805 +2008,Fla,8,M,31329,1743 +2008,Fla,8,F,30324,1711 +2008,Fla,9,M,32251,1732 +2008,Fla,9,F,30666,1688 +2008,Fla,10,M,32869,1757 +2008,Fla,10,F,31593,1759 +2008,Fla,11,M,32971,1691 +2008,Fla,11,F,31785,1621 +2008,Fla,12,M,33169,1639 +2008,Fla,12,F,31833,1591 +2008,Fla,13,M,33600,1771 +2008,Fla,13,F,31928,1558 +2008,Fla,14,M,34955,1588 +2008,Fla,14,F,33799,1588 +2008,Fla,15,M,36184,1657 +2008,Fla,15,F,34735,1571 +2008,Fla,16,M,36739,1655 +2008,Fla,16,F,34861,1540 +2008,Fla,17,M,36287,1686 +2008,Fla,17,F,34622,1591 +2008,Fla,18,M,35101,1685 +2008,Fla,18,F,33392,1729 +2008,Fla,19,M,34637,1776 +2008,Fla,19,F,33137,1981 +2008,Fla,20,M,34259,1786 +2008,Fla,20,F,32461,2265 +2008,Fla,21,M,34167,1919 +2008,Fla,21,F,32408,2637 +2008,Fla,22,M,33059,2200 +2008,Fla,22,F,31875,3023 +2008,Fla,23,M,33690,2477 +2008,Fla,23,F,32482,3204 +2008,Fla,24,M,34430,2674 +2008,Fla,24,F,33466,3460 +2008,Fla,25,M,35252,3025 +2008,Fla,25,F,33650,3599 +2008,Fla,26,M,36326,3232 +2008,Fla,26,F,34572,3613 +2008,Fla,27,M,35639,3448 +2008,Fla,27,F,34998,3855 +2008,Fla,28,M,36134,3491 +2008,Fla,28,F,34716,3712 +2008,Fla,29,M,35304,3496 +2008,Fla,29,F,34677,3682 +2008,Fla,30,M,34625,3607 +2008,Fla,30,F,34224,3636 +2008,Fla,31,M,34095,3653 +2008,Fla,31,F,33220,3589 +2008,Fla,32,M,33320,3659 +2008,Fla,32,F,32501,3567 +2008,Fla,33,M,34688,3769 +2008,Fla,33,F,34149,3482 +2008,Fla,34,M,36093,3704 +2008,Fla,34,F,35227,3493 +2008,Fla,35,M,37745,3815 +2008,Fla,35,F,37313,3669 +2008,Fla,36,M,39466,3758 +2008,Fla,36,F,39271,3548 +2008,Fla,37,M,40727,4003 +2008,Fla,37,F,39983,3698 +2008,Fla,38,M,40850,3856 +2008,Fla,38,F,40047,3443 +2008,Fla,39,M,41233,3900 +2008,Fla,39,F,40503,3425 +2008,Fla,40,M,42736,3593 +2008,Fla,40,F,41138,3244 +2008,Fla,41,M,44047,3792 +2008,Fla,41,F,43010,3260 +2008,Fla,42,M,45490,3667 +2008,Fla,42,F,44317,3131 +2008,Fla,43,M,47216,3650 +2008,Fla,43,F,46465,3022 +2008,Fla,44,M,47027,3372 +2008,Fla,44,F,45926,2679 +2008,Fla,45,M,46380,3213 +2008,Fla,45,F,45179,2651 +2008,Fla,46,M,45836,3042 +2008,Fla,46,F,45488,2436 +2008,Fla,47,M,44964,3048 +2008,Fla,47,F,44356,2431 +2008,Fla,48,M,45530,2769 +2008,Fla,48,F,44929,2280 +2008,Fla,49,M,44591,2877 +2008,Fla,49,F,43702,2034 +2008,Fla,50,M,43887,2607 +2008,Fla,50,F,42890,1983 +2008,Fla,51,M,42513,2492 +2008,Fla,51,F,42331,1876 +2008,Fla,52,M,41783,2463 +2008,Fla,52,F,41782,1805 +2008,Fla,53,M,40811,2387 +2008,Fla,53,F,40539,1781 +2008,Fla,54,M,39835,2215 +2008,Fla,54,F,39099,1698 +2008,Fla,55,M,39666,2171 +2008,Fla,55,F,38794,1661 +2008,Fla,56,M,37688,2148 +2008,Fla,56,F,37254,1570 +2008,Fla,57,M,37052,2063 +2008,Fla,57,F,37115,1648 +2008,Fla,58,M,37051,2177 +2008,Fla,58,F,36660,1577 +2008,Fla,59,M,36827,2076 +2008,Fla,59,F,37078,1545 +2008,Fla,60,M,36251,2000 +2008,Fla,60,F,36596,1568 +2008,Fla,61,M,36938,1986 +2008,Fla,61,F,37074,1427 +2008,Fla,62,M,32488,1642 +2008,Fla,62,F,33247,1258 +2008,Fla,63,M,32017,1606 +2008,Fla,63,F,32986,1344 +2008,Fla,64,M,30380,1567 +2008,Fla,64,F,31570,1199 +2008,Fla,65,M,26324,1408 +2008,Fla,65,F,27488,1132 +2008,Fla,66,M,23408,1338 +2008,Fla,66,F,25109,1037 +2008,Fla,67,M,25514,1327 +2008,Fla,67,F,27797,1230 +2008,Fla,68,M,27732,1239 +2008,Fla,68,F,30810,1014 +2008,Fla,69,M,28280,1216 +2008,Fla,69,F,31313,979 +2008,Fla,70,M,27011,1070 +2008,Fla,70,F,30047,951 +2008,Fla,71,M,25577,1015 +2008,Fla,71,F,29199,911 +2008,Fla,72,M,24861,977 +2008,Fla,72,F,28951,799 +2008,Fla,73,M,24392,872 +2008,Fla,73,F,29211,817 +2008,Fla,74,M,23594,866 +2008,Fla,74,F,28751,760 +2008,Fla,75,M,23274,769 +2008,Fla,75,F,29462,687 +2008,Fla,76,M,22362,719 +2008,Fla,76,F,28972,564 +2008,Fla,77,M,21023,670 +2008,Fla,77,F,28194,666 +2008,Fla,78,M,18416,558 +2008,Fla,78,F,25656,535 +2008,Fla,79,M,16918,511 +2008,Fla,79,F,24417,556 +2008,Fla,80,M,15336,420 +2008,Fla,80,F,22694,465 +2008,Fla,81,M,13915,360 +2008,Fla,81,F,22029,455 +2008,Fla,82,M,13007,379 +2008,Fla,82,F,20827,405 +2008,Fla,83,M,11425,309 +2008,Fla,83,F,19134,364 +2008,Fla,84,M,9973,272 +2008,Fla,84,F,18033,352 +2008,Fla,85,M,8506,234 +2008,Fla,85,F,15732,261 +2008,Fla,86,M,7200,181 +2008,Fla,86,F,14322,232 +2008,Fla,87,M,5937,150 +2008,Fla,87,F,12455,213 +2008,Fla,88,M,3796,90 +2008,Fla,88,F,8382,116 +2008,Fla,89,M,2044,64 +2008,Fla,89,F,5155,100 +2008,Fla,90,M,1614,42 +2008,Fla,90,F,4231,89 +2008,Fla,91,M,1443,39 +2008,Fla,91,F,4102,68 +2008,Fla,92,M,1395,34 +2008,Fla,92,F,3931,58 +2008,Fla,93,M,1100,23 +2008,Fla,93,F,3690,57 +2008,Fla,94,M,760,16 +2008,Fla,94,F,2892,41 +2008,Fla,95,M,529,6 +2008,Fla,95,F,2164,44 +2008,Fla,96,M,345,8 +2008,Fla,96,F,1470,17 +2008,Fla,97,M,213,5 +2008,Fla,97,F,984,13 +2008,Fla,98,M,129,6 +2008,Fla,98,F,669,11 +2008,Fla,99,M,97,2 +2008,Fla,99,F,491,9 +2008,Fla,100,M,47,1 +2008,Fla,100,F,294,4 +2008,Fla,101,M,16,0 +2008,Fla,101,F,157,5 +2008,Fla,102,M,11,1 +2008,Fla,102,F,112,3 +2008,Fla,103,M,9,1 +2008,Fla,103,F,53,1 +2008,Fla,104,M,0,1 +2008,Fla,104,F,28,2 +2008,Fla,105,M,2,0 +2008,Fla,105,F,12,1 +2008,Fla,106,M,0,0 +2008,Fla,106,F,8,0 +2008,Fla,107,M,1,0 +2008,Fla,107,F,2,0 +2008,Fla,108,M,0,0 +2008,Fla,108,F,3,0 +2008,Fla,109,M,0,0 +2008,Fla,109,F,1,0 +2008,Fla,110,M,0,0 +2008,Fla,110,F,0,0 +2008,Fla,111,M,0,0 +2008,Fla,111,F,0,0 +2008,Fla,112,M,0,0 +2008,Fla,112,F,0,1 +2008,Fla,113,M,0,0 +2008,Fla,113,F,0,0 +2008,Fla,114,M,0,0 +2008,Fla,114,F,0,0 +2008,Fla,115,M,0,0 +2008,Fla,115,F,0,0 +2008,Fla,116,M,0,0 +2008,Fla,116,F,0,0 +2008,Fla,117,M,0,0 +2008,Fla,117,F,0,0 +2008,Fla,118,M,0,0 +2008,Fla,118,F,0,0 +2008,Fla,119,M,0,0 +2008,Fla,119,F,0,0 +2008,Fla,120,M,0,0 +2008,Fla,120,F,0,0 +2008,Wal,0,M,19075,980 +2008,Wal,0,F,18041,877 +2008,Wal,1,M,19527,1006 +2008,Wal,1,F,18917,928 +2008,Wal,2,M,19467,947 +2008,Wal,2,F,18697,891 +2008,Wal,3,M,19549,902 +2008,Wal,3,F,18505,936 +2008,Wal,4,M,19245,994 +2008,Wal,4,F,18708,877 +2008,Wal,5,M,19474,987 +2008,Wal,5,F,18479,933 +2008,Wal,6,M,20111,966 +2008,Wal,6,F,19349,918 +2008,Wal,7,M,20476,999 +2008,Wal,7,F,19491,984 +2008,Wal,8,M,19957,976 +2008,Wal,8,F,18989,1009 +2008,Wal,9,M,19958,1007 +2008,Wal,9,F,19045,1007 +2008,Wal,10,M,20021,1049 +2008,Wal,10,F,19214,1016 +2008,Wal,11,M,20231,1093 +2008,Wal,11,F,19345,985 +2008,Wal,12,M,19759,1090 +2008,Wal,12,F,18971,970 +2008,Wal,13,M,19958,1136 +2008,Wal,13,F,19019,1048 +2008,Wal,14,M,20787,1067 +2008,Wal,14,F,19641,1069 +2008,Wal,15,M,21793,1149 +2008,Wal,15,F,20825,1148 +2008,Wal,16,M,22286,1225 +2008,Wal,16,F,21442,1158 +2008,Wal,17,M,21966,1262 +2008,Wal,17,F,21072,1317 +2008,Wal,18,M,22006,1299 +2008,Wal,18,F,20996,1445 +2008,Wal,19,M,21728,1356 +2008,Wal,19,F,20654,1473 +2008,Wal,20,M,20905,1399 +2008,Wal,20,F,19988,1568 +2008,Wal,21,M,20793,1483 +2008,Wal,21,F,19832,1729 +2008,Wal,22,M,19809,1550 +2008,Wal,22,F,19064,2012 +2008,Wal,23,M,19373,1688 +2008,Wal,23,F,18721,2111 +2008,Wal,24,M,19107,1871 +2008,Wal,24,F,17834,2143 +2008,Wal,25,M,18979,1981 +2008,Wal,25,F,18321,2381 +2008,Wal,26,M,18876,2088 +2008,Wal,26,F,18532,2448 +2008,Wal,27,M,18767,2322 +2008,Wal,27,F,18467,2485 +2008,Wal,28,M,18485,2400 +2008,Wal,28,F,17889,2496 +2008,Wal,29,M,18203,2475 +2008,Wal,29,F,17868,2489 +2008,Wal,30,M,18386,2457 +2008,Wal,30,F,18021,2553 +2008,Wal,31,M,18530,2583 +2008,Wal,31,F,18614,2430 +2008,Wal,32,M,18795,2531 +2008,Wal,32,F,18841,2591 +2008,Wal,33,M,19535,2823 +2008,Wal,33,F,19483,2683 +2008,Wal,34,M,20524,3040 +2008,Wal,34,F,20459,2775 +2008,Wal,35,M,21294,3093 +2008,Wal,35,F,21274,2937 +2008,Wal,36,M,21584,3146 +2008,Wal,36,F,21753,2856 +2008,Wal,37,M,21399,3077 +2008,Wal,37,F,21142,2968 +2008,Wal,38,M,21256,3111 +2008,Wal,38,F,21290,2886 +2008,Wal,39,M,20815,3041 +2008,Wal,39,F,21175,2983 +2008,Wal,40,M,21275,3131 +2008,Wal,40,F,21430,2854 +2008,Wal,41,M,21653,3410 +2008,Wal,41,F,21916,3097 +2008,Wal,42,M,22475,3449 +2008,Wal,42,F,22645,2908 +2008,Wal,43,M,23169,3265 +2008,Wal,43,F,23452,2988 +2008,Wal,44,M,22700,3273 +2008,Wal,44,F,23261,2886 +2008,Wal,45,M,22063,3141 +2008,Wal,45,F,22805,2609 +2008,Wal,46,M,22597,3109 +2008,Wal,46,F,23314,2661 +2008,Wal,47,M,22464,3389 +2008,Wal,47,F,22885,2604 +2008,Wal,48,M,22456,3178 +2008,Wal,48,F,23609,2474 +2008,Wal,49,M,22007,3130 +2008,Wal,49,F,23124,2430 +2008,Wal,50,M,21618,3088 +2008,Wal,50,F,22611,2323 +2008,Wal,51,M,21044,3149 +2008,Wal,51,F,22344,2351 +2008,Wal,52,M,20734,3041 +2008,Wal,52,F,22202,2296 +2008,Wal,53,M,20672,2990 +2008,Wal,53,F,21929,2248 +2008,Wal,54,M,20419,2855 +2008,Wal,54,F,21576,2103 +2008,Wal,55,M,20053,2829 +2008,Wal,55,F,21206,2114 +2008,Wal,56,M,19383,2651 +2008,Wal,56,F,20824,2093 +2008,Wal,57,M,20042,2673 +2008,Wal,57,F,20886,2129 +2008,Wal,58,M,19804,2590 +2008,Wal,58,F,20880,1942 +2008,Wal,59,M,20137,2614 +2008,Wal,59,F,21425,2114 +2008,Wal,60,M,19827,2570 +2008,Wal,60,F,21102,1947 +2008,Wal,61,M,19210,2387 +2008,Wal,61,F,20963,1781 +2008,Wal,62,M,14199,1876 +2008,Wal,62,F,16000,1521 +2008,Wal,63,M,14054,1883 +2008,Wal,63,F,15601,1536 +2008,Wal,64,M,12961,1661 +2008,Wal,64,F,14632,1390 +2008,Wal,65,M,11246,1550 +2008,Wal,65,F,12761,1363 +2008,Wal,66,M,10294,1493 +2008,Wal,66,F,12011,1313 +2008,Wal,67,M,11427,1649 +2008,Wal,67,F,13371,1570 +2008,Wal,68,M,12198,1555 +2008,Wal,68,F,14647,1560 +2008,Wal,69,M,12020,1398 +2008,Wal,69,F,14775,1580 +2008,Wal,70,M,11414,1425 +2008,Wal,70,F,13873,1420 +2008,Wal,71,M,10800,1325 +2008,Wal,71,F,13764,1397 +2008,Wal,72,M,10304,1293 +2008,Wal,72,F,13444,1429 +2008,Wal,73,M,10560,1244 +2008,Wal,73,F,13831,1458 +2008,Wal,74,M,10307,1168 +2008,Wal,74,F,13768,1432 +2008,Wal,75,M,10387,1152 +2008,Wal,75,F,14769,1328 +2008,Wal,76,M,10245,1027 +2008,Wal,76,F,14768,1346 +2008,Wal,77,M,9555,1072 +2008,Wal,77,F,14648,1365 +2008,Wal,78,M,8553,961 +2008,Wal,78,F,13488,1247 +2008,Wal,79,M,7907,861 +2008,Wal,79,F,13186,1164 +2008,Wal,80,M,7311,816 +2008,Wal,80,F,12457,1124 +2008,Wal,81,M,6626,756 +2008,Wal,81,F,12046,1126 +2008,Wal,82,M,6141,631 +2008,Wal,82,F,11795,1042 +2008,Wal,83,M,5460,588 +2008,Wal,83,F,10838,904 +2008,Wal,84,M,4619,513 +2008,Wal,84,F,9954,813 +2008,Wal,85,M,4016,386 +2008,Wal,85,F,9202,735 +2008,Wal,86,M,3481,316 +2008,Wal,86,F,8492,603 +2008,Wal,87,M,2829,222 +2008,Wal,87,F,7462,558 +2008,Wal,88,M,1761,133 +2008,Wal,88,F,4816,331 +2008,Wal,89,M,972,77 +2008,Wal,89,F,2842,189 +2008,Wal,90,M,753,54 +2008,Wal,90,F,2436,157 +2008,Wal,91,M,650,47 +2008,Wal,91,F,2101,137 +2008,Wal,92,M,535,30 +2008,Wal,92,F,2173,144 +2008,Wal,93,M,497,37 +2008,Wal,93,F,2076,123 +2008,Wal,94,M,358,19 +2008,Wal,94,F,1448,106 +2008,Wal,95,M,198,24 +2008,Wal,95,F,1116,76 +2008,Wal,96,M,125,6 +2008,Wal,96,F,780,53 +2008,Wal,97,M,88,5 +2008,Wal,97,F,508,42 +2008,Wal,98,M,59,4 +2008,Wal,98,F,361,29 +2008,Wal,99,M,32,2 +2008,Wal,99,F,232,14 +2008,Wal,100,M,20,0 +2008,Wal,100,F,156,7 +2008,Wal,101,M,5,0 +2008,Wal,101,F,80,7 +2008,Wal,102,M,9,2 +2008,Wal,102,F,54,4 +2008,Wal,103,M,0,0 +2008,Wal,103,F,26,1 +2008,Wal,104,M,1,0 +2008,Wal,104,F,15,4 +2008,Wal,105,M,0,0 +2008,Wal,105,F,4,0 +2008,Wal,106,M,0,0 +2008,Wal,106,F,4,0 +2008,Wal,107,M,0,0 +2008,Wal,107,F,2,0 +2008,Wal,108,M,0,0 +2008,Wal,108,F,2,0 +2008,Wal,109,M,0,0 +2008,Wal,109,F,0,0 +2008,Wal,110,M,0,0 +2008,Wal,110,F,0,0 +2008,Wal,111,M,0,0 +2008,Wal,111,F,0,0 +2008,Wal,112,M,0,0 +2008,Wal,112,F,0,0 +2008,Wal,113,M,0,0 +2008,Wal,113,F,0,0 +2008,Wal,114,M,0,0 +2008,Wal,114,F,0,0 +2008,Wal,115,M,0,0 +2008,Wal,115,F,0,0 +2008,Wal,116,M,0,0 +2008,Wal,116,F,0,0 +2008,Wal,117,M,0,0 +2008,Wal,117,F,0,0 +2008,Wal,118,M,0,0 +2008,Wal,118,F,0,0 +2008,Wal,119,M,0,0 +2008,Wal,119,F,0,0 +2008,Wal,120,M,0,0 +2008,Wal,120,F,0,0 +2009,BruCap,0,M,6541,2118 +2009,BruCap,0,F,6180,2114 +2009,BruCap,1,M,6354,2039 +2009,BruCap,1,F,6019,1946 +2009,BruCap,2,M,6294,1871 +2009,BruCap,2,F,5957,1768 +2009,BruCap,3,M,5914,1725 +2009,BruCap,3,F,5730,1658 +2009,BruCap,4,M,5774,1594 +2009,BruCap,4,F,5530,1596 +2009,BruCap,5,M,5345,1543 +2009,BruCap,5,F,5226,1469 +2009,BruCap,6,M,5136,1403 +2009,BruCap,6,F,4993,1402 +2009,BruCap,7,M,5171,1366 +2009,BruCap,7,F,5087,1291 +2009,BruCap,8,M,5040,1330 +2009,BruCap,8,F,4762,1275 +2009,BruCap,9,M,4901,1304 +2009,BruCap,9,F,4737,1231 +2009,BruCap,10,M,4714,1211 +2009,BruCap,10,F,4566,1226 +2009,BruCap,11,M,4852,1239 +2009,BruCap,11,F,4473,1212 +2009,BruCap,12,M,4620,1213 +2009,BruCap,12,F,4495,1204 +2009,BruCap,13,M,4618,1206 +2009,BruCap,13,F,4359,1138 +2009,BruCap,14,M,4719,1186 +2009,BruCap,14,F,4299,1112 +2009,BruCap,15,M,4614,1142 +2009,BruCap,15,F,4470,1117 +2009,BruCap,16,M,4705,1154 +2009,BruCap,16,F,4500,1102 +2009,BruCap,17,M,4696,1207 +2009,BruCap,17,F,4604,1107 +2009,BruCap,18,M,4713,1297 +2009,BruCap,18,F,4579,1330 +2009,BruCap,19,M,4708,1433 +2009,BruCap,19,F,4662,1675 +2009,BruCap,20,M,4802,1613 +2009,BruCap,20,F,4625,2047 +2009,BruCap,21,M,4673,1794 +2009,BruCap,21,F,4738,2508 +2009,BruCap,22,M,4677,1923 +2009,BruCap,22,F,4727,2717 +2009,BruCap,23,M,4732,2211 +2009,BruCap,23,F,4696,3133 +2009,BruCap,24,M,4924,2598 +2009,BruCap,24,F,5215,3510 +2009,BruCap,25,M,4968,2783 +2009,BruCap,25,F,5334,3686 +2009,BruCap,26,M,5311,3317 +2009,BruCap,26,F,5637,4027 +2009,BruCap,27,M,5499,3486 +2009,BruCap,27,F,5750,4188 +2009,BruCap,28,M,5724,3945 +2009,BruCap,28,F,5861,4529 +2009,BruCap,29,M,5645,3984 +2009,BruCap,29,F,5583,4474 +2009,BruCap,30,M,5491,4132 +2009,BruCap,30,F,5563,4300 +2009,BruCap,31,M,5425,4123 +2009,BruCap,31,F,5453,4070 +2009,BruCap,32,M,5261,4241 +2009,BruCap,32,F,5277,4034 +2009,BruCap,33,M,5213,3980 +2009,BruCap,33,F,4980,3948 +2009,BruCap,34,M,5235,3936 +2009,BruCap,34,F,4904,3805 +2009,BruCap,35,M,5331,3928 +2009,BruCap,35,F,5055,3608 +2009,BruCap,36,M,5235,3824 +2009,BruCap,36,F,4955,3584 +2009,BruCap,37,M,5281,3654 +2009,BruCap,37,F,4932,3301 +2009,BruCap,38,M,5299,3769 +2009,BruCap,38,F,4991,3200 +2009,BruCap,39,M,5127,3567 +2009,BruCap,39,F,4829,3116 +2009,BruCap,40,M,5037,3474 +2009,BruCap,40,F,4628,2894 +2009,BruCap,41,M,4889,3206 +2009,BruCap,41,F,4600,2715 +2009,BruCap,42,M,4838,3132 +2009,BruCap,42,F,4781,2616 +2009,BruCap,43,M,5044,2945 +2009,BruCap,43,F,4846,2449 +2009,BruCap,44,M,5030,2899 +2009,BruCap,44,F,4885,2422 +2009,BruCap,45,M,4818,2602 +2009,BruCap,45,F,4786,2263 +2009,BruCap,46,M,4696,2481 +2009,BruCap,46,F,4734,2119 +2009,BruCap,47,M,4554,2320 +2009,BruCap,47,F,4748,2035 +2009,BruCap,48,M,4721,2214 +2009,BruCap,48,F,5029,1965 +2009,BruCap,49,M,4621,2075 +2009,BruCap,49,F,4857,1870 +2009,BruCap,50,M,4429,2003 +2009,BruCap,50,F,4824,1722 +2009,BruCap,51,M,4298,1790 +2009,BruCap,51,F,4717,1679 +2009,BruCap,52,M,4227,1838 +2009,BruCap,52,F,4724,1625 +2009,BruCap,53,M,4242,1743 +2009,BruCap,53,F,4707,1528 +2009,BruCap,54,M,4134,1573 +2009,BruCap,54,F,4622,1513 +2009,BruCap,55,M,4164,1452 +2009,BruCap,55,F,4603,1384 +2009,BruCap,56,M,4104,1447 +2009,BruCap,56,F,4562,1465 +2009,BruCap,57,M,3835,1277 +2009,BruCap,57,F,4245,1298 +2009,BruCap,58,M,3824,1378 +2009,BruCap,58,F,4411,1365 +2009,BruCap,59,M,3749,1272 +2009,BruCap,59,F,4262,1241 +2009,BruCap,60,M,3696,1231 +2009,BruCap,60,F,4234,1180 +2009,BruCap,61,M,3636,1159 +2009,BruCap,61,F,4330,1150 +2009,BruCap,62,M,3601,1079 +2009,BruCap,62,F,4162,1104 +2009,BruCap,63,M,3033,902 +2009,BruCap,63,F,3716,985 +2009,BruCap,64,M,3218,895 +2009,BruCap,64,F,3762,974 +2009,BruCap,65,M,2964,808 +2009,BruCap,65,F,3554,865 +2009,BruCap,66,M,2618,771 +2009,BruCap,66,F,3126,807 +2009,BruCap,67,M,2198,673 +2009,BruCap,67,F,2726,718 +2009,BruCap,68,M,2551,747 +2009,BruCap,68,F,3161,918 +2009,BruCap,69,M,2494,706 +2009,BruCap,69,F,3297,776 +2009,BruCap,70,M,2501,680 +2009,BruCap,70,F,3223,753 +2009,BruCap,71,M,2369,609 +2009,BruCap,71,F,3117,710 +2009,BruCap,72,M,2315,568 +2009,BruCap,72,F,3118,748 +2009,BruCap,73,M,2239,526 +2009,BruCap,73,F,3159,714 +2009,BruCap,74,M,2269,501 +2009,BruCap,74,F,3149,650 +2009,BruCap,75,M,2170,441 +2009,BruCap,75,F,3240,566 +2009,BruCap,76,M,2193,459 +2009,BruCap,76,F,3334,534 +2009,BruCap,77,M,2114,386 +2009,BruCap,77,F,3276,500 +2009,BruCap,78,M,2005,399 +2009,BruCap,78,F,3523,587 +2009,BruCap,79,M,1843,347 +2009,BruCap,79,F,3316,401 +2009,BruCap,80,M,1806,278 +2009,BruCap,80,F,3189,416 +2009,BruCap,81,M,1675,230 +2009,BruCap,81,F,3110,367 +2009,BruCap,82,M,1549,225 +2009,BruCap,82,F,3108,309 +2009,BruCap,83,M,1412,177 +2009,BruCap,83,F,2968,265 +2009,BruCap,84,M,1408,150 +2009,BruCap,84,F,2899,260 +2009,BruCap,85,M,1138,129 +2009,BruCap,85,F,2804,218 +2009,BruCap,86,M,1077,128 +2009,BruCap,86,F,2577,177 +2009,BruCap,87,M,1025,94 +2009,BruCap,87,F,2361,153 +2009,BruCap,88,M,795,66 +2009,BruCap,88,F,2101,177 +2009,BruCap,89,M,498,44 +2009,BruCap,89,F,1355,105 +2009,BruCap,90,M,272,30 +2009,BruCap,90,F,886,70 +2009,BruCap,91,M,236,20 +2009,BruCap,91,F,721,64 +2009,BruCap,92,M,165,15 +2009,BruCap,92,F,657,59 +2009,BruCap,93,M,151,17 +2009,BruCap,93,F,650,42 +2009,BruCap,94,M,153,13 +2009,BruCap,94,F,631,49 +2009,BruCap,95,M,101,7 +2009,BruCap,95,F,445,25 +2009,BruCap,96,M,66,7 +2009,BruCap,96,F,318,27 +2009,BruCap,97,M,50,9 +2009,BruCap,97,F,199,20 +2009,BruCap,98,M,36,4 +2009,BruCap,98,F,182,14 +2009,BruCap,99,M,16,1 +2009,BruCap,99,F,101,16 +2009,BruCap,100,M,7,1 +2009,BruCap,100,F,72,9 +2009,BruCap,101,M,3,1 +2009,BruCap,101,F,42,0 +2009,BruCap,102,M,3,0 +2009,BruCap,102,F,31,2 +2009,BruCap,103,M,0,0 +2009,BruCap,103,F,14,1 +2009,BruCap,104,M,2,0 +2009,BruCap,104,F,12,1 +2009,BruCap,105,M,0,0 +2009,BruCap,105,F,4,0 +2009,BruCap,106,M,0,0 +2009,BruCap,106,F,1,1 +2009,BruCap,107,M,0,0 +2009,BruCap,107,F,2,1 +2009,BruCap,108,M,0,0 +2009,BruCap,108,F,0,0 +2009,BruCap,109,M,0,0 +2009,BruCap,109,F,0,0 +2009,BruCap,110,M,0,0 +2009,BruCap,110,F,1,0 +2009,BruCap,111,M,0,0 +2009,BruCap,111,F,0,0 +2009,BruCap,112,M,0,0 +2009,BruCap,112,F,0,0 +2009,BruCap,113,M,0,0 +2009,BruCap,113,F,0,0 +2009,BruCap,114,M,0,0 +2009,BruCap,114,F,0,0 +2009,BruCap,115,M,0,0 +2009,BruCap,115,F,0,0 +2009,BruCap,116,M,0,0 +2009,BruCap,116,F,0,0 +2009,BruCap,117,M,0,0 +2009,BruCap,117,F,0,0 +2009,BruCap,118,M,0,0 +2009,BruCap,118,F,0,0 +2009,BruCap,119,M,0,0 +2009,BruCap,119,F,0,0 +2009,BruCap,120,M,0,0 +2009,BruCap,120,F,0,0 +2009,Fla,0,M,33090,2505 +2009,Fla,0,F,31536,2341 +2009,Fla,1,M,32270,2343 +2009,Fla,1,F,31066,2348 +2009,Fla,2,M,32199,2272 +2009,Fla,2,F,30897,2184 +2009,Fla,3,M,31977,2189 +2009,Fla,3,F,30178,2029 +2009,Fla,4,M,31479,2114 +2009,Fla,4,F,29762,2103 +2009,Fla,5,M,30388,2081 +2009,Fla,5,F,29037,1927 +2009,Fla,6,M,30384,1973 +2009,Fla,6,F,28930,1899 +2009,Fla,7,M,30724,1892 +2009,Fla,7,F,29458,1835 +2009,Fla,8,M,31501,2008 +2009,Fla,8,F,30219,1909 +2009,Fla,9,M,31429,1887 +2009,Fla,9,F,30432,1844 +2009,Fla,10,M,32381,1878 +2009,Fla,10,F,30816,1801 +2009,Fla,11,M,33006,1893 +2009,Fla,11,F,31771,1805 +2009,Fla,12,M,33110,1718 +2009,Fla,12,F,31911,1690 +2009,Fla,13,M,33283,1728 +2009,Fla,13,F,31964,1659 +2009,Fla,14,M,33718,1862 +2009,Fla,14,F,32062,1630 +2009,Fla,15,M,35096,1661 +2009,Fla,15,F,33884,1661 +2009,Fla,16,M,36292,1726 +2009,Fla,16,F,34833,1672 +2009,Fla,17,M,36853,1753 +2009,Fla,17,F,34958,1656 +2009,Fla,18,M,36377,1859 +2009,Fla,18,F,34693,1759 +2009,Fla,19,M,35136,1801 +2009,Fla,19,F,33447,2013 +2009,Fla,20,M,34617,2050 +2009,Fla,20,F,33249,2418 +2009,Fla,21,M,34282,2175 +2009,Fla,21,F,32546,2842 +2009,Fla,22,M,34187,2396 +2009,Fla,22,F,32530,3256 +2009,Fla,23,M,32997,2790 +2009,Fla,23,F,31945,3591 +2009,Fla,24,M,33581,3057 +2009,Fla,24,F,32483,3774 +2009,Fla,25,M,34431,3195 +2009,Fla,25,F,33487,3947 +2009,Fla,26,M,35186,3564 +2009,Fla,26,F,33795,4059 +2009,Fla,27,M,36321,3643 +2009,Fla,27,F,34643,3919 +2009,Fla,28,M,35663,3921 +2009,Fla,28,F,35152,4207 +2009,Fla,29,M,36252,3905 +2009,Fla,29,F,34915,4075 +2009,Fla,30,M,35408,3909 +2009,Fla,30,F,34875,3992 +2009,Fla,31,M,34756,3926 +2009,Fla,31,F,34433,3874 +2009,Fla,32,M,34184,4016 +2009,Fla,32,F,33464,3824 +2009,Fla,33,M,33443,3938 +2009,Fla,33,F,32776,3734 +2009,Fla,34,M,34822,4031 +2009,Fla,34,F,34379,3689 +2009,Fla,35,M,36186,3885 +2009,Fla,35,F,35424,3624 +2009,Fla,36,M,37880,4078 +2009,Fla,36,F,37505,3784 +2009,Fla,37,M,39572,3978 +2009,Fla,37,F,39462,3630 +2009,Fla,38,M,40846,4198 +2009,Fla,38,F,40151,3814 +2009,Fla,39,M,40956,4108 +2009,Fla,39,F,40186,3549 +2009,Fla,40,M,41315,4075 +2009,Fla,40,F,40617,3505 +2009,Fla,41,M,42774,3755 +2009,Fla,41,F,41243,3320 +2009,Fla,42,M,44085,3870 +2009,Fla,42,F,43116,3309 +2009,Fla,43,M,45495,3825 +2009,Fla,43,F,44366,3187 +2009,Fla,44,M,47267,3758 +2009,Fla,44,F,46521,3059 +2009,Fla,45,M,46960,3487 +2009,Fla,45,F,45960,2740 +2009,Fla,46,M,46359,3319 +2009,Fla,46,F,45245,2655 +2009,Fla,47,M,45823,3159 +2009,Fla,47,F,45483,2463 +2009,Fla,48,M,44930,3134 +2009,Fla,48,F,44390,2439 +2009,Fla,49,M,45466,2873 +2009,Fla,49,F,44877,2296 +2009,Fla,50,M,44517,2900 +2009,Fla,50,F,43693,2052 +2009,Fla,51,M,43787,2673 +2009,Fla,51,F,42865,2015 +2009,Fla,52,M,42375,2530 +2009,Fla,52,F,42266,1892 +2009,Fla,53,M,41649,2494 +2009,Fla,53,F,41697,1848 +2009,Fla,54,M,40663,2436 +2009,Fla,54,F,40461,1820 +2009,Fla,55,M,39693,2218 +2009,Fla,55,F,38973,1712 +2009,Fla,56,M,39425,2167 +2009,Fla,56,F,38667,1659 +2009,Fla,57,M,37455,2132 +2009,Fla,57,F,37135,1558 +2009,Fla,58,M,36792,2056 +2009,Fla,58,F,37000,1653 +2009,Fla,59,M,36782,2158 +2009,Fla,59,F,36535,1586 +2009,Fla,60,M,36495,2062 +2009,Fla,60,F,36927,1552 +2009,Fla,61,M,35927,1956 +2009,Fla,61,F,36442,1561 +2009,Fla,62,M,36535,1962 +2009,Fla,62,F,36898,1424 +2009,Fla,63,M,32134,1631 +2009,Fla,63,F,33106,1245 +2009,Fla,64,M,31633,1573 +2009,Fla,64,F,32780,1328 +2009,Fla,65,M,29975,1566 +2009,Fla,65,F,31383,1177 +2009,Fla,66,M,25941,1404 +2009,Fla,66,F,27302,1127 +2009,Fla,67,M,23059,1300 +2009,Fla,67,F,24918,1024 +2009,Fla,68,M,25086,1288 +2009,Fla,68,F,27581,1214 +2009,Fla,69,M,27246,1202 +2009,Fla,69,F,30545,1007 +2009,Fla,70,M,27741,1184 +2009,Fla,70,F,30986,981 +2009,Fla,71,M,26460,1055 +2009,Fla,71,F,29714,933 +2009,Fla,72,M,24921,970 +2009,Fla,72,F,28827,877 +2009,Fla,73,M,24199,935 +2009,Fla,73,F,28561,773 +2009,Fla,74,M,23653,837 +2009,Fla,74,F,28745,796 +2009,Fla,75,M,22792,835 +2009,Fla,75,F,28254,739 +2009,Fla,76,M,22400,734 +2009,Fla,76,F,28837,669 +2009,Fla,77,M,21377,691 +2009,Fla,77,F,28285,538 +2009,Fla,78,M,19968,630 +2009,Fla,78,F,27417,624 +2009,Fla,79,M,17364,518 +2009,Fla,79,F,24886,509 +2009,Fla,80,M,15883,461 +2009,Fla,80,F,23466,529 +2009,Fla,81,M,14309,379 +2009,Fla,81,F,21747,434 +2009,Fla,82,M,12852,330 +2009,Fla,82,F,20924,426 +2009,Fla,83,M,11861,350 +2009,Fla,83,F,19634,376 +2009,Fla,84,M,10282,268 +2009,Fla,84,F,17911,339 +2009,Fla,85,M,8903,233 +2009,Fla,85,F,16724,327 +2009,Fla,86,M,7492,199 +2009,Fla,86,F,14370,232 +2009,Fla,87,M,6207,159 +2009,Fla,87,F,12897,210 +2009,Fla,88,M,5049,129 +2009,Fla,88,F,11063,183 +2009,Fla,89,M,3160,75 +2009,Fla,89,F,7286,99 +2009,Fla,90,M,1655,52 +2009,Fla,90,F,4400,84 +2009,Fla,91,M,1308,31 +2009,Fla,91,F,3572,77 +2009,Fla,92,M,1092,29 +2009,Fla,92,F,3410,59 +2009,Fla,93,M,1063,26 +2009,Fla,93,F,3131,50 +2009,Fla,94,M,797,14 +2009,Fla,94,F,2869,47 +2009,Fla,95,M,534,14 +2009,Fla,95,F,2180,36 +2009,Fla,96,M,365,6 +2009,Fla,96,F,1590,33 +2009,Fla,97,M,226,5 +2009,Fla,97,F,1090,9 +2009,Fla,98,M,134,4 +2009,Fla,98,F,706,11 +2009,Fla,99,M,84,4 +2009,Fla,99,F,456,7 +2009,Fla,100,M,58,1 +2009,Fla,100,F,312,4 +2009,Fla,101,M,25,1 +2009,Fla,101,F,181,3 +2009,Fla,102,M,9,0 +2009,Fla,102,F,74,1 +2009,Fla,103,M,6,1 +2009,Fla,103,F,78,2 +2009,Fla,104,M,4,0 +2009,Fla,104,F,32,0 +2009,Fla,105,M,0,0 +2009,Fla,105,F,19,1 +2009,Fla,106,M,0,0 +2009,Fla,106,F,7,1 +2009,Fla,107,M,0,0 +2009,Fla,107,F,6,0 +2009,Fla,108,M,1,0 +2009,Fla,108,F,1,0 +2009,Fla,109,M,0,0 +2009,Fla,109,F,0,0 +2009,Fla,110,M,0,0 +2009,Fla,110,F,1,0 +2009,Fla,111,M,0,0 +2009,Fla,111,F,0,0 +2009,Fla,112,M,0,0 +2009,Fla,112,F,0,0 +2009,Fla,113,M,0,0 +2009,Fla,113,F,0,0 +2009,Fla,114,M,0,0 +2009,Fla,114,F,0,0 +2009,Fla,115,M,0,0 +2009,Fla,115,F,0,0 +2009,Fla,116,M,0,0 +2009,Fla,116,F,0,0 +2009,Fla,117,M,0,0 +2009,Fla,117,F,0,0 +2009,Fla,118,M,0,0 +2009,Fla,118,F,0,0 +2009,Fla,119,M,0,0 +2009,Fla,119,F,0,0 +2009,Fla,120,M,0,0 +2009,Fla,120,F,0,0 +2009,Wal,0,M,19654,1081 +2009,Wal,0,F,18507,977 +2009,Wal,1,M,19710,1010 +2009,Wal,1,F,18618,952 +2009,Wal,2,M,19772,1001 +2009,Wal,2,F,19135,939 +2009,Wal,3,M,19655,979 +2009,Wal,3,F,18879,914 +2009,Wal,4,M,19663,902 +2009,Wal,4,F,18653,932 +2009,Wal,5,M,19404,994 +2009,Wal,5,F,18837,907 +2009,Wal,6,M,19595,996 +2009,Wal,6,F,18601,947 +2009,Wal,7,M,20208,983 +2009,Wal,7,F,19463,931 +2009,Wal,8,M,20609,1014 +2009,Wal,8,F,19559,1018 +2009,Wal,9,M,20046,1028 +2009,Wal,9,F,19066,1026 +2009,Wal,10,M,20057,1005 +2009,Wal,10,F,19172,1002 +2009,Wal,11,M,20118,1079 +2009,Wal,11,F,19301,1017 +2009,Wal,12,M,20356,1094 +2009,Wal,12,F,19446,1009 +2009,Wal,13,M,19850,1100 +2009,Wal,13,F,19058,986 +2009,Wal,14,M,20033,1139 +2009,Wal,14,F,19130,1038 +2009,Wal,15,M,20900,1067 +2009,Wal,15,F,19742,1087 +2009,Wal,16,M,21857,1163 +2009,Wal,16,F,20891,1181 +2009,Wal,17,M,22385,1250 +2009,Wal,17,F,21529,1222 +2009,Wal,18,M,22015,1323 +2009,Wal,18,F,21170,1417 +2009,Wal,19,M,22035,1346 +2009,Wal,19,F,21049,1472 +2009,Wal,20,M,21723,1405 +2009,Wal,20,F,20662,1618 +2009,Wal,21,M,20868,1493 +2009,Wal,21,F,19990,1849 +2009,Wal,22,M,20742,1593 +2009,Wal,22,F,19778,1964 +2009,Wal,23,M,19663,1719 +2009,Wal,23,F,18937,2167 +2009,Wal,24,M,19198,1861 +2009,Wal,24,F,18572,2309 +2009,Wal,25,M,18900,2046 +2009,Wal,25,F,17720,2228 +2009,Wal,26,M,18826,2169 +2009,Wal,26,F,18224,2522 +2009,Wal,27,M,18763,2244 +2009,Wal,27,F,18620,2540 +2009,Wal,28,M,18800,2397 +2009,Wal,28,F,18607,2655 +2009,Wal,29,M,18534,2602 +2009,Wal,29,F,18008,2572 +2009,Wal,30,M,18283,2618 +2009,Wal,30,F,18028,2600 +2009,Wal,31,M,18473,2576 +2009,Wal,31,F,18229,2684 +2009,Wal,32,M,18697,2597 +2009,Wal,32,F,18810,2493 +2009,Wal,33,M,18946,2641 +2009,Wal,33,F,19035,2595 +2009,Wal,34,M,19763,2884 +2009,Wal,34,F,19636,2718 +2009,Wal,35,M,20627,3079 +2009,Wal,35,F,20621,2820 +2009,Wal,36,M,21468,3096 +2009,Wal,36,F,21417,2932 +2009,Wal,37,M,21741,3153 +2009,Wal,37,F,21913,2834 +2009,Wal,38,M,21466,3120 +2009,Wal,38,F,21330,2939 +2009,Wal,39,M,21336,3117 +2009,Wal,39,F,21422,2901 +2009,Wal,40,M,20885,3048 +2009,Wal,40,F,21288,2978 +2009,Wal,41,M,21367,3119 +2009,Wal,41,F,21526,2830 +2009,Wal,42,M,21715,3393 +2009,Wal,42,F,21997,3052 +2009,Wal,43,M,22513,3425 +2009,Wal,43,F,22728,2925 +2009,Wal,44,M,23195,3245 +2009,Wal,44,F,23560,2937 +2009,Wal,45,M,22738,3278 +2009,Wal,45,F,23318,2855 +2009,Wal,46,M,22051,3126 +2009,Wal,46,F,22840,2581 +2009,Wal,47,M,22556,3112 +2009,Wal,47,F,23338,2646 +2009,Wal,48,M,22434,3341 +2009,Wal,48,F,22902,2591 +2009,Wal,49,M,22395,3132 +2009,Wal,49,F,23620,2436 +2009,Wal,50,M,21934,3106 +2009,Wal,50,F,23094,2400 +2009,Wal,51,M,21577,3047 +2009,Wal,51,F,22598,2322 +2009,Wal,52,M,20966,3127 +2009,Wal,52,F,22329,2320 +2009,Wal,53,M,20654,3003 +2009,Wal,53,F,22209,2292 +2009,Wal,54,M,20559,2946 +2009,Wal,54,F,21877,2228 +2009,Wal,55,M,20314,2819 +2009,Wal,55,F,21548,2102 +2009,Wal,56,M,19925,2812 +2009,Wal,56,F,21147,2108 +2009,Wal,57,M,19219,2635 +2009,Wal,57,F,20758,2066 +2009,Wal,58,M,19852,2625 +2009,Wal,58,F,20798,2112 +2009,Wal,59,M,19611,2547 +2009,Wal,59,F,20792,1924 +2009,Wal,60,M,19882,2560 +2009,Wal,60,F,21319,2091 +2009,Wal,61,M,19577,2516 +2009,Wal,61,F,20974,1941 +2009,Wal,62,M,18957,2346 +2009,Wal,62,F,20820,1779 +2009,Wal,63,M,13972,1856 +2009,Wal,63,F,15873,1509 +2009,Wal,64,M,13805,1847 +2009,Wal,64,F,15472,1513 +2009,Wal,65,M,12722,1619 +2009,Wal,65,F,14501,1378 +2009,Wal,66,M,11016,1513 +2009,Wal,66,F,12670,1337 +2009,Wal,67,M,10072,1451 +2009,Wal,67,F,11885,1304 +2009,Wal,68,M,11189,1612 +2009,Wal,68,F,13230,1547 +2009,Wal,69,M,11884,1508 +2009,Wal,69,F,14468,1536 +2009,Wal,70,M,11710,1341 +2009,Wal,70,F,14580,1549 +2009,Wal,71,M,11094,1386 +2009,Wal,71,F,13663,1394 +2009,Wal,72,M,10473,1261 +2009,Wal,72,F,13548,1381 +2009,Wal,73,M,9991,1232 +2009,Wal,73,F,13215,1405 +2009,Wal,74,M,10143,1170 +2009,Wal,74,F,13568,1438 +2009,Wal,75,M,9864,1101 +2009,Wal,75,F,13459,1403 +2009,Wal,76,M,9919,1086 +2009,Wal,76,F,14400,1305 +2009,Wal,77,M,9713,977 +2009,Wal,77,F,14342,1305 +2009,Wal,78,M,9044,998 +2009,Wal,78,F,14160,1315 +2009,Wal,79,M,7997,885 +2009,Wal,79,F,13017,1205 +2009,Wal,80,M,7325,773 +2009,Wal,80,F,12628,1101 +2009,Wal,81,M,6743,742 +2009,Wal,81,F,11874,1080 +2009,Wal,82,M,6055,684 +2009,Wal,82,F,11335,1069 +2009,Wal,83,M,5554,564 +2009,Wal,83,F,11071,979 +2009,Wal,84,M,4846,535 +2009,Wal,84,F,10056,847 +2009,Wal,85,M,4076,446 +2009,Wal,85,F,9122,754 +2009,Wal,86,M,3473,323 +2009,Wal,86,F,8334,674 +2009,Wal,87,M,2963,262 +2009,Wal,87,F,7597,549 +2009,Wal,88,M,2355,191 +2009,Wal,88,F,6552,490 +2009,Wal,89,M,1437,109 +2009,Wal,89,F,4169,308 +2009,Wal,90,M,768,58 +2009,Wal,90,F,2463,158 +2009,Wal,91,M,593,40 +2009,Wal,91,F,2038,132 +2009,Wal,92,M,516,36 +2009,Wal,92,F,1694,125 +2009,Wal,93,M,389,27 +2009,Wal,93,F,1746,123 +2009,Wal,94,M,359,27 +2009,Wal,94,F,1572,96 +2009,Wal,95,M,256,11 +2009,Wal,95,F,1096,81 +2009,Wal,96,M,116,14 +2009,Wal,96,F,791,54 +2009,Wal,97,M,76,4 +2009,Wal,97,F,551,40 +2009,Wal,98,M,60,4 +2009,Wal,98,F,361,33 +2009,Wal,99,M,33,3 +2009,Wal,99,F,238,17 +2009,Wal,100,M,22,2 +2009,Wal,100,F,155,13 +2009,Wal,101,M,11,0 +2009,Wal,101,F,97,3 +2009,Wal,102,M,4,0 +2009,Wal,102,F,54,1 +2009,Wal,103,M,7,1 +2009,Wal,103,F,37,3 +2009,Wal,104,M,0,0 +2009,Wal,104,F,11,1 +2009,Wal,105,M,0,0 +2009,Wal,105,F,4,2 +2009,Wal,106,M,0,0 +2009,Wal,106,F,2,0 +2009,Wal,107,M,0,0 +2009,Wal,107,F,2,1 +2009,Wal,108,M,0,1 +2009,Wal,108,F,2,1 +2009,Wal,109,M,0,0 +2009,Wal,109,F,2,0 +2009,Wal,110,M,0,0 +2009,Wal,110,F,0,0 +2009,Wal,111,M,0,0 +2009,Wal,111,F,0,0 +2009,Wal,112,M,0,0 +2009,Wal,112,F,0,0 +2009,Wal,113,M,0,0 +2009,Wal,113,F,0,0 +2009,Wal,114,M,0,0 +2009,Wal,114,F,0,0 +2009,Wal,115,M,0,0 +2009,Wal,115,F,0,0 +2009,Wal,116,M,0,0 +2009,Wal,116,F,0,0 +2009,Wal,117,M,0,0 +2009,Wal,117,F,0,0 +2009,Wal,118,M,0,0 +2009,Wal,118,F,0,0 +2009,Wal,119,M,0,0 +2009,Wal,119,F,0,0 +2009,Wal,120,M,0,0 +2009,Wal,120,F,0,0 +2010,BruCap,0,M,6730,2326 +2010,BruCap,0,F,6411,2267 +2010,BruCap,1,M,6425,2201 +2010,BruCap,1,F,6086,2202 +2010,BruCap,2,M,6214,2092 +2010,BruCap,2,F,5921,1986 +2010,BruCap,3,M,6152,1929 +2010,BruCap,3,F,5841,1803 +2010,BruCap,4,M,5854,1762 +2010,BruCap,4,F,5636,1725 +2010,BruCap,5,M,5669,1632 +2010,BruCap,5,F,5438,1620 +2010,BruCap,6,M,5293,1595 +2010,BruCap,6,F,5133,1509 +2010,BruCap,7,M,5074,1438 +2010,BruCap,7,F,4948,1427 +2010,BruCap,8,M,5050,1410 +2010,BruCap,8,F,5032,1337 +2010,BruCap,9,M,5012,1411 +2010,BruCap,9,F,4704,1306 +2010,BruCap,10,M,4881,1363 +2010,BruCap,10,F,4667,1279 +2010,BruCap,11,M,4672,1281 +2010,BruCap,11,F,4503,1275 +2010,BruCap,12,M,4816,1279 +2010,BruCap,12,F,4440,1230 +2010,BruCap,13,M,4616,1273 +2010,BruCap,13,F,4470,1266 +2010,BruCap,14,M,4580,1248 +2010,BruCap,14,F,4355,1162 +2010,BruCap,15,M,4711,1247 +2010,BruCap,15,F,4300,1151 +2010,BruCap,16,M,4635,1164 +2010,BruCap,16,F,4479,1174 +2010,BruCap,17,M,4737,1175 +2010,BruCap,17,F,4549,1163 +2010,BruCap,18,M,4748,1376 +2010,BruCap,18,F,4690,1294 +2010,BruCap,19,M,4747,1563 +2010,BruCap,19,F,4668,1706 +2010,BruCap,20,M,4759,1710 +2010,BruCap,20,F,4726,2128 +2010,BruCap,21,M,4866,1822 +2010,BruCap,21,F,4717,2526 +2010,BruCap,22,M,4720,2062 +2010,BruCap,22,F,4890,2912 +2010,BruCap,23,M,4806,2229 +2010,BruCap,23,F,4868,3219 +2010,BruCap,24,M,4876,2580 +2010,BruCap,24,F,4975,3546 +2010,BruCap,25,M,5075,3067 +2010,BruCap,25,F,5488,4038 +2010,BruCap,26,M,5191,3188 +2010,BruCap,26,F,5535,4107 +2010,BruCap,27,M,5403,3737 +2010,BruCap,27,F,5652,4408 +2010,BruCap,28,M,5519,3901 +2010,BruCap,28,F,5758,4463 +2010,BruCap,29,M,5660,4328 +2010,BruCap,29,F,5812,4750 +2010,BruCap,30,M,5612,4347 +2010,BruCap,30,F,5530,4669 +2010,BruCap,31,M,5446,4348 +2010,BruCap,31,F,5521,4459 +2010,BruCap,32,M,5417,4331 +2010,BruCap,32,F,5442,4250 +2010,BruCap,33,M,5241,4391 +2010,BruCap,33,F,5175,4170 +2010,BruCap,34,M,5185,4187 +2010,BruCap,34,F,4903,4002 +2010,BruCap,35,M,5169,4130 +2010,BruCap,35,F,4855,3932 +2010,BruCap,36,M,5280,4026 +2010,BruCap,36,F,4982,3647 +2010,BruCap,37,M,5212,3860 +2010,BruCap,37,F,4955,3634 +2010,BruCap,38,M,5250,3667 +2010,BruCap,38,F,4865,3314 +2010,BruCap,39,M,5267,3824 +2010,BruCap,39,F,4984,3218 +2010,BruCap,40,M,5151,3640 +2010,BruCap,40,F,4796,3147 +2010,BruCap,41,M,5040,3510 +2010,BruCap,41,F,4660,2953 +2010,BruCap,42,M,4870,3256 +2010,BruCap,42,F,4577,2715 +2010,BruCap,43,M,4839,3147 +2010,BruCap,43,F,4771,2587 +2010,BruCap,44,M,5033,2922 +2010,BruCap,44,F,4870,2474 +2010,BruCap,45,M,5009,2954 +2010,BruCap,45,F,4897,2455 +2010,BruCap,46,M,4791,2611 +2010,BruCap,46,F,4762,2309 +2010,BruCap,47,M,4682,2493 +2010,BruCap,47,F,4742,2141 +2010,BruCap,48,M,4527,2358 +2010,BruCap,48,F,4735,2106 +2010,BruCap,49,M,4693,2232 +2010,BruCap,49,F,5034,2032 +2010,BruCap,50,M,4582,2085 +2010,BruCap,50,F,4869,1928 +2010,BruCap,51,M,4391,1994 +2010,BruCap,51,F,4811,1767 +2010,BruCap,52,M,4277,1791 +2010,BruCap,52,F,4699,1719 +2010,BruCap,53,M,4188,1848 +2010,BruCap,53,F,4718,1644 +2010,BruCap,54,M,4194,1737 +2010,BruCap,54,F,4687,1596 +2010,BruCap,55,M,4089,1563 +2010,BruCap,55,F,4602,1550 +2010,BruCap,56,M,4115,1427 +2010,BruCap,56,F,4575,1411 +2010,BruCap,57,M,4054,1425 +2010,BruCap,57,F,4547,1494 +2010,BruCap,58,M,3786,1262 +2010,BruCap,58,F,4219,1298 +2010,BruCap,59,M,3809,1338 +2010,BruCap,59,F,4392,1364 +2010,BruCap,60,M,3677,1219 +2010,BruCap,60,F,4218,1224 +2010,BruCap,61,M,3635,1201 +2010,BruCap,61,F,4199,1162 +2010,BruCap,62,M,3555,1115 +2010,BruCap,62,F,4292,1129 +2010,BruCap,63,M,3514,1041 +2010,BruCap,63,F,4118,1079 +2010,BruCap,64,M,2958,866 +2010,BruCap,64,F,3673,970 +2010,BruCap,65,M,3130,825 +2010,BruCap,65,F,3697,958 +2010,BruCap,66,M,2884,774 +2010,BruCap,66,F,3503,854 +2010,BruCap,67,M,2551,749 +2010,BruCap,67,F,3104,783 +2010,BruCap,68,M,2142,642 +2010,BruCap,68,F,2716,706 +2010,BruCap,69,M,2474,719 +2010,BruCap,69,F,3127,884 +2010,BruCap,70,M,2437,661 +2010,BruCap,70,F,3259,779 +2010,BruCap,71,M,2443,643 +2010,BruCap,71,F,3172,752 +2010,BruCap,72,M,2301,591 +2010,BruCap,72,F,3073,686 +2010,BruCap,73,M,2266,538 +2010,BruCap,73,F,3050,743 +2010,BruCap,74,M,2168,498 +2010,BruCap,74,F,3122,689 +2010,BruCap,75,M,2182,477 +2010,BruCap,75,F,3077,627 +2010,BruCap,76,M,2083,427 +2010,BruCap,76,F,3157,550 +2010,BruCap,77,M,2104,434 +2010,BruCap,77,F,3256,507 +2010,BruCap,78,M,1996,357 +2010,BruCap,78,F,3159,494 +2010,BruCap,79,M,1873,364 +2010,BruCap,79,F,3406,560 +2010,BruCap,80,M,1744,325 +2010,BruCap,80,F,3145,388 +2010,BruCap,81,M,1680,255 +2010,BruCap,81,F,3039,402 +2010,BruCap,82,M,1556,197 +2010,BruCap,82,F,2936,348 +2010,BruCap,83,M,1407,196 +2010,BruCap,83,F,2905,291 +2010,BruCap,84,M,1265,158 +2010,BruCap,84,F,2790,255 +2010,BruCap,85,M,1266,134 +2010,BruCap,85,F,2677,236 +2010,BruCap,86,M,988,112 +2010,BruCap,86,F,2565,205 +2010,BruCap,87,M,928,116 +2010,BruCap,87,F,2335,161 +2010,BruCap,88,M,895,77 +2010,BruCap,88,F,2097,131 +2010,BruCap,89,M,659,59 +2010,BruCap,89,F,1862,159 +2010,BruCap,90,M,400,37 +2010,BruCap,90,F,1178,91 +2010,BruCap,91,M,207,26 +2010,BruCap,91,F,738,62 +2010,BruCap,92,M,193,18 +2010,BruCap,92,F,606,46 +2010,BruCap,93,M,130,13 +2010,BruCap,93,F,529,48 +2010,BruCap,94,M,111,8 +2010,BruCap,94,F,514,31 +2010,BruCap,95,M,111,12 +2010,BruCap,95,F,485,38 +2010,BruCap,96,M,75,5 +2010,BruCap,96,F,325,16 +2010,BruCap,97,M,36,5 +2010,BruCap,97,F,243,20 +2010,BruCap,98,M,32,6 +2010,BruCap,98,F,156,13 +2010,BruCap,99,M,25,3 +2010,BruCap,99,F,118,11 +2010,BruCap,100,M,7,0 +2010,BruCap,100,F,72,14 +2010,BruCap,101,M,6,1 +2010,BruCap,101,F,53,5 +2010,BruCap,102,M,1,1 +2010,BruCap,102,F,27,0 +2010,BruCap,103,M,2,0 +2010,BruCap,103,F,23,0 +2010,BruCap,104,M,0,0 +2010,BruCap,104,F,11,1 +2010,BruCap,105,M,2,0 +2010,BruCap,105,F,4,0 +2010,BruCap,106,M,0,0 +2010,BruCap,106,F,0,0 +2010,BruCap,107,M,0,0 +2010,BruCap,107,F,0,0 +2010,BruCap,108,M,0,0 +2010,BruCap,108,F,1,0 +2010,BruCap,109,M,0,0 +2010,BruCap,109,F,0,0 +2010,BruCap,110,M,0,0 +2010,BruCap,110,F,0,0 +2010,BruCap,111,M,0,0 +2010,BruCap,111,F,0,0 +2010,BruCap,112,M,0,0 +2010,BruCap,112,F,0,0 +2010,BruCap,113,M,0,0 +2010,BruCap,113,F,0,0 +2010,BruCap,114,M,0,0 +2010,BruCap,114,F,0,0 +2010,BruCap,115,M,0,0 +2010,BruCap,115,F,0,0 +2010,BruCap,116,M,0,0 +2010,BruCap,116,F,0,0 +2010,BruCap,117,M,0,0 +2010,BruCap,117,F,0,0 +2010,BruCap,118,M,0,0 +2010,BruCap,118,F,0,0 +2010,BruCap,119,M,0,0 +2010,BruCap,119,F,0,0 +2010,BruCap,120,M,0,0 +2010,BruCap,120,F,0,0 +2010,Fla,0,M,32705,2735 +2010,Fla,0,F,30873,2603 +2010,Fla,1,M,33421,2648 +2010,Fla,1,F,31828,2447 +2010,Fla,2,M,32558,2487 +2010,Fla,2,F,31323,2470 +2010,Fla,3,M,32472,2390 +2010,Fla,3,F,31155,2258 +2010,Fla,4,M,32185,2264 +2010,Fla,4,F,30365,2119 +2010,Fla,5,M,31674,2236 +2010,Fla,5,F,29997,2217 +2010,Fla,6,M,30582,2170 +2010,Fla,6,F,29215,2018 +2010,Fla,7,M,30528,2141 +2010,Fla,7,F,29108,2007 +2010,Fla,8,M,30915,2042 +2010,Fla,8,F,29596,1942 +2010,Fla,9,M,31641,2118 +2010,Fla,9,F,30372,2039 +2010,Fla,10,M,31570,2018 +2010,Fla,10,F,30584,1953 +2010,Fla,11,M,32496,1975 +2010,Fla,11,F,30962,1912 +2010,Fla,12,M,33148,1970 +2010,Fla,12,F,31893,1909 +2010,Fla,13,M,33234,1827 +2010,Fla,13,F,32005,1762 +2010,Fla,14,M,33380,1829 +2010,Fla,14,F,32076,1746 +2010,Fla,15,M,33808,1941 +2010,Fla,15,F,32146,1724 +2010,Fla,16,M,35194,1786 +2010,Fla,16,F,33963,1758 +2010,Fla,17,M,36385,1891 +2010,Fla,17,F,34907,1810 +2010,Fla,18,M,36929,1921 +2010,Fla,18,F,35044,1856 +2010,Fla,19,M,36417,2008 +2010,Fla,19,F,34789,1995 +2010,Fla,20,M,35163,2039 +2010,Fla,20,F,33497,2399 +2010,Fla,21,M,34643,2328 +2010,Fla,21,F,33295,2905 +2010,Fla,22,M,34252,2565 +2010,Fla,22,F,32546,3376 +2010,Fla,23,M,34174,2772 +2010,Fla,23,F,32590,3735 +2010,Fla,24,M,32983,3174 +2010,Fla,24,F,31948,4114 +2010,Fla,25,M,33570,3522 +2010,Fla,25,F,32485,4247 +2010,Fla,26,M,34346,3603 +2010,Fla,26,F,33510,4285 +2010,Fla,27,M,35190,3924 +2010,Fla,27,F,33921,4395 +2010,Fla,28,M,36385,3886 +2010,Fla,28,F,34790,4301 +2010,Fla,29,M,35723,4221 +2010,Fla,29,F,35318,4454 +2010,Fla,30,M,36318,4179 +2010,Fla,30,F,35118,4377 +2010,Fla,31,M,35542,4193 +2010,Fla,31,F,35084,4266 +2010,Fla,32,M,34872,4139 +2010,Fla,32,F,34620,4136 +2010,Fla,33,M,34322,4293 +2010,Fla,33,F,33710,3996 +2010,Fla,34,M,33569,4141 +2010,Fla,34,F,33004,3979 +2010,Fla,35,M,34994,4191 +2010,Fla,35,F,34585,3845 +2010,Fla,36,M,36344,4088 +2010,Fla,36,F,35605,3834 +2010,Fla,37,M,38025,4234 +2010,Fla,37,F,37707,3929 +2010,Fla,38,M,39728,4144 +2010,Fla,38,F,39632,3761 +2010,Fla,39,M,40893,4334 +2010,Fla,39,F,40335,3903 +2010,Fla,40,M,41012,4179 +2010,Fla,40,F,40317,3655 +2010,Fla,41,M,41403,4176 +2010,Fla,41,F,40733,3599 +2010,Fla,42,M,42816,3853 +2010,Fla,42,F,41366,3361 +2010,Fla,43,M,44138,3963 +2010,Fla,43,F,43252,3356 +2010,Fla,44,M,45559,3928 +2010,Fla,44,F,44465,3186 +2010,Fla,45,M,47224,3789 +2010,Fla,45,F,46556,3093 +2010,Fla,46,M,46967,3554 +2010,Fla,46,F,45980,2805 +2010,Fla,47,M,46327,3392 +2010,Fla,47,F,45255,2723 +2010,Fla,48,M,45753,3195 +2010,Fla,48,F,45496,2510 +2010,Fla,49,M,44886,3202 +2010,Fla,49,F,44385,2496 +2010,Fla,50,M,45360,2909 +2010,Fla,50,F,44837,2350 +2010,Fla,51,M,44384,2901 +2010,Fla,51,F,43627,2119 +2010,Fla,52,M,43594,2668 +2010,Fla,52,F,42811,2055 +2010,Fla,53,M,42243,2520 +2010,Fla,53,F,42186,1944 +2010,Fla,54,M,41455,2507 +2010,Fla,54,F,41604,1873 +2010,Fla,55,M,40499,2394 +2010,Fla,55,F,40375,1852 +2010,Fla,56,M,39478,2248 +2010,Fla,56,F,38867,1734 +2010,Fla,57,M,39182,2167 +2010,Fla,57,F,38568,1679 +2010,Fla,58,M,37191,2112 +2010,Fla,58,F,36989,1561 +2010,Fla,59,M,36530,2026 +2010,Fla,59,F,36861,1672 +2010,Fla,60,M,36470,2122 +2010,Fla,60,F,36374,1578 +2010,Fla,61,M,36175,2044 +2010,Fla,61,F,36762,1564 +2010,Fla,62,M,35551,1947 +2010,Fla,62,F,36283,1545 +2010,Fla,63,M,36154,1938 +2010,Fla,63,F,36693,1410 +2010,Fla,64,M,31783,1613 +2010,Fla,64,F,32932,1235 +2010,Fla,65,M,31208,1548 +2010,Fla,65,F,32547,1315 +2010,Fla,66,M,29560,1547 +2010,Fla,66,F,31149,1177 +2010,Fla,67,M,25581,1363 +2010,Fla,67,F,27100,1142 +2010,Fla,68,M,22679,1277 +2010,Fla,68,F,24720,1016 +2010,Fla,69,M,24643,1243 +2010,Fla,69,F,27332,1193 +2010,Fla,70,M,26665,1174 +2010,Fla,70,F,30228,981 +2010,Fla,71,M,27187,1144 +2010,Fla,71,F,30652,968 +2010,Fla,72,M,25813,1021 +2010,Fla,72,F,29313,913 +2010,Fla,73,M,24226,936 +2010,Fla,73,F,28450,861 +2010,Fla,74,M,23433,895 +2010,Fla,74,F,28135,764 +2010,Fla,75,M,22915,808 +2010,Fla,75,F,28246,775 +2010,Fla,76,M,21952,797 +2010,Fla,76,F,27700,698 +2010,Fla,77,M,21432,691 +2010,Fla,77,F,28196,652 +2010,Fla,78,M,20351,658 +2010,Fla,78,F,27556,520 +2010,Fla,79,M,18936,591 +2010,Fla,79,F,26603,607 +2010,Fla,80,M,16321,485 +2010,Fla,80,F,24018,481 +2010,Fla,81,M,14852,435 +2010,Fla,81,F,22467,496 +2010,Fla,82,M,13283,354 +2010,Fla,82,F,20796,417 +2010,Fla,83,M,11735,299 +2010,Fla,83,F,19725,401 +2010,Fla,84,M,10695,311 +2010,Fla,84,F,18371,339 +2010,Fla,85,M,9184,238 +2010,Fla,85,F,16604,310 +2010,Fla,86,M,7832,204 +2010,Fla,86,F,15288,304 +2010,Fla,87,M,6476,168 +2010,Fla,87,F,12994,214 +2010,Fla,88,M,5296,142 +2010,Fla,88,F,11500,182 +2010,Fla,89,M,4220,111 +2010,Fla,89,F,9743,159 +2010,Fla,90,M,2601,66 +2010,Fla,90,F,6257,86 +2010,Fla,91,M,1344,41 +2010,Fla,91,F,3731,76 +2010,Fla,92,M,978,27 +2010,Fla,92,F,2924,65 +2010,Fla,93,M,836,26 +2010,Fla,93,F,2724,49 +2010,Fla,94,M,783,18 +2010,Fla,94,F,2495,45 +2010,Fla,95,M,581,8 +2010,Fla,95,F,2166,43 +2010,Fla,96,M,378,11 +2010,Fla,96,F,1615,31 +2010,Fla,97,M,232,2 +2010,Fla,97,F,1140,26 +2010,Fla,98,M,150,2 +2010,Fla,98,F,781,6 +2010,Fla,99,M,88,1 +2010,Fla,99,F,486,10 +2010,Fla,100,M,49,3 +2010,Fla,100,F,310,5 +2010,Fla,101,M,38,1 +2010,Fla,101,F,194,3 +2010,Fla,102,M,15,0 +2010,Fla,102,F,113,2 +2010,Fla,103,M,7,0 +2010,Fla,103,F,49,1 +2010,Fla,104,M,4,1 +2010,Fla,104,F,51,2 +2010,Fla,105,M,1,0 +2010,Fla,105,F,18,0 +2010,Fla,106,M,0,0 +2010,Fla,106,F,7,0 +2010,Fla,107,M,0,0 +2010,Fla,107,F,3,0 +2010,Fla,108,M,0,0 +2010,Fla,108,F,4,0 +2010,Fla,109,M,1,0 +2010,Fla,109,F,0,0 +2010,Fla,110,M,0,0 +2010,Fla,110,F,0,0 +2010,Fla,111,M,0,0 +2010,Fla,111,F,1,0 +2010,Fla,112,M,0,0 +2010,Fla,112,F,0,0 +2010,Fla,113,M,0,0 +2010,Fla,113,F,0,0 +2010,Fla,114,M,0,0 +2010,Fla,114,F,0,0 +2010,Fla,115,M,0,0 +2010,Fla,115,F,0,0 +2010,Fla,116,M,0,0 +2010,Fla,116,F,0,0 +2010,Fla,117,M,0,0 +2010,Fla,117,F,0,0 +2010,Fla,118,M,0,0 +2010,Fla,118,F,0,0 +2010,Fla,119,M,0,0 +2010,Fla,119,F,0,0 +2010,Fla,120,M,0,0 +2010,Fla,120,F,0,0 +2010,Wal,0,M,19284,1145 +2010,Wal,0,F,18689,1066 +2010,Wal,1,M,19894,1127 +2010,Wal,1,F,18763,1040 +2010,Wal,2,M,19882,1076 +2010,Wal,2,F,18820,1017 +2010,Wal,3,M,19935,1037 +2010,Wal,3,F,19278,1006 +2010,Wal,4,M,19778,1046 +2010,Wal,4,F,19002,980 +2010,Wal,5,M,19780,981 +2010,Wal,5,F,18776,1007 +2010,Wal,6,M,19526,1101 +2010,Wal,6,F,18940,982 +2010,Wal,7,M,19675,1071 +2010,Wal,7,F,18655,1019 +2010,Wal,8,M,20339,1050 +2010,Wal,8,F,19539,1032 +2010,Wal,9,M,20678,1040 +2010,Wal,9,F,19634,1085 +2010,Wal,10,M,20116,1063 +2010,Wal,10,F,19150,1039 +2010,Wal,11,M,20152,1058 +2010,Wal,11,F,19246,1057 +2010,Wal,12,M,20223,1099 +2010,Wal,12,F,19404,1088 +2010,Wal,13,M,20437,1125 +2010,Wal,13,F,19554,1049 +2010,Wal,14,M,19923,1173 +2010,Wal,14,F,19107,1026 +2010,Wal,15,M,20121,1184 +2010,Wal,15,F,19226,1082 +2010,Wal,16,M,20937,1142 +2010,Wal,16,F,19816,1191 +2010,Wal,17,M,21934,1224 +2010,Wal,17,F,20961,1306 +2010,Wal,18,M,22434,1352 +2010,Wal,18,F,21597,1374 +2010,Wal,19,M,22094,1378 +2010,Wal,19,F,21227,1503 +2010,Wal,20,M,22053,1404 +2010,Wal,20,F,21062,1666 +2010,Wal,21,M,21714,1572 +2010,Wal,21,F,20672,1850 +2010,Wal,22,M,20848,1652 +2010,Wal,22,F,19973,2031 +2010,Wal,23,M,20643,1774 +2010,Wal,23,F,19707,2202 +2010,Wal,24,M,19476,1883 +2010,Wal,24,F,18791,2310 +2010,Wal,25,M,19048,2075 +2010,Wal,25,F,18429,2412 +2010,Wal,26,M,18729,2193 +2010,Wal,26,F,17644,2338 +2010,Wal,27,M,18786,2356 +2010,Wal,27,F,18275,2657 +2010,Wal,28,M,18812,2385 +2010,Wal,28,F,18722,2652 +2010,Wal,29,M,18887,2551 +2010,Wal,29,F,18808,2794 +2010,Wal,30,M,18652,2730 +2010,Wal,30,F,18212,2676 +2010,Wal,31,M,18412,2727 +2010,Wal,31,F,18184,2717 +2010,Wal,32,M,18587,2668 +2010,Wal,32,F,18435,2745 +2010,Wal,33,M,18887,2635 +2010,Wal,33,F,19022,2592 +2010,Wal,34,M,19090,2740 +2010,Wal,34,F,19193,2670 +2010,Wal,35,M,19917,2927 +2010,Wal,35,F,19825,2817 +2010,Wal,36,M,20791,3122 +2010,Wal,36,F,20778,2902 +2010,Wal,37,M,21646,3129 +2010,Wal,37,F,21538,2982 +2010,Wal,38,M,21821,3228 +2010,Wal,38,F,22061,2846 +2010,Wal,39,M,21633,3136 +2010,Wal,39,F,21473,2972 +2010,Wal,40,M,21421,3164 +2010,Wal,40,F,21552,2903 +2010,Wal,41,M,20910,3093 +2010,Wal,41,F,21397,2986 +2010,Wal,42,M,21442,3140 +2010,Wal,42,F,21625,2825 +2010,Wal,43,M,21776,3420 +2010,Wal,43,F,22055,3060 +2010,Wal,44,M,22582,3439 +2010,Wal,44,F,22782,2906 +2010,Wal,45,M,23249,3278 +2010,Wal,45,F,23650,2923 +2010,Wal,46,M,22745,3269 +2010,Wal,46,F,23397,2826 +2010,Wal,47,M,22046,3162 +2010,Wal,47,F,22898,2574 +2010,Wal,48,M,22584,3080 +2010,Wal,48,F,23343,2600 +2010,Wal,49,M,22446,3328 +2010,Wal,49,F,22932,2586 +2010,Wal,50,M,22368,3104 +2010,Wal,50,F,23630,2416 +2010,Wal,51,M,21871,3095 +2010,Wal,51,F,23086,2391 +2010,Wal,52,M,21495,3056 +2010,Wal,52,F,22584,2335 +2010,Wal,53,M,20894,3100 +2010,Wal,53,F,22312,2310 +2010,Wal,54,M,20568,2990 +2010,Wal,54,F,22178,2271 +2010,Wal,55,M,20454,2904 +2010,Wal,55,F,21829,2186 +2010,Wal,56,M,20187,2798 +2010,Wal,56,F,21485,2094 +2010,Wal,57,M,19780,2753 +2010,Wal,57,F,21092,2093 +2010,Wal,58,M,19065,2608 +2010,Wal,58,F,20721,2045 +2010,Wal,59,M,19641,2590 +2010,Wal,59,F,20718,2103 +2010,Wal,60,M,19402,2503 +2010,Wal,60,F,20715,1909 +2010,Wal,61,M,19632,2535 +2010,Wal,61,F,21205,2074 +2010,Wal,62,M,19357,2458 +2010,Wal,62,F,20849,1915 +2010,Wal,63,M,18699,2314 +2010,Wal,63,F,20681,1763 +2010,Wal,64,M,13770,1818 +2010,Wal,64,F,15754,1501 +2010,Wal,65,M,13578,1802 +2010,Wal,65,F,15338,1509 +2010,Wal,66,M,12474,1570 +2010,Wal,66,F,14366,1378 +2010,Wal,67,M,10829,1474 +2010,Wal,67,F,12540,1344 +2010,Wal,68,M,9870,1406 +2010,Wal,68,F,11715,1281 +2010,Wal,69,M,10941,1570 +2010,Wal,69,F,13087,1511 +2010,Wal,70,M,11630,1482 +2010,Wal,70,F,14297,1524 +2010,Wal,71,M,11351,1321 +2010,Wal,71,F,14364,1520 +2010,Wal,72,M,10765,1340 +2010,Wal,72,F,13462,1386 +2010,Wal,73,M,10162,1209 +2010,Wal,73,F,13285,1358 +2010,Wal,74,M,9643,1182 +2010,Wal,74,F,12990,1386 +2010,Wal,75,M,9766,1124 +2010,Wal,75,F,13264,1398 +2010,Wal,76,M,9406,1045 +2010,Wal,76,F,13125,1360 +2010,Wal,77,M,9407,1019 +2010,Wal,77,F,14040,1266 +2010,Wal,78,M,9182,925 +2010,Wal,78,F,13906,1261 +2010,Wal,79,M,8514,934 +2010,Wal,79,F,13602,1261 +2010,Wal,80,M,7451,830 +2010,Wal,80,F,12498,1158 +2010,Wal,81,M,6780,712 +2010,Wal,81,F,11996,1051 +2010,Wal,82,M,6179,681 +2010,Wal,82,F,11240,1032 +2010,Wal,83,M,5523,621 +2010,Wal,83,F,10679,999 +2010,Wal,84,M,5000,510 +2010,Wal,84,F,10302,922 +2010,Wal,85,M,4284,455 +2010,Wal,85,F,9279,789 +2010,Wal,86,M,3568,388 +2010,Wal,86,F,8277,704 +2010,Wal,87,M,2961,265 +2010,Wal,87,F,7475,614 +2010,Wal,88,M,2498,220 +2010,Wal,88,F,6739,493 +2010,Wal,89,M,1927,164 +2010,Wal,89,F,5749,434 +2010,Wal,90,M,1162,95 +2010,Wal,90,F,3607,260 +2010,Wal,91,M,636,45 +2010,Wal,91,F,2076,140 +2010,Wal,92,M,458,32 +2010,Wal,92,F,1666,118 +2010,Wal,93,M,398,24 +2010,Wal,93,F,1379,104 +2010,Wal,94,M,289,21 +2010,Wal,94,F,1371,94 +2010,Wal,95,M,252,24 +2010,Wal,95,F,1216,83 +2010,Wal,96,M,182,10 +2010,Wal,96,F,819,61 +2010,Wal,97,M,66,8 +2010,Wal,97,F,557,36 +2010,Wal,98,M,59,1 +2010,Wal,98,F,404,28 +2010,Wal,99,M,36,2 +2010,Wal,99,F,254,25 +2010,Wal,100,M,16,2 +2010,Wal,100,F,144,11 +2010,Wal,101,M,14,1 +2010,Wal,101,F,100,5 +2010,Wal,102,M,8,0 +2010,Wal,102,F,60,3 +2010,Wal,103,M,2,0 +2010,Wal,103,F,32,1 +2010,Wal,104,M,1,1 +2010,Wal,104,F,21,2 +2010,Wal,105,M,0,0 +2010,Wal,105,F,6,1 +2010,Wal,106,M,0,0 +2010,Wal,106,F,3,1 +2010,Wal,107,M,0,0 +2010,Wal,107,F,2,0 +2010,Wal,108,M,0,0 +2010,Wal,108,F,1,1 +2010,Wal,109,M,0,1 +2010,Wal,109,F,2,1 +2010,Wal,110,M,0,0 +2010,Wal,110,F,2,0 +2010,Wal,111,M,0,0 +2010,Wal,111,F,0,0 +2010,Wal,112,M,0,0 +2010,Wal,112,F,0,0 +2010,Wal,113,M,0,0 +2010,Wal,113,F,0,0 +2010,Wal,114,M,0,0 +2010,Wal,114,F,0,0 +2010,Wal,115,M,0,0 +2010,Wal,115,F,0,0 +2010,Wal,116,M,0,0 +2010,Wal,116,F,0,0 +2010,Wal,117,M,0,0 +2010,Wal,117,F,0,0 +2010,Wal,118,M,0,0 +2010,Wal,118,F,0,0 +2010,Wal,119,M,0,0 +2010,Wal,119,F,0,0 +2010,Wal,120,M,0,0 +2010,Wal,120,F,0,0 +2011,BruCap,0,M,6708,2689 +2011,BruCap,0,F,6356,2596 +2011,BruCap,1,M,6619,2476 +2011,BruCap,1,F,6320,2381 +2011,BruCap,2,M,6261,2281 +2011,BruCap,2,F,5982,2236 +2011,BruCap,3,M,6124,2192 +2011,BruCap,3,F,5818,2002 +2011,BruCap,4,M,6067,2000 +2011,BruCap,4,F,5741,1882 +2011,BruCap,5,M,5736,1847 +2011,BruCap,5,F,5554,1823 +2011,BruCap,6,M,5576,1715 +2011,BruCap,6,F,5330,1657 +2011,BruCap,7,M,5230,1707 +2011,BruCap,7,F,5015,1579 +2011,BruCap,8,M,5008,1550 +2011,BruCap,8,F,4872,1518 +2011,BruCap,9,M,5001,1522 +2011,BruCap,9,F,4949,1420 +2011,BruCap,10,M,4948,1535 +2011,BruCap,10,F,4664,1410 +2011,BruCap,11,M,4854,1448 +2011,BruCap,11,F,4654,1384 +2011,BruCap,12,M,4658,1360 +2011,BruCap,12,F,4500,1404 +2011,BruCap,13,M,4760,1366 +2011,BruCap,13,F,4434,1348 +2011,BruCap,14,M,4623,1355 +2011,BruCap,14,F,4446,1365 +2011,BruCap,15,M,4586,1322 +2011,BruCap,15,F,4358,1244 +2011,BruCap,16,M,4728,1340 +2011,BruCap,16,F,4296,1243 +2011,BruCap,17,M,4641,1295 +2011,BruCap,17,F,4479,1300 +2011,BruCap,18,M,4772,1379 +2011,BruCap,18,F,4619,1476 +2011,BruCap,19,M,4812,1684 +2011,BruCap,19,F,4798,1828 +2011,BruCap,20,M,4823,1973 +2011,BruCap,20,F,4752,2296 +2011,BruCap,21,M,4837,2041 +2011,BruCap,21,F,4831,2672 +2011,BruCap,22,M,4950,2187 +2011,BruCap,22,F,4826,3104 +2011,BruCap,23,M,4870,2472 +2011,BruCap,23,F,5076,3501 +2011,BruCap,24,M,4985,2776 +2011,BruCap,24,F,5189,3781 +2011,BruCap,25,M,5108,3186 +2011,BruCap,25,F,5205,4133 +2011,BruCap,26,M,5231,3650 +2011,BruCap,26,F,5641,4577 +2011,BruCap,27,M,5285,3712 +2011,BruCap,27,F,5601,4568 +2011,BruCap,28,M,5445,4318 +2011,BruCap,28,F,5616,4883 +2011,BruCap,29,M,5492,4323 +2011,BruCap,29,F,5721,4726 +2011,BruCap,30,M,5645,4750 +2011,BruCap,30,F,5776,5025 +2011,BruCap,31,M,5565,4680 +2011,BruCap,31,F,5440,4900 +2011,BruCap,32,M,5382,4677 +2011,BruCap,32,F,5378,4670 +2011,BruCap,33,M,5382,4629 +2011,BruCap,33,F,5371,4413 +2011,BruCap,34,M,5181,4710 +2011,BruCap,34,F,5105,4290 +2011,BruCap,35,M,5144,4415 +2011,BruCap,35,F,4846,4047 +2011,BruCap,36,M,5133,4385 +2011,BruCap,36,F,4801,4036 +2011,BruCap,37,M,5258,4214 +2011,BruCap,37,F,4946,3705 +2011,BruCap,38,M,5206,4032 +2011,BruCap,38,F,4918,3657 +2011,BruCap,39,M,5184,3822 +2011,BruCap,39,F,4839,3412 +2011,BruCap,40,M,5276,3956 +2011,BruCap,40,F,4985,3287 +2011,BruCap,41,M,5145,3750 +2011,BruCap,41,F,4771,3233 +2011,BruCap,42,M,5028,3639 +2011,BruCap,42,F,4654,3075 +2011,BruCap,43,M,4825,3387 +2011,BruCap,43,F,4568,2816 +2011,BruCap,44,M,4834,3245 +2011,BruCap,44,F,4763,2654 +2011,BruCap,45,M,4995,3020 +2011,BruCap,45,F,4869,2592 +2011,BruCap,46,M,4972,3024 +2011,BruCap,46,F,4904,2529 +2011,BruCap,47,M,4773,2689 +2011,BruCap,47,F,4755,2372 +2011,BruCap,48,M,4645,2559 +2011,BruCap,48,F,4719,2221 +2011,BruCap,49,M,4498,2447 +2011,BruCap,49,F,4730,2135 +2011,BruCap,50,M,4677,2294 +2011,BruCap,50,F,5015,2104 +2011,BruCap,51,M,4550,2131 +2011,BruCap,51,F,4860,2029 +2011,BruCap,52,M,4378,2050 +2011,BruCap,52,F,4792,1858 +2011,BruCap,53,M,4256,1844 +2011,BruCap,53,F,4684,1782 +2011,BruCap,54,M,4148,1888 +2011,BruCap,54,F,4729,1681 +2011,BruCap,55,M,4164,1757 +2011,BruCap,55,F,4663,1670 +2011,BruCap,56,M,4052,1566 +2011,BruCap,56,F,4560,1611 +2011,BruCap,57,M,4090,1420 +2011,BruCap,57,F,4552,1435 +2011,BruCap,58,M,4030,1450 +2011,BruCap,58,F,4506,1526 +2011,BruCap,59,M,3729,1259 +2011,BruCap,59,F,4197,1304 +2011,BruCap,60,M,3759,1338 +2011,BruCap,60,F,4355,1372 +2011,BruCap,61,M,3604,1194 +2011,BruCap,61,F,4167,1215 +2011,BruCap,62,M,3542,1176 +2011,BruCap,62,F,4134,1171 +2011,BruCap,63,M,3488,1080 +2011,BruCap,63,F,4268,1097 +2011,BruCap,64,M,3446,1020 +2011,BruCap,64,F,4082,1062 +2011,BruCap,65,M,2861,840 +2011,BruCap,65,F,3630,942 +2011,BruCap,66,M,3038,792 +2011,BruCap,66,F,3669,950 +2011,BruCap,67,M,2795,760 +2011,BruCap,67,F,3458,845 +2011,BruCap,68,M,2497,722 +2011,BruCap,68,F,3067,795 +2011,BruCap,69,M,2083,623 +2011,BruCap,69,F,2679,712 +2011,BruCap,70,M,2406,697 +2011,BruCap,70,F,3095,863 +2011,BruCap,71,M,2376,639 +2011,BruCap,71,F,3208,772 +2011,BruCap,72,M,2367,608 +2011,BruCap,72,F,3136,753 +2011,BruCap,73,M,2223,557 +2011,BruCap,73,F,3018,675 +2011,BruCap,74,M,2207,515 +2011,BruCap,74,F,3000,730 +2011,BruCap,75,M,2087,483 +2011,BruCap,75,F,3084,667 +2011,BruCap,76,M,2081,465 +2011,BruCap,76,F,3042,614 +2011,BruCap,77,M,1996,412 +2011,BruCap,77,F,3070,535 +2011,BruCap,78,M,2014,402 +2011,BruCap,78,F,3160,479 +2011,BruCap,79,M,1886,327 +2011,BruCap,79,F,3044,468 +2011,BruCap,80,M,1762,346 +2011,BruCap,80,F,3274,536 +2011,BruCap,81,M,1613,301 +2011,BruCap,81,F,3016,374 +2011,BruCap,82,M,1523,231 +2011,BruCap,82,F,2910,376 +2011,BruCap,83,M,1409,174 +2011,BruCap,83,F,2778,323 +2011,BruCap,84,M,1304,179 +2011,BruCap,84,F,2721,276 +2011,BruCap,85,M,1132,143 +2011,BruCap,85,F,2594,236 +2011,BruCap,86,M,1112,111 +2011,BruCap,86,F,2454,218 +2011,BruCap,87,M,834,96 +2011,BruCap,87,F,2323,191 +2011,BruCap,88,M,799,100 +2011,BruCap,88,F,2077,150 +2011,BruCap,89,M,756,64 +2011,BruCap,89,F,1828,117 +2011,BruCap,90,M,540,55 +2011,BruCap,90,F,1588,136 +2011,BruCap,91,M,319,31 +2011,BruCap,91,F,1020,81 +2011,BruCap,92,M,165,22 +2011,BruCap,92,F,610,54 +2011,BruCap,93,M,151,14 +2011,BruCap,93,F,503,40 +2011,BruCap,94,M,103,10 +2011,BruCap,94,F,432,41 +2011,BruCap,95,M,74,5 +2011,BruCap,95,F,396,24 +2011,BruCap,96,M,77,11 +2011,BruCap,96,F,372,32 +2011,BruCap,97,M,47,4 +2011,BruCap,97,F,233,14 +2011,BruCap,98,M,29,5 +2011,BruCap,98,F,179,14 +2011,BruCap,99,M,22,6 +2011,BruCap,99,F,113,11 +2011,BruCap,100,M,13,2 +2011,BruCap,100,F,80,9 +2011,BruCap,101,M,4,0 +2011,BruCap,101,F,41,10 +2011,BruCap,102,M,2,1 +2011,BruCap,102,F,31,5 +2011,BruCap,103,M,0,1 +2011,BruCap,103,F,17,0 +2011,BruCap,104,M,2,0 +2011,BruCap,104,F,11,0 +2011,BruCap,105,M,0,0 +2011,BruCap,105,F,6,0 +2011,BruCap,106,M,0,0 +2011,BruCap,106,F,1,0 +2011,BruCap,107,M,0,0 +2011,BruCap,107,F,0,0 +2011,BruCap,108,M,0,0 +2011,BruCap,108,F,0,1 +2011,BruCap,109,M,0,0 +2011,BruCap,109,F,0,0 +2011,BruCap,110,M,0,0 +2011,BruCap,110,F,0,0 +2011,BruCap,111,M,0,0 +2011,BruCap,111,F,0,0 +2011,BruCap,112,M,0,0 +2011,BruCap,112,F,0,0 +2011,BruCap,113,M,0,0 +2011,BruCap,113,F,0,0 +2011,BruCap,114,M,0,0 +2011,BruCap,114,F,0,0 +2011,BruCap,115,M,0,0 +2011,BruCap,115,F,0,0 +2011,BruCap,116,M,0,0 +2011,BruCap,116,F,0,0 +2011,BruCap,117,M,0,0 +2011,BruCap,117,F,0,0 +2011,BruCap,118,M,0,0 +2011,BruCap,118,F,0,0 +2011,BruCap,119,M,0,0 +2011,BruCap,119,F,0,0 +2011,BruCap,120,M,0,0 +2011,BruCap,120,F,0,0 +2011,Fla,0,M,32781,3084 +2011,Fla,0,F,31425,3014 +2011,Fla,1,M,33104,2865 +2011,Fla,1,F,31175,2774 +2011,Fla,2,M,33762,2801 +2011,Fla,2,F,32171,2552 +2011,Fla,3,M,32812,2657 +2011,Fla,3,F,31632,2577 +2011,Fla,4,M,32712,2511 +2011,Fla,4,F,31429,2424 +2011,Fla,5,M,32422,2441 +2011,Fla,5,F,30599,2270 +2011,Fla,6,M,31874,2341 +2011,Fla,6,F,30227,2387 +2011,Fla,7,M,30776,2317 +2011,Fla,7,F,29405,2210 +2011,Fla,8,M,30727,2292 +2011,Fla,8,F,29283,2178 +2011,Fla,9,M,31079,2174 +2011,Fla,9,F,29798,2087 +2011,Fla,10,M,31795,2321 +2011,Fla,10,F,30529,2195 +2011,Fla,11,M,31715,2154 +2011,Fla,11,F,30749,2072 +2011,Fla,12,M,32655,2070 +2011,Fla,12,F,31073,2016 +2011,Fla,13,M,33286,2073 +2011,Fla,13,F,32058,1999 +2011,Fla,14,M,33347,1969 +2011,Fla,14,F,32119,1894 +2011,Fla,15,M,33478,1942 +2011,Fla,15,F,32223,1835 +2011,Fla,16,M,33921,2064 +2011,Fla,16,F,32257,1864 +2011,Fla,17,M,35315,1952 +2011,Fla,17,F,34120,1910 +2011,Fla,18,M,36501,2082 +2011,Fla,18,F,35007,2020 +2011,Fla,19,M,36976,2090 +2011,Fla,19,F,35137,2150 +2011,Fla,20,M,36491,2283 +2011,Fla,20,F,34845,2504 +2011,Fla,21,M,35198,2409 +2011,Fla,21,F,33615,2998 +2011,Fla,22,M,34663,2855 +2011,Fla,22,F,33424,3513 +2011,Fla,23,M,34231,3093 +2011,Fla,23,F,32625,3998 +2011,Fla,24,M,34154,3364 +2011,Fla,24,F,32628,4236 +2011,Fla,25,M,32979,3720 +2011,Fla,25,F,31957,4632 +2011,Fla,26,M,33586,4065 +2011,Fla,26,F,32560,4679 +2011,Fla,27,M,34411,4191 +2011,Fla,27,F,33652,4715 +2011,Fla,28,M,35268,4406 +2011,Fla,28,F,34137,4773 +2011,Fla,29,M,36476,4316 +2011,Fla,29,F,35015,4665 +2011,Fla,30,M,35874,4671 +2011,Fla,30,F,35640,4796 +2011,Fla,31,M,36480,4559 +2011,Fla,31,F,35390,4673 +2011,Fla,32,M,35738,4588 +2011,Fla,32,F,35383,4522 +2011,Fla,33,M,35034,4498 +2011,Fla,33,F,34881,4383 +2011,Fla,34,M,34571,4670 +2011,Fla,34,F,33996,4220 +2011,Fla,35,M,33803,4463 +2011,Fla,35,F,33237,4246 +2011,Fla,36,M,35215,4498 +2011,Fla,36,F,34796,4045 +2011,Fla,37,M,36548,4345 +2011,Fla,37,F,35830,4000 +2011,Fla,38,M,38207,4484 +2011,Fla,38,F,37878,4101 +2011,Fla,39,M,39887,4403 +2011,Fla,39,F,39788,3884 +2011,Fla,40,M,41062,4549 +2011,Fla,40,F,40541,4027 +2011,Fla,41,M,41119,4343 +2011,Fla,41,F,40489,3786 +2011,Fla,42,M,41497,4383 +2011,Fla,42,F,40865,3748 +2011,Fla,43,M,42924,4038 +2011,Fla,43,F,41455,3436 +2011,Fla,44,M,44204,4114 +2011,Fla,44,F,43333,3418 +2011,Fla,45,M,45613,4036 +2011,Fla,45,F,44532,3290 +2011,Fla,46,M,47282,3908 +2011,Fla,46,F,46595,3141 +2011,Fla,47,M,46962,3644 +2011,Fla,47,F,46041,2883 +2011,Fla,48,M,46349,3495 +2011,Fla,48,F,45302,2789 +2011,Fla,49,M,45705,3273 +2011,Fla,49,F,45526,2590 +2011,Fla,50,M,44837,3237 +2011,Fla,50,F,44387,2558 +2011,Fla,51,M,45275,2936 +2011,Fla,51,F,44816,2392 +2011,Fla,52,M,44283,2964 +2011,Fla,52,F,43581,2148 +2011,Fla,53,M,43473,2711 +2011,Fla,53,F,42741,2093 +2011,Fla,54,M,42084,2559 +2011,Fla,54,F,42114,1999 +2011,Fla,55,M,41280,2525 +2011,Fla,55,F,41505,1914 +2011,Fla,56,M,40302,2403 +2011,Fla,56,F,40317,1888 +2011,Fla,57,M,39288,2259 +2011,Fla,57,F,38795,1763 +2011,Fla,58,M,38955,2139 +2011,Fla,58,F,38440,1712 +2011,Fla,59,M,36981,2104 +2011,Fla,59,F,36876,1587 +2011,Fla,60,M,36253,2018 +2011,Fla,60,F,36729,1690 +2011,Fla,61,M,36169,2122 +2011,Fla,61,F,36213,1620 +2011,Fla,62,M,35862,2018 +2011,Fla,62,F,36603,1560 +2011,Fla,63,M,35166,1942 +2011,Fla,63,F,36065,1546 +2011,Fla,64,M,35785,1909 +2011,Fla,64,F,36462,1413 +2011,Fla,65,M,31410,1563 +2011,Fla,65,F,32741,1230 +2011,Fla,66,M,30758,1518 +2011,Fla,66,F,32313,1311 +2011,Fla,67,M,29134,1508 +2011,Fla,67,F,30906,1155 +2011,Fla,68,M,25202,1309 +2011,Fla,68,F,26855,1143 +2011,Fla,69,M,22284,1226 +2011,Fla,69,F,24523,1000 +2011,Fla,70,M,24149,1212 +2011,Fla,70,F,27022,1190 +2011,Fla,71,M,26060,1142 +2011,Fla,71,F,29905,969 +2011,Fla,72,M,26506,1100 +2011,Fla,72,F,30268,957 +2011,Fla,73,M,25186,986 +2011,Fla,73,F,28911,895 +2011,Fla,74,M,23528,911 +2011,Fla,74,F,28009,835 +2011,Fla,75,M,22683,873 +2011,Fla,75,F,27605,756 +2011,Fla,76,M,22137,766 +2011,Fla,76,F,27686,772 +2011,Fla,77,M,21077,752 +2011,Fla,77,F,27065,663 +2011,Fla,78,M,20429,656 +2011,Fla,78,F,27478,622 +2011,Fla,79,M,19329,615 +2011,Fla,79,F,26774,503 +2011,Fla,80,M,17841,548 +2011,Fla,80,F,25670,572 +2011,Fla,81,M,15276,454 +2011,Fla,81,F,23038,452 +2011,Fla,82,M,13790,397 +2011,Fla,82,F,21441,471 +2011,Fla,83,M,12231,320 +2011,Fla,83,F,19664,390 +2011,Fla,84,M,10668,272 +2011,Fla,84,F,18475,371 +2011,Fla,85,M,9582,275 +2011,Fla,85,F,17024,310 +2011,Fla,86,M,8144,210 +2011,Fla,86,F,15231,284 +2011,Fla,87,M,6830,175 +2011,Fla,87,F,13884,270 +2011,Fla,88,M,5529,138 +2011,Fla,88,F,11610,193 +2011,Fla,89,M,4447,122 +2011,Fla,89,F,10036,154 +2011,Fla,90,M,3467,92 +2011,Fla,90,F,8431,140 +2011,Fla,91,M,2061,51 +2011,Fla,91,F,5284,72 +2011,Fla,92,M,1073,33 +2011,Fla,92,F,3073,62 +2011,Fla,93,M,742,25 +2011,Fla,93,F,2400,59 +2011,Fla,94,M,634,17 +2011,Fla,94,F,2130,41 +2011,Fla,95,M,562,17 +2011,Fla,95,F,1918,38 +2011,Fla,96,M,391,5 +2011,Fla,96,F,1616,32 +2011,Fla,97,M,274,6 +2011,Fla,97,F,1164,22 +2011,Fla,98,M,159,2 +2011,Fla,98,F,798,18 +2011,Fla,99,M,101,2 +2011,Fla,99,F,547,6 +2011,Fla,100,M,53,1 +2011,Fla,100,F,319,7 +2011,Fla,101,M,28,1 +2011,Fla,101,F,211,4 +2011,Fla,102,M,23,1 +2011,Fla,102,F,108,1 +2011,Fla,103,M,10,0 +2011,Fla,103,F,68,2 +2011,Fla,104,M,5,0 +2011,Fla,104,F,32,0 +2011,Fla,105,M,2,0 +2011,Fla,105,F,24,0 +2011,Fla,106,M,0,0 +2011,Fla,106,F,12,0 +2011,Fla,107,M,0,0 +2011,Fla,107,F,4,0 +2011,Fla,108,M,0,0 +2011,Fla,108,F,2,0 +2011,Fla,109,M,0,0 +2011,Fla,109,F,2,0 +2011,Fla,110,M,1,0 +2011,Fla,110,F,0,0 +2011,Fla,111,M,0,0 +2011,Fla,111,F,0,0 +2011,Fla,112,M,0,0 +2011,Fla,112,F,1,0 +2011,Fla,113,M,0,0 +2011,Fla,113,F,0,0 +2011,Fla,114,M,0,0 +2011,Fla,114,F,0,0 +2011,Fla,115,M,0,0 +2011,Fla,115,F,0,1 +2011,Fla,116,M,0,0 +2011,Fla,116,F,0,0 +2011,Fla,117,M,0,0 +2011,Fla,117,F,0,0 +2011,Fla,118,M,0,0 +2011,Fla,118,F,0,0 +2011,Fla,119,M,0,0 +2011,Fla,119,F,0,0 +2011,Fla,120,M,0,0 +2011,Fla,120,F,0,0 +2011,Wal,0,M,19576,1264 +2011,Wal,0,F,18613,1252 +2011,Wal,1,M,19599,1211 +2011,Wal,1,F,19013,1165 +2011,Wal,2,M,20137,1185 +2011,Wal,2,F,18975,1115 +2011,Wal,3,M,20103,1165 +2011,Wal,3,F,19011,1095 +2011,Wal,4,M,20133,1129 +2011,Wal,4,F,19439,1092 +2011,Wal,5,M,19941,1124 +2011,Wal,5,F,19136,1017 +2011,Wal,6,M,19917,1082 +2011,Wal,6,F,18937,1096 +2011,Wal,7,M,19646,1169 +2011,Wal,7,F,19041,1039 +2011,Wal,8,M,19768,1166 +2011,Wal,8,F,18789,1096 +2011,Wal,9,M,20428,1120 +2011,Wal,9,F,19652,1094 +2011,Wal,10,M,20792,1106 +2011,Wal,10,F,19712,1152 +2011,Wal,11,M,20229,1150 +2011,Wal,11,F,19228,1103 +2011,Wal,12,M,20270,1116 +2011,Wal,12,F,19368,1107 +2011,Wal,13,M,20327,1164 +2011,Wal,13,F,19476,1137 +2011,Wal,14,M,20498,1219 +2011,Wal,14,F,19639,1112 +2011,Wal,15,M,20020,1221 +2011,Wal,15,F,19163,1082 +2011,Wal,16,M,20220,1197 +2011,Wal,16,F,19299,1159 +2011,Wal,17,M,21007,1232 +2011,Wal,17,F,19887,1304 +2011,Wal,18,M,22023,1345 +2011,Wal,18,F,21076,1458 +2011,Wal,19,M,22487,1386 +2011,Wal,19,F,21642,1510 +2011,Wal,20,M,22105,1519 +2011,Wal,20,F,21260,1744 +2011,Wal,21,M,22030,1553 +2011,Wal,21,F,21103,1965 +2011,Wal,22,M,21689,1715 +2011,Wal,22,F,20633,2166 +2011,Wal,23,M,20747,1882 +2011,Wal,23,F,19891,2273 +2011,Wal,24,M,20530,2026 +2011,Wal,24,F,19529,2505 +2011,Wal,25,M,19348,2031 +2011,Wal,25,F,18748,2496 +2011,Wal,26,M,18980,2246 +2011,Wal,26,F,18428,2646 +2011,Wal,27,M,18746,2370 +2011,Wal,27,F,17712,2496 +2011,Wal,28,M,18857,2506 +2011,Wal,28,F,18388,2864 +2011,Wal,29,M,18961,2556 +2011,Wal,29,F,18904,2759 +2011,Wal,30,M,19034,2728 +2011,Wal,30,F,18947,2935 +2011,Wal,31,M,18810,2875 +2011,Wal,31,F,18396,2802 +2011,Wal,32,M,18660,2858 +2011,Wal,32,F,18408,2826 +2011,Wal,33,M,18760,2829 +2011,Wal,33,F,18678,2777 +2011,Wal,34,M,19099,2708 +2011,Wal,34,F,19200,2717 +2011,Wal,35,M,19300,2828 +2011,Wal,35,F,19393,2794 +2011,Wal,36,M,20089,3015 +2011,Wal,36,F,19986,2862 +2011,Wal,37,M,20984,3232 +2011,Wal,37,F,20947,2948 +2011,Wal,38,M,21704,3228 +2011,Wal,38,F,21684,3061 +2011,Wal,39,M,21993,3306 +2011,Wal,39,F,22204,2893 +2011,Wal,40,M,21745,3254 +2011,Wal,40,F,21592,3035 +2011,Wal,41,M,21524,3219 +2011,Wal,41,F,21666,2891 +2011,Wal,42,M,21068,3134 +2011,Wal,42,F,21510,2973 +2011,Wal,43,M,21518,3211 +2011,Wal,43,F,21706,2890 +2011,Wal,44,M,21834,3458 +2011,Wal,44,F,22124,3026 +2011,Wal,45,M,22637,3490 +2011,Wal,45,F,22874,2897 +2011,Wal,46,M,23288,3284 +2011,Wal,46,F,23730,2931 +2011,Wal,47,M,22743,3282 +2011,Wal,47,F,23456,2807 +2011,Wal,48,M,22100,3195 +2011,Wal,48,F,22930,2556 +2011,Wal,49,M,22567,3064 +2011,Wal,49,F,23373,2598 +2011,Wal,50,M,22477,3314 +2011,Wal,50,F,22952,2581 +2011,Wal,51,M,22348,3072 +2011,Wal,51,F,23631,2400 +2011,Wal,52,M,21830,3059 +2011,Wal,52,F,23114,2379 +2011,Wal,53,M,21490,3030 +2011,Wal,53,F,22574,2316 +2011,Wal,54,M,20806,3058 +2011,Wal,54,F,22276,2298 +2011,Wal,55,M,20502,2960 +2011,Wal,55,F,22183,2217 +2011,Wal,56,M,20406,2829 +2011,Wal,56,F,21801,2184 +2011,Wal,57,M,20063,2745 +2011,Wal,57,F,21458,2071 +2011,Wal,58,M,19640,2703 +2011,Wal,58,F,21066,2065 +2011,Wal,59,M,18932,2554 +2011,Wal,59,F,20635,2031 +2011,Wal,60,M,19414,2517 +2011,Wal,60,F,20605,2089 +2011,Wal,61,M,19182,2454 +2011,Wal,61,F,20640,1873 +2011,Wal,62,M,19426,2467 +2011,Wal,62,F,21087,2038 +2011,Wal,63,M,19096,2385 +2011,Wal,63,F,20722,1864 +2011,Wal,64,M,18439,2242 +2011,Wal,64,F,20527,1728 +2011,Wal,65,M,13562,1730 +2011,Wal,65,F,15634,1472 +2011,Wal,66,M,13359,1741 +2011,Wal,66,F,15209,1485 +2011,Wal,67,M,12257,1541 +2011,Wal,67,F,14236,1347 +2011,Wal,68,M,10612,1422 +2011,Wal,68,F,12426,1317 +2011,Wal,69,M,9621,1364 +2011,Wal,69,F,11605,1248 +2011,Wal,70,M,10658,1509 +2011,Wal,70,F,12930,1502 +2011,Wal,71,M,11351,1424 +2011,Wal,71,F,14125,1503 +2011,Wal,72,M,11027,1252 +2011,Wal,72,F,14167,1467 +2011,Wal,73,M,10452,1271 +2011,Wal,73,F,13264,1357 +2011,Wal,74,M,9861,1155 +2011,Wal,74,F,13057,1331 +2011,Wal,75,M,9288,1112 +2011,Wal,75,F,12709,1349 +2011,Wal,76,M,9339,1058 +2011,Wal,76,F,12942,1365 +2011,Wal,77,M,8956,972 +2011,Wal,77,F,12736,1318 +2011,Wal,78,M,8893,950 +2011,Wal,78,F,13657,1213 +2011,Wal,79,M,8617,862 +2011,Wal,79,F,13416,1232 +2011,Wal,80,M,7954,855 +2011,Wal,80,F,13058,1217 +2011,Wal,81,M,6921,751 +2011,Wal,81,F,11948,1110 +2011,Wal,82,M,6176,649 +2011,Wal,82,F,11294,982 +2011,Wal,83,M,5576,597 +2011,Wal,83,F,10580,960 +2011,Wal,84,M,4926,539 +2011,Wal,84,F,9964,937 +2011,Wal,85,M,4420,432 +2011,Wal,85,F,9540,858 +2011,Wal,86,M,3717,397 +2011,Wal,86,F,8508,747 +2011,Wal,87,M,3049,331 +2011,Wal,87,F,7516,649 +2011,Wal,88,M,2497,218 +2011,Wal,88,F,6647,552 +2011,Wal,89,M,2112,189 +2011,Wal,89,F,5887,442 +2011,Wal,90,M,1579,127 +2011,Wal,90,F,4927,373 +2011,Wal,91,M,950,79 +2011,Wal,91,F,3022,217 +2011,Wal,92,M,481,30 +2011,Wal,92,F,1681,121 +2011,Wal,93,M,359,20 +2011,Wal,93,F,1348,97 +2011,Wal,94,M,295,15 +2011,Wal,94,F,1103,80 +2011,Wal,95,M,206,18 +2011,Wal,95,F,1030,70 +2011,Wal,96,M,163,15 +2011,Wal,96,F,927,56 +2011,Wal,97,M,123,6 +2011,Wal,97,F,605,36 +2011,Wal,98,M,42,7 +2011,Wal,98,F,383,29 +2011,Wal,99,M,32,1 +2011,Wal,99,F,279,18 +2011,Wal,100,M,22,1 +2011,Wal,100,F,169,16 +2011,Wal,101,M,10,2 +2011,Wal,101,F,88,8 +2011,Wal,102,M,8,0 +2011,Wal,102,F,52,3 +2011,Wal,103,M,3,0 +2011,Wal,103,F,38,2 +2011,Wal,104,M,0,0 +2011,Wal,104,F,21,1 +2011,Wal,105,M,1,1 +2011,Wal,105,F,13,1 +2011,Wal,106,M,0,0 +2011,Wal,106,F,4,1 +2011,Wal,107,M,0,0 +2011,Wal,107,F,2,0 +2011,Wal,108,M,0,0 +2011,Wal,108,F,1,0 +2011,Wal,109,M,0,0 +2011,Wal,109,F,0,0 +2011,Wal,110,M,0,0 +2011,Wal,110,F,1,0 +2011,Wal,111,M,0,0 +2011,Wal,111,F,1,0 +2011,Wal,112,M,0,0 +2011,Wal,112,F,0,0 +2011,Wal,113,M,0,0 +2011,Wal,113,F,0,0 +2011,Wal,114,M,0,0 +2011,Wal,114,F,0,0 +2011,Wal,115,M,0,0 +2011,Wal,115,F,0,0 +2011,Wal,116,M,0,0 +2011,Wal,116,F,0,0 +2011,Wal,117,M,0,0 +2011,Wal,117,F,0,0 +2011,Wal,118,M,0,0 +2011,Wal,118,F,0,0 +2011,Wal,119,M,0,0 +2011,Wal,119,F,0,0 +2011,Wal,120,M,0,0 +2011,Wal,120,F,0,0 +2012,BruCap,0,M,6440,2818 +2012,BruCap,0,F,6111,2670 +2012,BruCap,1,M,6604,2801 +2012,BruCap,1,F,6205,2693 +2012,BruCap,2,M,6423,2533 +2012,BruCap,2,F,6125,2472 +2012,BruCap,3,M,6106,2363 +2012,BruCap,3,F,5831,2311 +2012,BruCap,4,M,5989,2263 +2012,BruCap,4,F,5703,2075 +2012,BruCap,5,M,5951,2072 +2012,BruCap,5,F,5632,1921 +2012,BruCap,6,M,5638,1937 +2012,BruCap,6,F,5436,1858 +2012,BruCap,7,M,5494,1790 +2012,BruCap,7,F,5242,1714 +2012,BruCap,8,M,5156,1773 +2012,BruCap,8,F,4955,1636 +2012,BruCap,9,M,4917,1613 +2012,BruCap,9,F,4802,1567 +2012,BruCap,10,M,4932,1574 +2012,BruCap,10,F,4909,1484 +2012,BruCap,11,M,4929,1629 +2012,BruCap,11,F,4630,1491 +2012,BruCap,12,M,4834,1522 +2012,BruCap,12,F,4624,1450 +2012,BruCap,13,M,4626,1430 +2012,BruCap,13,F,4452,1495 +2012,BruCap,14,M,4750,1460 +2012,BruCap,14,F,4436,1438 +2012,BruCap,15,M,4610,1409 +2012,BruCap,15,F,4416,1432 +2012,BruCap,16,M,4564,1404 +2012,BruCap,16,F,4349,1333 +2012,BruCap,17,M,4732,1481 +2012,BruCap,17,F,4292,1361 +2012,BruCap,18,M,4652,1481 +2012,BruCap,18,F,4513,1626 +2012,BruCap,19,M,4813,1659 +2012,BruCap,19,F,4655,1961 +2012,BruCap,20,M,4818,1975 +2012,BruCap,20,F,4777,2287 +2012,BruCap,21,M,4873,2185 +2012,BruCap,21,F,4827,2752 +2012,BruCap,22,M,4888,2294 +2012,BruCap,22,F,4924,3113 +2012,BruCap,23,M,5032,2495 +2012,BruCap,23,F,4932,3513 +2012,BruCap,24,M,5018,2887 +2012,BruCap,24,F,5318,4050 +2012,BruCap,25,M,5192,3217 +2012,BruCap,25,F,5437,4235 +2012,BruCap,26,M,5292,3566 +2012,BruCap,26,F,5338,4634 +2012,BruCap,27,M,5310,4110 +2012,BruCap,27,F,5709,4864 +2012,BruCap,28,M,5253,4120 +2012,BruCap,28,F,5540,4888 +2012,BruCap,29,M,5413,4631 +2012,BruCap,29,F,5592,5119 +2012,BruCap,30,M,5472,4570 +2012,BruCap,30,F,5631,4885 +2012,BruCap,31,M,5545,4981 +2012,BruCap,31,F,5667,5109 +2012,BruCap,32,M,5468,4896 +2012,BruCap,32,F,5352,4953 +2012,BruCap,33,M,5322,4848 +2012,BruCap,33,F,5291,4778 +2012,BruCap,34,M,5314,4756 +2012,BruCap,34,F,5278,4498 +2012,BruCap,35,M,5109,4806 +2012,BruCap,35,F,5005,4371 +2012,BruCap,36,M,5113,4548 +2012,BruCap,36,F,4826,4078 +2012,BruCap,37,M,5081,4481 +2012,BruCap,37,F,4765,4007 +2012,BruCap,38,M,5169,4329 +2012,BruCap,38,F,4885,3709 +2012,BruCap,39,M,5083,4073 +2012,BruCap,39,F,4862,3686 +2012,BruCap,40,M,5134,3912 +2012,BruCap,40,F,4788,3461 +2012,BruCap,41,M,5175,4042 +2012,BruCap,41,F,4964,3308 +2012,BruCap,42,M,5081,3852 +2012,BruCap,42,F,4768,3275 +2012,BruCap,43,M,4985,3708 +2012,BruCap,43,F,4641,3115 +2012,BruCap,44,M,4792,3473 +2012,BruCap,44,F,4529,2852 +2012,BruCap,45,M,4816,3297 +2012,BruCap,45,F,4727,2681 +2012,BruCap,46,M,4967,3043 +2012,BruCap,46,F,4865,2643 +2012,BruCap,47,M,4936,3042 +2012,BruCap,47,F,4871,2563 +2012,BruCap,48,M,4709,2729 +2012,BruCap,48,F,4748,2405 +2012,BruCap,49,M,4619,2597 +2012,BruCap,49,F,4708,2260 +2012,BruCap,50,M,4463,2450 +2012,BruCap,50,F,4722,2186 +2012,BruCap,51,M,4593,2333 +2012,BruCap,51,F,5014,2125 +2012,BruCap,52,M,4509,2157 +2012,BruCap,52,F,4818,2090 +2012,BruCap,53,M,4347,2065 +2012,BruCap,53,F,4780,1884 +2012,BruCap,54,M,4194,1849 +2012,BruCap,54,F,4646,1797 +2012,BruCap,55,M,4082,1884 +2012,BruCap,55,F,4689,1700 +2012,BruCap,56,M,4106,1735 +2012,BruCap,56,F,4628,1687 +2012,BruCap,57,M,3991,1551 +2012,BruCap,57,F,4526,1615 +2012,BruCap,58,M,4026,1447 +2012,BruCap,58,F,4520,1443 +2012,BruCap,59,M,3968,1444 +2012,BruCap,59,F,4436,1510 +2012,BruCap,60,M,3649,1222 +2012,BruCap,60,F,4153,1302 +2012,BruCap,61,M,3696,1296 +2012,BruCap,61,F,4259,1351 +2012,BruCap,62,M,3541,1178 +2012,BruCap,62,F,4119,1198 +2012,BruCap,63,M,3453,1172 +2012,BruCap,63,F,4080,1145 +2012,BruCap,64,M,3410,1046 +2012,BruCap,64,F,4208,1073 +2012,BruCap,65,M,3328,951 +2012,BruCap,65,F,4002,1037 +2012,BruCap,66,M,2788,801 +2012,BruCap,66,F,3592,922 +2012,BruCap,67,M,2970,767 +2012,BruCap,67,F,3640,915 +2012,BruCap,68,M,2722,734 +2012,BruCap,68,F,3395,815 +2012,BruCap,69,M,2436,682 +2012,BruCap,69,F,3023,783 +2012,BruCap,70,M,2025,595 +2012,BruCap,70,F,2638,697 +2012,BruCap,71,M,2346,681 +2012,BruCap,71,F,3062,841 +2012,BruCap,72,M,2312,611 +2012,BruCap,72,F,3143,754 +2012,BruCap,73,M,2301,568 +2012,BruCap,73,F,3072,738 +2012,BruCap,74,M,2158,515 +2012,BruCap,74,F,2947,658 +2012,BruCap,75,M,2126,500 +2012,BruCap,75,F,2920,713 +2012,BruCap,76,M,2006,461 +2012,BruCap,76,F,3011,633 +2012,BruCap,77,M,1984,439 +2012,BruCap,77,F,2952,581 +2012,BruCap,78,M,1888,375 +2012,BruCap,78,F,2973,508 +2012,BruCap,79,M,1883,372 +2012,BruCap,79,F,3044,459 +2012,BruCap,80,M,1778,306 +2012,BruCap,80,F,2912,442 +2012,BruCap,81,M,1652,322 +2012,BruCap,81,F,3121,504 +2012,BruCap,82,M,1499,271 +2012,BruCap,82,F,2881,352 +2012,BruCap,83,M,1396,206 +2012,BruCap,83,F,2760,341 +2012,BruCap,84,M,1283,167 +2012,BruCap,84,F,2605,303 +2012,BruCap,85,M,1175,165 +2012,BruCap,85,F,2499,258 +2012,BruCap,86,M,1007,129 +2012,BruCap,86,F,2398,217 +2012,BruCap,87,M,1003,102 +2012,BruCap,87,F,2259,189 +2012,BruCap,88,M,729,82 +2012,BruCap,88,F,2089,182 +2012,BruCap,89,M,675,88 +2012,BruCap,89,F,1825,128 +2012,BruCap,90,M,630,51 +2012,BruCap,90,F,1583,113 +2012,BruCap,91,M,442,45 +2012,BruCap,91,F,1359,121 +2012,BruCap,92,M,262,27 +2012,BruCap,92,F,855,67 +2012,BruCap,93,M,135,21 +2012,BruCap,93,F,500,47 +2012,BruCap,94,M,111,13 +2012,BruCap,94,F,390,35 +2012,BruCap,95,M,81,7 +2012,BruCap,95,F,332,37 +2012,BruCap,96,M,52,4 +2012,BruCap,96,F,299,18 +2012,BruCap,97,M,51,6 +2012,BruCap,97,F,282,21 +2012,BruCap,98,M,35,3 +2012,BruCap,98,F,166,8 +2012,BruCap,99,M,20,4 +2012,BruCap,99,F,124,10 +2012,BruCap,100,M,15,5 +2012,BruCap,100,F,76,6 +2012,BruCap,101,M,8,1 +2012,BruCap,101,F,52,7 +2012,BruCap,102,M,1,0 +2012,BruCap,102,F,25,7 +2012,BruCap,103,M,0,1 +2012,BruCap,103,F,22,5 +2012,BruCap,104,M,0,0 +2012,BruCap,104,F,12,0 +2012,BruCap,105,M,1,0 +2012,BruCap,105,F,7,0 +2012,BruCap,106,M,0,0 +2012,BruCap,106,F,3,0 +2012,BruCap,107,M,0,0 +2012,BruCap,107,F,1,0 +2012,BruCap,108,M,0,0 +2012,BruCap,108,F,0,0 +2012,BruCap,109,M,0,0 +2012,BruCap,109,F,0,0 +2012,BruCap,110,M,0,0 +2012,BruCap,110,F,0,0 +2012,BruCap,111,M,0,1 +2012,BruCap,111,F,0,0 +2012,BruCap,112,M,0,0 +2012,BruCap,112,F,0,0 +2012,BruCap,113,M,0,0 +2012,BruCap,113,F,0,0 +2012,BruCap,114,M,0,0 +2012,BruCap,114,F,0,0 +2012,BruCap,115,M,0,0 +2012,BruCap,115,F,0,0 +2012,BruCap,116,M,0,0 +2012,BruCap,116,F,0,0 +2012,BruCap,117,M,0,0 +2012,BruCap,117,F,0,0 +2012,BruCap,118,M,0,0 +2012,BruCap,118,F,0,0 +2012,BruCap,119,M,0,0 +2012,BruCap,119,F,0,0 +2012,BruCap,120,M,0,0 +2012,BruCap,120,F,0,0 +2012,Fla,0,M,32348,3310 +2012,Fla,0,F,30725,3146 +2012,Fla,1,M,33084,3227 +2012,Fla,1,F,31705,3154 +2012,Fla,2,M,33386,3012 +2012,Fla,2,F,31491,2917 +2012,Fla,3,M,33985,2936 +2012,Fla,3,F,32338,2749 +2012,Fla,4,M,32989,2826 +2012,Fla,4,F,31823,2717 +2012,Fla,5,M,32915,2654 +2012,Fla,5,F,31603,2587 +2012,Fla,6,M,32539,2558 +2012,Fla,6,F,30717,2394 +2012,Fla,7,M,32032,2454 +2012,Fla,7,F,30360,2432 +2012,Fla,8,M,30891,2475 +2012,Fla,8,F,29503,2342 +2012,Fla,9,M,30879,2379 +2012,Fla,9,F,29390,2288 +2012,Fla,10,M,31198,2321 +2012,Fla,10,F,29896,2223 +2012,Fla,11,M,31890,2478 +2012,Fla,11,F,30615,2325 +2012,Fla,12,M,31809,2295 +2012,Fla,12,F,30845,2166 +2012,Fla,13,M,32750,2198 +2012,Fla,13,F,31159,2123 +2012,Fla,14,M,33368,2217 +2012,Fla,14,F,32119,2128 +2012,Fla,15,M,33417,2103 +2012,Fla,15,F,32206,2040 +2012,Fla,16,M,33551,2087 +2012,Fla,16,F,32279,1988 +2012,Fla,17,M,33997,2221 +2012,Fla,17,F,32350,2007 +2012,Fla,18,M,35394,2178 +2012,Fla,18,F,34219,2069 +2012,Fla,19,M,36546,2307 +2012,Fla,19,F,35078,2246 +2012,Fla,20,M,36975,2395 +2012,Fla,20,F,35199,2624 +2012,Fla,21,M,36505,2692 +2012,Fla,21,F,34897,3097 +2012,Fla,22,M,35166,2867 +2012,Fla,22,F,33644,3670 +2012,Fla,23,M,34617,3379 +2012,Fla,23,F,33418,4197 +2012,Fla,24,M,34172,3581 +2012,Fla,24,F,32605,4502 +2012,Fla,25,M,34033,3840 +2012,Fla,25,F,32660,4793 +2012,Fla,26,M,32833,4239 +2012,Fla,26,F,32010,5008 +2012,Fla,27,M,33494,4557 +2012,Fla,27,F,32686,5063 +2012,Fla,28,M,34367,4622 +2012,Fla,28,F,33832,4986 +2012,Fla,29,M,35279,4786 +2012,Fla,29,F,34313,5077 +2012,Fla,30,M,36473,4745 +2012,Fla,30,F,35224,4903 +2012,Fla,31,M,35967,5041 +2012,Fla,31,F,35896,5033 +2012,Fla,32,M,36620,4864 +2012,Fla,32,F,35579,4859 +2012,Fla,33,M,35850,4891 +2012,Fla,33,F,35635,4729 +2012,Fla,34,M,35174,4837 +2012,Fla,34,F,35051,4634 +2012,Fla,35,M,34724,4821 +2012,Fla,35,F,34213,4429 +2012,Fla,36,M,33934,4708 +2012,Fla,36,F,33381,4445 +2012,Fla,37,M,35294,4705 +2012,Fla,37,F,34948,4215 +2012,Fla,38,M,36648,4545 +2012,Fla,38,F,35954,4155 +2012,Fla,39,M,38321,4655 +2012,Fla,39,F,38054,4165 +2012,Fla,40,M,39930,4571 +2012,Fla,40,F,39905,3985 +2012,Fla,41,M,41152,4753 +2012,Fla,41,F,40665,4132 +2012,Fla,42,M,41152,4513 +2012,Fla,42,F,40585,3874 +2012,Fla,43,M,41478,4532 +2012,Fla,43,F,40975,3828 +2012,Fla,44,M,42916,4160 +2012,Fla,44,F,41525,3471 +2012,Fla,45,M,44163,4218 +2012,Fla,45,F,43356,3438 +2012,Fla,46,M,45583,4113 +2012,Fla,46,F,44541,3292 +2012,Fla,47,M,47233,3963 +2012,Fla,47,F,46611,3183 +2012,Fla,48,M,46893,3703 +2012,Fla,48,F,46012,2914 +2012,Fla,49,M,46247,3530 +2012,Fla,49,F,45242,2832 +2012,Fla,50,M,45581,3308 +2012,Fla,50,F,45465,2600 +2012,Fla,51,M,44719,3245 +2012,Fla,51,F,44335,2593 +2012,Fla,52,M,45115,2970 +2012,Fla,52,F,44761,2411 +2012,Fla,53,M,44143,2977 +2012,Fla,53,F,43481,2159 +2012,Fla,54,M,43311,2711 +2012,Fla,54,F,42661,2080 +2012,Fla,55,M,41905,2575 +2012,Fla,55,F,42018,1993 +2012,Fla,56,M,41084,2489 +2012,Fla,56,F,41373,1942 +2012,Fla,57,M,40062,2380 +2012,Fla,57,F,40167,1882 +2012,Fla,58,M,39023,2219 +2012,Fla,58,F,38677,1758 +2012,Fla,59,M,38689,2097 +2012,Fla,59,F,38298,1688 +2012,Fla,60,M,36608,2076 +2012,Fla,60,F,36731,1556 +2012,Fla,61,M,35943,1990 +2012,Fla,61,F,36549,1695 +2012,Fla,62,M,35816,2044 +2012,Fla,62,F,36042,1600 +2012,Fla,63,M,35526,1965 +2012,Fla,63,F,36440,1535 +2012,Fla,64,M,34811,1895 +2012,Fla,64,F,35844,1508 +2012,Fla,65,M,35327,1860 +2012,Fla,65,F,36270,1388 +2012,Fla,66,M,30937,1516 +2012,Fla,66,F,32484,1209 +2012,Fla,67,M,30350,1482 +2012,Fla,67,F,32069,1289 +2012,Fla,68,M,28672,1452 +2012,Fla,68,F,30661,1128 +2012,Fla,69,M,24752,1287 +2012,Fla,69,F,26646,1122 +2012,Fla,70,M,21869,1192 +2012,Fla,70,F,24278,968 +2012,Fla,71,M,23643,1171 +2012,Fla,71,F,26741,1167 +2012,Fla,72,M,25420,1096 +2012,Fla,72,F,29527,957 +2012,Fla,73,M,25848,1059 +2012,Fla,73,F,29838,941 +2012,Fla,74,M,24482,952 +2012,Fla,74,F,28503,871 +2012,Fla,75,M,22794,874 +2012,Fla,75,F,27598,806 +2012,Fla,76,M,21918,837 +2012,Fla,76,F,27090,746 +2012,Fla,77,M,21275,745 +2012,Fla,77,F,27084,747 +2012,Fla,78,M,20166,709 +2012,Fla,78,F,26421,631 +2012,Fla,79,M,19366,622 +2012,Fla,79,F,26726,590 +2012,Fla,80,M,18310,572 +2012,Fla,80,F,25875,470 +2012,Fla,81,M,16725,505 +2012,Fla,81,F,24586,553 +2012,Fla,82,M,14187,420 +2012,Fla,82,F,22032,431 +2012,Fla,83,M,12666,366 +2012,Fla,83,F,20346,442 +2012,Fla,84,M,11171,292 +2012,Fla,84,F,18491,353 +2012,Fla,85,M,9655,234 +2012,Fla,85,F,17243,338 +2012,Fla,86,M,8459,236 +2012,Fla,86,F,15667,275 +2012,Fla,87,M,7151,175 +2012,Fla,87,F,13938,252 +2012,Fla,88,M,5908,138 +2012,Fla,88,F,12440,238 +2012,Fla,89,M,4717,118 +2012,Fla,89,F,10219,172 +2012,Fla,90,M,3723,96 +2012,Fla,90,F,8718,134 +2012,Fla,91,M,2789,71 +2012,Fla,91,F,7202,116 +2012,Fla,92,M,1627,35 +2012,Fla,92,F,4414,59 +2012,Fla,93,M,834,28 +2012,Fla,93,F,2511,51 +2012,Fla,94,M,543,16 +2012,Fla,94,F,1904,56 +2012,Fla,95,M,462,9 +2012,Fla,95,F,1701,31 +2012,Fla,96,M,401,12 +2012,Fla,96,F,1458,27 +2012,Fla,97,M,287,3 +2012,Fla,97,F,1185,25 +2012,Fla,98,M,182,4 +2012,Fla,98,F,843,18 +2012,Fla,99,M,108,2 +2012,Fla,99,F,559,15 +2012,Fla,100,M,73,1 +2012,Fla,100,F,362,5 +2012,Fla,101,M,31,0 +2012,Fla,101,F,197,6 +2012,Fla,102,M,18,1 +2012,Fla,102,F,152,3 +2012,Fla,103,M,12,1 +2012,Fla,103,F,69,0 +2012,Fla,104,M,3,0 +2012,Fla,104,F,34,2 +2012,Fla,105,M,0,0 +2012,Fla,105,F,23,0 +2012,Fla,106,M,1,0 +2012,Fla,106,F,13,0 +2012,Fla,107,M,0,0 +2012,Fla,107,F,4,0 +2012,Fla,108,M,0,0 +2012,Fla,108,F,2,0 +2012,Fla,109,M,0,0 +2012,Fla,109,F,2,0 +2012,Fla,110,M,0,0 +2012,Fla,110,F,0,0 +2012,Fla,111,M,1,0 +2012,Fla,111,F,0,0 +2012,Fla,112,M,0,0 +2012,Fla,112,F,0,0 +2012,Fla,113,M,0,0 +2012,Fla,113,F,1,0 +2012,Fla,114,M,0,0 +2012,Fla,114,F,0,0 +2012,Fla,115,M,0,0 +2012,Fla,115,F,0,0 +2012,Fla,116,M,0,0 +2012,Fla,116,F,0,1 +2012,Fla,117,M,0,0 +2012,Fla,117,F,0,0 +2012,Fla,118,M,0,0 +2012,Fla,118,F,0,0 +2012,Fla,119,M,0,0 +2012,Fla,119,F,0,0 +2012,Fla,120,M,0,0 +2012,Fla,120,F,0,0 +2012,Wal,0,M,19104,1455 +2012,Wal,0,F,18358,1367 +2012,Wal,1,M,19797,1332 +2012,Wal,1,F,18860,1320 +2012,Wal,2,M,19838,1290 +2012,Wal,2,F,19173,1207 +2012,Wal,3,M,20292,1271 +2012,Wal,3,F,19121,1198 +2012,Wal,4,M,20225,1229 +2012,Wal,4,F,19140,1190 +2012,Wal,5,M,20220,1207 +2012,Wal,5,F,19535,1196 +2012,Wal,6,M,20035,1185 +2012,Wal,6,F,19265,1074 +2012,Wal,7,M,19971,1214 +2012,Wal,7,F,19025,1191 +2012,Wal,8,M,19702,1233 +2012,Wal,8,F,19119,1138 +2012,Wal,9,M,19841,1229 +2012,Wal,9,F,18872,1175 +2012,Wal,10,M,20491,1191 +2012,Wal,10,F,19725,1143 +2012,Wal,11,M,20869,1185 +2012,Wal,11,F,19793,1225 +2012,Wal,12,M,20285,1233 +2012,Wal,12,F,19275,1160 +2012,Wal,13,M,20324,1180 +2012,Wal,13,F,19445,1180 +2012,Wal,14,M,20372,1226 +2012,Wal,14,F,19531,1181 +2012,Wal,15,M,20540,1266 +2012,Wal,15,F,19689,1191 +2012,Wal,16,M,20083,1300 +2012,Wal,16,F,19238,1172 +2012,Wal,17,M,20275,1255 +2012,Wal,17,F,19367,1304 +2012,Wal,18,M,21088,1374 +2012,Wal,18,F,19976,1492 +2012,Wal,19,M,22033,1448 +2012,Wal,19,F,21147,1585 +2012,Wal,20,M,22498,1463 +2012,Wal,20,F,21673,1702 +2012,Wal,21,M,22073,1635 +2012,Wal,21,F,21223,1966 +2012,Wal,22,M,21920,1676 +2012,Wal,22,F,21085,2101 +2012,Wal,23,M,21612,1908 +2012,Wal,23,F,20597,2327 +2012,Wal,24,M,20564,2037 +2012,Wal,24,F,19715,2455 +2012,Wal,25,M,20384,2207 +2012,Wal,25,F,19363,2655 +2012,Wal,26,M,19205,2264 +2012,Wal,26,F,18679,2596 +2012,Wal,27,M,18922,2400 +2012,Wal,27,F,18431,2775 +2012,Wal,28,M,18726,2558 +2012,Wal,28,F,17816,2602 +2012,Wal,29,M,18869,2659 +2012,Wal,29,F,18501,2948 +2012,Wal,30,M,19019,2676 +2012,Wal,30,F,19076,2851 +2012,Wal,31,M,19142,2873 +2012,Wal,31,F,19097,3017 +2012,Wal,32,M,18957,2904 +2012,Wal,32,F,18564,2912 +2012,Wal,33,M,18756,2975 +2012,Wal,33,F,18600,2887 +2012,Wal,34,M,18875,2883 +2012,Wal,34,F,18828,2835 +2012,Wal,35,M,19239,2787 +2012,Wal,35,F,19356,2765 +2012,Wal,36,M,19388,2914 +2012,Wal,36,F,19559,2827 +2012,Wal,37,M,20204,3069 +2012,Wal,37,F,20113,2933 +2012,Wal,38,M,21097,3264 +2012,Wal,38,F,21100,2993 +2012,Wal,39,M,21748,3296 +2012,Wal,39,F,21844,3060 +2012,Wal,40,M,22097,3329 +2012,Wal,40,F,22308,2909 +2012,Wal,41,M,21812,3298 +2012,Wal,41,F,21681,3070 +2012,Wal,42,M,21604,3231 +2012,Wal,42,F,21767,2866 +2012,Wal,43,M,21161,3213 +2012,Wal,43,F,21600,2965 +2012,Wal,44,M,21499,3227 +2012,Wal,44,F,21771,2900 +2012,Wal,45,M,21878,3492 +2012,Wal,45,F,22195,3024 +2012,Wal,46,M,22623,3468 +2012,Wal,46,F,22912,2880 +2012,Wal,47,M,23285,3315 +2012,Wal,47,F,23792,2892 +2012,Wal,48,M,22767,3259 +2012,Wal,48,F,23485,2789 +2012,Wal,49,M,22091,3164 +2012,Wal,49,F,22940,2522 +2012,Wal,50,M,22559,3066 +2012,Wal,50,F,23400,2544 +2012,Wal,51,M,22439,3295 +2012,Wal,51,F,22976,2520 +2012,Wal,52,M,22304,3049 +2012,Wal,52,F,23607,2376 +2012,Wal,53,M,21716,3046 +2012,Wal,53,F,23094,2338 +2012,Wal,54,M,21383,2965 +2012,Wal,54,F,22577,2281 +2012,Wal,55,M,20754,2983 +2012,Wal,55,F,22222,2241 +2012,Wal,56,M,20415,2894 +2012,Wal,56,F,22161,2183 +2012,Wal,57,M,20245,2777 +2012,Wal,57,F,21770,2139 +2012,Wal,58,M,19935,2660 +2012,Wal,58,F,21406,2049 +2012,Wal,59,M,19469,2638 +2012,Wal,59,F,21031,2016 +2012,Wal,60,M,18750,2486 +2012,Wal,60,F,20559,1975 +2012,Wal,61,M,19167,2432 +2012,Wal,61,F,20519,2036 +2012,Wal,62,M,18948,2385 +2012,Wal,62,F,20536,1820 +2012,Wal,63,M,19172,2358 +2012,Wal,63,F,20946,1989 +2012,Wal,64,M,18885,2278 +2012,Wal,64,F,20623,1813 +2012,Wal,65,M,18193,2150 +2012,Wal,65,F,20380,1675 +2012,Wal,66,M,13339,1648 +2012,Wal,66,F,15506,1429 +2012,Wal,67,M,13107,1661 +2012,Wal,67,F,15069,1470 +2012,Wal,68,M,11974,1479 +2012,Wal,68,F,14086,1315 +2012,Wal,69,M,10383,1370 +2012,Wal,69,F,12296,1278 +2012,Wal,70,M,9462,1289 +2012,Wal,70,F,11459,1210 +2012,Wal,71,M,10390,1433 +2012,Wal,71,F,12775,1447 +2012,Wal,72,M,11048,1352 +2012,Wal,72,F,13919,1466 +2012,Wal,73,M,10699,1203 +2012,Wal,73,F,13958,1406 +2012,Wal,74,M,10097,1190 +2012,Wal,74,F,13030,1317 +2012,Wal,75,M,9490,1106 +2012,Wal,75,F,12825,1292 +2012,Wal,76,M,8911,1040 +2012,Wal,76,F,12455,1322 +2012,Wal,77,M,8935,993 +2012,Wal,77,F,12632,1318 +2012,Wal,78,M,8516,920 +2012,Wal,78,F,12340,1284 +2012,Wal,79,M,8400,889 +2012,Wal,79,F,13205,1166 +2012,Wal,80,M,8042,798 +2012,Wal,80,F,12881,1198 +2012,Wal,81,M,7409,792 +2012,Wal,81,F,12490,1160 +2012,Wal,82,M,6429,689 +2012,Wal,82,F,11386,1060 +2012,Wal,83,M,5598,589 +2012,Wal,83,F,10602,919 +2012,Wal,84,M,5018,540 +2012,Wal,84,F,9881,922 +2012,Wal,85,M,4362,484 +2012,Wal,85,F,9204,865 +2012,Wal,86,M,3906,370 +2012,Wal,86,F,8704,791 +2012,Wal,87,M,3192,343 +2012,Wal,87,F,7681,682 +2012,Wal,88,M,2611,275 +2012,Wal,88,F,6654,585 +2012,Wal,89,M,2075,180 +2012,Wal,89,F,5830,502 +2012,Wal,90,M,1714,159 +2012,Wal,90,F,5045,377 +2012,Wal,91,M,1276,100 +2012,Wal,91,F,4163,301 +2012,Wal,92,M,764,59 +2012,Wal,92,F,2499,184 +2012,Wal,93,M,369,24 +2012,Wal,93,F,1362,96 +2012,Wal,94,M,274,12 +2012,Wal,94,F,1063,78 +2012,Wal,95,M,212,11 +2012,Wal,95,F,851,65 +2012,Wal,96,M,139,7 +2012,Wal,96,F,750,47 +2012,Wal,97,M,120,12 +2012,Wal,97,F,674,45 +2012,Wal,98,M,88,3 +2012,Wal,98,F,437,26 +2012,Wal,99,M,26,7 +2012,Wal,99,F,273,18 +2012,Wal,100,M,19,1 +2012,Wal,100,F,203,13 +2012,Wal,101,M,14,1 +2012,Wal,101,F,118,13 +2012,Wal,102,M,2,1 +2012,Wal,102,F,48,7 +2012,Wal,103,M,2,0 +2012,Wal,103,F,33,0 +2012,Wal,104,M,0,0 +2012,Wal,104,F,24,1 +2012,Wal,105,M,0,0 +2012,Wal,105,F,7,0 +2012,Wal,106,M,0,0 +2012,Wal,106,F,4,1 +2012,Wal,107,M,0,0 +2012,Wal,107,F,2,1 +2012,Wal,108,M,0,0 +2012,Wal,108,F,2,0 +2012,Wal,109,M,0,0 +2012,Wal,109,F,0,0 +2012,Wal,110,M,0,0 +2012,Wal,110,F,0,0 +2012,Wal,111,M,0,0 +2012,Wal,111,F,1,0 +2012,Wal,112,M,0,0 +2012,Wal,112,F,0,0 +2012,Wal,113,M,0,0 +2012,Wal,113,F,0,0 +2012,Wal,114,M,0,0 +2012,Wal,114,F,0,0 +2012,Wal,115,M,0,0 +2012,Wal,115,F,0,0 +2012,Wal,116,M,0,0 +2012,Wal,116,F,0,0 +2012,Wal,117,M,0,0 +2012,Wal,117,F,0,0 +2012,Wal,118,M,0,0 +2012,Wal,118,F,0,0 +2012,Wal,119,M,0,0 +2012,Wal,119,F,0,0 +2012,Wal,120,M,0,0 +2012,Wal,120,F,0,0 +2013,BruCap,0,M,6478,2858 +2013,BruCap,0,F,6178,2809 +2013,BruCap,1,M,6384,2811 +2013,BruCap,1,F,6090,2663 +2013,BruCap,2,M,6520,2721 +2013,BruCap,2,F,6112,2625 +2013,BruCap,3,M,6335,2472 +2013,BruCap,3,F,5977,2433 +2013,BruCap,4,M,6067,2327 +2013,BruCap,4,F,5767,2296 +2013,BruCap,5,M,5952,2209 +2013,BruCap,5,F,5648,2090 +2013,BruCap,6,M,5854,2086 +2013,BruCap,6,F,5557,1905 +2013,BruCap,7,M,5584,1922 +2013,BruCap,7,F,5371,1826 +2013,BruCap,8,M,5455,1787 +2013,BruCap,8,F,5211,1701 +2013,BruCap,9,M,5138,1777 +2013,BruCap,9,F,4927,1619 +2013,BruCap,10,M,4885,1634 +2013,BruCap,10,F,4774,1615 +2013,BruCap,11,M,4926,1608 +2013,BruCap,11,F,4858,1458 +2013,BruCap,12,M,4927,1616 +2013,BruCap,12,F,4606,1515 +2013,BruCap,13,M,4825,1551 +2013,BruCap,13,F,4644,1471 +2013,BruCap,14,M,4612,1454 +2013,BruCap,14,F,4454,1493 +2013,BruCap,15,M,4771,1463 +2013,BruCap,15,F,4443,1433 +2013,BruCap,16,M,4639,1439 +2013,BruCap,16,F,4411,1470 +2013,BruCap,17,M,4578,1435 +2013,BruCap,17,F,4368,1389 +2013,BruCap,18,M,4773,1631 +2013,BruCap,18,F,4383,1604 +2013,BruCap,19,M,4701,1766 +2013,BruCap,19,F,4564,1970 +2013,BruCap,20,M,4855,1951 +2013,BruCap,20,F,4690,2347 +2013,BruCap,21,M,4875,2182 +2013,BruCap,21,F,4865,2700 +2013,BruCap,22,M,4930,2467 +2013,BruCap,22,F,4893,3200 +2013,BruCap,23,M,4977,2587 +2013,BruCap,23,F,5079,3522 +2013,BruCap,24,M,5217,2919 +2013,BruCap,24,F,5224,4029 +2013,BruCap,25,M,5225,3356 +2013,BruCap,25,F,5575,4507 +2013,BruCap,26,M,5351,3692 +2013,BruCap,26,F,5702,4588 +2013,BruCap,27,M,5397,3973 +2013,BruCap,27,F,5498,4969 +2013,BruCap,28,M,5345,4457 +2013,BruCap,28,F,5737,5071 +2013,BruCap,29,M,5303,4461 +2013,BruCap,29,F,5481,5025 +2013,BruCap,30,M,5382,4750 +2013,BruCap,30,F,5583,5230 +2013,BruCap,31,M,5445,4739 +2013,BruCap,31,F,5582,4861 +2013,BruCap,32,M,5466,5097 +2013,BruCap,32,F,5653,5173 +2013,BruCap,33,M,5424,4958 +2013,BruCap,33,F,5298,4902 +2013,BruCap,34,M,5305,4849 +2013,BruCap,34,F,5303,4662 +2013,BruCap,35,M,5258,4775 +2013,BruCap,35,F,5242,4454 +2013,BruCap,36,M,5115,4816 +2013,BruCap,36,F,5047,4321 +2013,BruCap,37,M,5135,4534 +2013,BruCap,37,F,4781,4047 +2013,BruCap,38,M,5076,4522 +2013,BruCap,38,F,4749,3971 +2013,BruCap,39,M,5145,4312 +2013,BruCap,39,F,4887,3622 +2013,BruCap,40,M,5064,4085 +2013,BruCap,40,F,4871,3602 +2013,BruCap,41,M,5136,3864 +2013,BruCap,41,F,4777,3456 +2013,BruCap,42,M,5209,3991 +2013,BruCap,42,F,4956,3287 +2013,BruCap,43,M,5070,3841 +2013,BruCap,43,F,4781,3282 +2013,BruCap,44,M,5004,3730 +2013,BruCap,44,F,4680,3041 +2013,BruCap,45,M,4764,3438 +2013,BruCap,45,F,4538,2797 +2013,BruCap,46,M,4791,3271 +2013,BruCap,46,F,4729,2700 +2013,BruCap,47,M,4972,3012 +2013,BruCap,47,F,4886,2576 +2013,BruCap,48,M,4937,3000 +2013,BruCap,48,F,4881,2556 +2013,BruCap,49,M,4732,2754 +2013,BruCap,49,F,4745,2389 +2013,BruCap,50,M,4610,2604 +2013,BruCap,50,F,4711,2254 +2013,BruCap,51,M,4455,2435 +2013,BruCap,51,F,4727,2183 +2013,BruCap,52,M,4568,2336 +2013,BruCap,52,F,5007,2137 +2013,BruCap,53,M,4480,2131 +2013,BruCap,53,F,4795,2071 +2013,BruCap,54,M,4321,2045 +2013,BruCap,54,F,4755,1869 +2013,BruCap,55,M,4165,1816 +2013,BruCap,55,F,4635,1744 +2013,BruCap,56,M,4025,1871 +2013,BruCap,56,F,4675,1665 +2013,BruCap,57,M,4065,1690 +2013,BruCap,57,F,4568,1677 +2013,BruCap,58,M,3939,1507 +2013,BruCap,58,F,4508,1544 +2013,BruCap,59,M,3967,1412 +2013,BruCap,59,F,4484,1414 +2013,BruCap,60,M,3893,1379 +2013,BruCap,60,F,4401,1431 +2013,BruCap,61,M,3574,1182 +2013,BruCap,61,F,4091,1251 +2013,BruCap,62,M,3634,1250 +2013,BruCap,62,F,4205,1300 +2013,BruCap,63,M,3447,1127 +2013,BruCap,63,F,4049,1139 +2013,BruCap,64,M,3390,1122 +2013,BruCap,64,F,4031,1103 +2013,BruCap,65,M,3334,981 +2013,BruCap,65,F,4119,1023 +2013,BruCap,66,M,3229,909 +2013,BruCap,66,F,3936,991 +2013,BruCap,67,M,2728,762 +2013,BruCap,67,F,3551,900 +2013,BruCap,68,M,2904,710 +2013,BruCap,68,F,3567,900 +2013,BruCap,69,M,2655,699 +2013,BruCap,69,F,3344,780 +2013,BruCap,70,M,2387,637 +2013,BruCap,70,F,3001,754 +2013,BruCap,71,M,1955,554 +2013,BruCap,71,F,2581,660 +2013,BruCap,72,M,2271,633 +2013,BruCap,72,F,3013,786 +2013,BruCap,73,M,2245,572 +2013,BruCap,73,F,3079,727 +2013,BruCap,74,M,2201,533 +2013,BruCap,74,F,3011,690 +2013,BruCap,75,M,2065,489 +2013,BruCap,75,F,2882,628 +2013,BruCap,76,M,2025,475 +2013,BruCap,76,F,2859,670 +2013,BruCap,77,M,1909,429 +2013,BruCap,77,F,2920,594 +2013,BruCap,78,M,1898,402 +2013,BruCap,78,F,2865,552 +2013,BruCap,79,M,1760,345 +2013,BruCap,79,F,2858,484 +2013,BruCap,80,M,1763,343 +2013,BruCap,80,F,2910,430 +2013,BruCap,81,M,1659,271 +2013,BruCap,81,F,2773,409 +2013,BruCap,82,M,1537,299 +2013,BruCap,82,F,2964,465 +2013,BruCap,83,M,1389,238 +2013,BruCap,83,F,2726,328 +2013,BruCap,84,M,1276,190 +2013,BruCap,84,F,2568,312 +2013,BruCap,85,M,1140,146 +2013,BruCap,85,F,2410,278 +2013,BruCap,86,M,1048,136 +2013,BruCap,86,F,2302,226 +2013,BruCap,87,M,873,120 +2013,BruCap,87,F,2180,186 +2013,BruCap,88,M,865,86 +2013,BruCap,88,F,2001,166 +2013,BruCap,89,M,605,65 +2013,BruCap,89,F,1806,155 +2013,BruCap,90,M,560,69 +2013,BruCap,90,F,1555,114 +2013,BruCap,91,M,529,48 +2013,BruCap,91,F,1342,103 +2013,BruCap,92,M,350,36 +2013,BruCap,92,F,1109,101 +2013,BruCap,93,M,192,22 +2013,BruCap,93,F,690,53 +2013,BruCap,94,M,103,15 +2013,BruCap,94,F,403,38 +2013,BruCap,95,M,82,10 +2013,BruCap,95,F,308,25 +2013,BruCap,96,M,51,6 +2013,BruCap,96,F,242,28 +2013,BruCap,97,M,36,4 +2013,BruCap,97,F,219,12 +2013,BruCap,98,M,34,5 +2013,BruCap,98,F,202,15 +2013,BruCap,99,M,23,1 +2013,BruCap,99,F,119,7 +2013,BruCap,100,M,14,3 +2013,BruCap,100,F,80,7 +2013,BruCap,101,M,10,4 +2013,BruCap,101,F,49,2 +2013,BruCap,102,M,5,1 +2013,BruCap,102,F,26,5 +2013,BruCap,103,M,0,0 +2013,BruCap,103,F,14,5 +2013,BruCap,104,M,1,0 +2013,BruCap,104,F,15,2 +2013,BruCap,105,M,0,0 +2013,BruCap,105,F,7,0 +2013,BruCap,106,M,1,0 +2013,BruCap,106,F,5,0 +2013,BruCap,107,M,0,0 +2013,BruCap,107,F,1,0 +2013,BruCap,108,M,0,0 +2013,BruCap,108,F,0,0 +2013,BruCap,109,M,0,0 +2013,BruCap,109,F,0,0 +2013,BruCap,110,M,0,0 +2013,BruCap,110,F,0,0 +2013,BruCap,111,M,0,0 +2013,BruCap,111,F,0,0 +2013,BruCap,112,M,0,1 +2013,BruCap,112,F,0,0 +2013,BruCap,113,M,0,0 +2013,BruCap,113,F,0,0 +2013,BruCap,114,M,0,0 +2013,BruCap,114,F,0,0 +2013,BruCap,115,M,0,0 +2013,BruCap,115,F,0,0 +2013,BruCap,116,M,0,0 +2013,BruCap,116,F,0,0 +2013,BruCap,117,M,0,0 +2013,BruCap,117,F,0,0 +2013,BruCap,118,M,0,0 +2013,BruCap,118,F,0,0 +2013,BruCap,119,M,0,0 +2013,BruCap,119,F,0,0 +2013,BruCap,120,M,0,0 +2013,BruCap,120,F,0,0 +2013,Fla,0,M,31598,3445 +2013,Fla,0,F,30204,3337 +2013,Fla,1,M,32683,3324 +2013,Fla,1,F,31064,3184 +2013,Fla,2,M,33400,3257 +2013,Fla,2,F,31999,3141 +2013,Fla,3,M,33619,3048 +2013,Fla,3,F,31786,2973 +2013,Fla,4,M,34223,2984 +2013,Fla,4,F,32582,2807 +2013,Fla,5,M,33201,2866 +2013,Fla,5,F,32022,2742 +2013,Fla,6,M,33066,2753 +2013,Fla,6,F,31792,2607 +2013,Fla,7,M,32685,2606 +2013,Fla,7,F,30861,2427 +2013,Fla,8,M,32163,2520 +2013,Fla,8,F,30504,2463 +2013,Fla,9,M,31010,2506 +2013,Fla,9,F,29655,2361 +2013,Fla,10,M,31020,2409 +2013,Fla,10,F,29480,2363 +2013,Fla,11,M,31288,2368 +2013,Fla,11,F,30059,2242 +2013,Fla,12,M,32048,2503 +2013,Fla,12,F,30754,2326 +2013,Fla,13,M,31926,2338 +2013,Fla,13,F,30920,2199 +2013,Fla,14,M,32822,2265 +2013,Fla,14,F,31249,2160 +2013,Fla,15,M,33484,2236 +2013,Fla,15,F,32243,2129 +2013,Fla,16,M,33530,2175 +2013,Fla,16,F,32304,2104 +2013,Fla,17,M,33651,2290 +2013,Fla,17,F,32377,2060 +2013,Fla,18,M,34116,2430 +2013,Fla,18,F,32465,2096 +2013,Fla,19,M,35443,2314 +2013,Fla,19,F,34329,2235 +2013,Fla,20,M,36534,2575 +2013,Fla,20,F,35144,2593 +2013,Fla,21,M,36974,2771 +2013,Fla,21,F,35200,3049 +2013,Fla,22,M,36505,3038 +2013,Fla,22,F,34961,3616 +2013,Fla,23,M,35164,3344 +2013,Fla,23,F,33683,4162 +2013,Fla,24,M,34510,3782 +2013,Fla,24,F,33395,4597 +2013,Fla,25,M,34087,3992 +2013,Fla,25,F,32625,4859 +2013,Fla,26,M,33915,4279 +2013,Fla,26,F,32647,5123 +2013,Fla,27,M,32770,4686 +2013,Fla,27,F,32116,5228 +2013,Fla,28,M,33536,4823 +2013,Fla,28,F,32839,5305 +2013,Fla,29,M,34338,4913 +2013,Fla,29,F,34017,5206 +2013,Fla,30,M,35329,5114 +2013,Fla,30,F,34524,5199 +2013,Fla,31,M,36554,4965 +2013,Fla,31,F,35463,5024 +2013,Fla,32,M,36119,5224 +2013,Fla,32,F,36111,5134 +2013,Fla,33,M,36733,5036 +2013,Fla,33,F,35846,4947 +2013,Fla,34,M,35969,4946 +2013,Fla,34,F,35883,4814 +2013,Fla,35,M,35342,4954 +2013,Fla,35,F,35249,4713 +2013,Fla,36,M,34848,4901 +2013,Fla,36,F,34366,4510 +2013,Fla,37,M,34064,4784 +2013,Fla,37,F,33589,4537 +2013,Fla,38,M,35437,4752 +2013,Fla,38,F,35144,4287 +2013,Fla,39,M,36802,4618 +2013,Fla,39,F,36145,4193 +2013,Fla,40,M,38447,4710 +2013,Fla,40,F,38182,4142 +2013,Fla,41,M,39978,4617 +2013,Fla,41,F,40015,4011 +2013,Fla,42,M,41224,4773 +2013,Fla,42,F,40799,4115 +2013,Fla,43,M,41206,4546 +2013,Fla,43,F,40681,3876 +2013,Fla,44,M,41510,4514 +2013,Fla,44,F,41042,3822 +2013,Fla,45,M,42892,4169 +2013,Fla,45,F,41574,3452 +2013,Fla,46,M,44185,4202 +2013,Fla,46,F,43423,3395 +2013,Fla,47,M,45584,4100 +2013,Fla,47,F,44568,3286 +2013,Fla,48,M,47231,3937 +2013,Fla,48,F,46611,3124 +2013,Fla,49,M,46805,3735 +2013,Fla,49,F,46006,2913 +2013,Fla,50,M,46208,3492 +2013,Fla,50,F,45221,2756 +2013,Fla,51,M,45451,3258 +2013,Fla,51,F,45403,2574 +2013,Fla,52,M,44578,3193 +2013,Fla,52,F,44284,2559 +2013,Fla,53,M,44973,2950 +2013,Fla,53,F,44671,2359 +2013,Fla,54,M,43951,2929 +2013,Fla,54,F,43374,2139 +2013,Fla,55,M,43082,2682 +2013,Fla,55,F,42572,2034 +2013,Fla,56,M,41738,2527 +2013,Fla,56,F,41902,1950 +2013,Fla,57,M,40872,2427 +2013,Fla,57,F,41276,1900 +2013,Fla,58,M,39817,2319 +2013,Fla,58,F,40054,1828 +2013,Fla,59,M,38743,2142 +2013,Fla,59,F,38531,1708 +2013,Fla,60,M,38418,2047 +2013,Fla,60,F,38163,1629 +2013,Fla,61,M,36293,2006 +2013,Fla,61,F,36558,1507 +2013,Fla,62,M,35602,1928 +2013,Fla,62,F,36391,1638 +2013,Fla,63,M,35472,1989 +2013,Fla,63,F,35866,1551 +2013,Fla,64,M,35098,1904 +2013,Fla,64,F,36228,1489 +2013,Fla,65,M,34327,1820 +2013,Fla,65,F,35623,1442 +2013,Fla,66,M,34856,1778 +2013,Fla,66,F,36030,1338 +2013,Fla,67,M,30409,1459 +2013,Fla,67,F,32204,1165 +2013,Fla,68,M,29897,1429 +2013,Fla,68,F,31808,1246 +2013,Fla,69,M,28128,1390 +2013,Fla,69,F,30381,1081 +2013,Fla,70,M,24255,1246 +2013,Fla,70,F,26367,1072 +2013,Fla,71,M,21415,1136 +2013,Fla,71,F,23973,930 +2013,Fla,72,M,23093,1130 +2013,Fla,72,F,26420,1119 +2013,Fla,73,M,24757,1045 +2013,Fla,73,F,29108,920 +2013,Fla,74,M,25118,996 +2013,Fla,74,F,29363,893 +2013,Fla,75,M,23766,890 +2013,Fla,75,F,28031,820 +2013,Fla,76,M,22003,826 +2013,Fla,76,F,27083,781 +2013,Fla,77,M,21063,780 +2013,Fla,77,F,26520,710 +2013,Fla,78,M,20352,699 +2013,Fla,78,F,26435,718 +2013,Fla,79,M,19163,666 +2013,Fla,79,F,25676,605 +2013,Fla,80,M,18309,590 +2013,Fla,80,F,25835,559 +2013,Fla,81,M,17101,531 +2013,Fla,81,F,24863,441 +2013,Fla,82,M,15615,467 +2013,Fla,82,F,23493,513 +2013,Fla,83,M,13043,378 +2013,Fla,83,F,20927,394 +2013,Fla,84,M,11515,322 +2013,Fla,84,F,19132,398 +2013,Fla,85,M,10048,260 +2013,Fla,85,F,17189,321 +2013,Fla,86,M,8544,199 +2013,Fla,86,F,15878,298 +2013,Fla,87,M,7372,204 +2013,Fla,87,F,14153,249 +2013,Fla,88,M,6088,148 +2013,Fla,88,F,12485,227 +2013,Fla,89,M,5020,110 +2013,Fla,89,F,10892,211 +2013,Fla,90,M,3872,98 +2013,Fla,90,F,8808,154 +2013,Fla,91,M,3037,73 +2013,Fla,91,F,7401,107 +2013,Fla,92,M,2171,55 +2013,Fla,92,F,5943,95 +2013,Fla,93,M,1203,29 +2013,Fla,93,F,3574,50 +2013,Fla,94,M,619,21 +2013,Fla,94,F,1946,44 +2013,Fla,95,M,376,14 +2013,Fla,95,F,1417,38 +2013,Fla,96,M,335,7 +2013,Fla,96,F,1269,20 +2013,Fla,97,M,267,7 +2013,Fla,97,F,1065,23 +2013,Fla,98,M,179,2 +2013,Fla,98,F,800,17 +2013,Fla,99,M,107,4 +2013,Fla,99,F,564,15 +2013,Fla,100,M,62,2 +2013,Fla,100,F,376,8 +2013,Fla,101,M,44,1 +2013,Fla,101,F,242,4 +2013,Fla,102,M,12,0 +2013,Fla,102,F,122,2 +2013,Fla,103,M,11,0 +2013,Fla,103,F,91,0 +2013,Fla,104,M,5,1 +2013,Fla,104,F,43,0 +2013,Fla,105,M,1,0 +2013,Fla,105,F,13,2 +2013,Fla,106,M,0,0 +2013,Fla,106,F,9,0 +2013,Fla,107,M,1,0 +2013,Fla,107,F,7,0 +2013,Fla,108,M,0,0 +2013,Fla,108,F,1,0 +2013,Fla,109,M,0,0 +2013,Fla,109,F,1,0 +2013,Fla,110,M,0,0 +2013,Fla,110,F,1,0 +2013,Fla,111,M,0,0 +2013,Fla,111,F,0,0 +2013,Fla,112,M,0,0 +2013,Fla,112,F,0,0 +2013,Fla,113,M,0,0 +2013,Fla,113,F,0,0 +2013,Fla,114,M,0,0 +2013,Fla,114,F,1,0 +2013,Fla,115,M,0,0 +2013,Fla,115,F,0,0 +2013,Fla,116,M,0,0 +2013,Fla,116,F,0,0 +2013,Fla,117,M,0,0 +2013,Fla,117,F,0,0 +2013,Fla,118,M,0,0 +2013,Fla,118,F,0,0 +2013,Fla,119,M,0,0 +2013,Fla,119,F,0,0 +2013,Fla,120,M,0,0 +2013,Fla,120,F,0,0 +2013,Wal,0,M,18972,1367 +2013,Wal,0,F,18369,1333 +2013,Wal,1,M,19358,1469 +2013,Wal,1,F,18612,1351 +2013,Wal,2,M,20008,1337 +2013,Wal,2,F,19099,1322 +2013,Wal,3,M,20049,1335 +2013,Wal,3,F,19377,1236 +2013,Wal,4,M,20451,1280 +2013,Wal,4,F,19281,1201 +2013,Wal,5,M,20318,1256 +2013,Wal,5,F,19245,1222 +2013,Wal,6,M,20347,1257 +2013,Wal,6,F,19668,1244 +2013,Wal,7,M,20131,1199 +2013,Wal,7,F,19357,1088 +2013,Wal,8,M,20074,1234 +2013,Wal,8,F,19114,1210 +2013,Wal,9,M,19782,1253 +2013,Wal,9,F,19203,1152 +2013,Wal,10,M,19946,1236 +2013,Wal,10,F,18950,1198 +2013,Wal,11,M,20548,1204 +2013,Wal,11,F,19815,1169 +2013,Wal,12,M,20951,1215 +2013,Wal,12,F,19905,1251 +2013,Wal,13,M,20387,1222 +2013,Wal,13,F,19368,1204 +2013,Wal,14,M,20418,1194 +2013,Wal,14,F,19526,1213 +2013,Wal,15,M,20434,1251 +2013,Wal,15,F,19604,1203 +2013,Wal,16,M,20606,1277 +2013,Wal,16,F,19768,1248 +2013,Wal,17,M,20182,1355 +2013,Wal,17,F,19312,1298 +2013,Wal,18,M,20358,1425 +2013,Wal,18,F,19441,1436 +2013,Wal,19,M,21127,1402 +2013,Wal,19,F,20020,1512 +2013,Wal,20,M,22027,1524 +2013,Wal,20,F,21188,1688 +2013,Wal,21,M,22483,1544 +2013,Wal,21,F,21653,1856 +2013,Wal,22,M,22021,1786 +2013,Wal,22,F,21204,2143 +2013,Wal,23,M,21858,1824 +2013,Wal,23,F,20997,2278 +2013,Wal,24,M,21425,2059 +2013,Wal,24,F,20473,2535 +2013,Wal,25,M,20471,2181 +2013,Wal,25,F,19579,2589 +2013,Wal,26,M,20250,2356 +2013,Wal,26,F,19285,2734 +2013,Wal,27,M,19144,2432 +2013,Wal,27,F,18676,2709 +2013,Wal,28,M,18956,2521 +2013,Wal,28,F,18513,2875 +2013,Wal,29,M,18799,2648 +2013,Wal,29,F,18018,2649 +2013,Wal,30,M,18954,2764 +2013,Wal,30,F,18704,2957 +2013,Wal,31,M,19195,2724 +2013,Wal,31,F,19292,2919 +2013,Wal,32,M,19345,2931 +2013,Wal,32,F,19338,3019 +2013,Wal,33,M,19163,2897 +2013,Wal,33,F,18750,2929 +2013,Wal,34,M,18893,3043 +2013,Wal,34,F,18772,2903 +2013,Wal,35,M,19032,2907 +2013,Wal,35,F,19025,2832 +2013,Wal,36,M,19382,2774 +2013,Wal,36,F,19507,2774 +2013,Wal,37,M,19481,2911 +2013,Wal,37,F,19751,2803 +2013,Wal,38,M,20330,3075 +2013,Wal,38,F,20292,2915 +2013,Wal,39,M,21203,3254 +2013,Wal,39,F,21241,2944 +2013,Wal,40,M,21872,3279 +2013,Wal,40,F,22008,3032 +2013,Wal,41,M,22209,3305 +2013,Wal,41,F,22442,2854 +2013,Wal,42,M,21903,3271 +2013,Wal,42,F,21817,3049 +2013,Wal,43,M,21619,3220 +2013,Wal,43,F,21863,2856 +2013,Wal,44,M,21199,3189 +2013,Wal,44,F,21703,2904 +2013,Wal,45,M,21579,3209 +2013,Wal,45,F,21822,2847 +2013,Wal,46,M,21912,3499 +2013,Wal,46,F,22273,2974 +2013,Wal,47,M,22673,3407 +2013,Wal,47,F,22974,2837 +2013,Wal,48,M,23288,3260 +2013,Wal,48,F,23847,2814 +2013,Wal,49,M,22776,3217 +2013,Wal,49,F,23533,2732 +2013,Wal,50,M,22057,3136 +2013,Wal,50,F,22976,2463 +2013,Wal,51,M,22489,3043 +2013,Wal,51,F,23395,2496 +2013,Wal,52,M,22363,3250 +2013,Wal,52,F,22976,2463 +2013,Wal,53,M,22228,2995 +2013,Wal,53,F,23594,2327 +2013,Wal,54,M,21646,2990 +2013,Wal,54,F,23120,2286 +2013,Wal,55,M,21316,2898 +2013,Wal,55,F,22561,2216 +2013,Wal,56,M,20661,2929 +2013,Wal,56,F,22204,2187 +2013,Wal,57,M,20305,2822 +2013,Wal,57,F,22096,2128 +2013,Wal,58,M,20148,2687 +2013,Wal,58,F,21727,2077 +2013,Wal,59,M,19795,2583 +2013,Wal,59,F,21299,1996 +2013,Wal,60,M,19239,2556 +2013,Wal,60,F,20929,1947 +2013,Wal,61,M,18563,2407 +2013,Wal,61,F,20473,1916 +2013,Wal,62,M,18938,2353 +2013,Wal,62,F,20438,1962 +2013,Wal,63,M,18732,2310 +2013,Wal,63,F,20425,1772 +2013,Wal,64,M,18898,2275 +2013,Wal,64,F,20817,1923 +2013,Wal,65,M,18579,2203 +2013,Wal,65,F,20473,1749 +2013,Wal,66,M,17889,2089 +2013,Wal,66,F,20213,1620 +2013,Wal,67,M,13053,1583 +2013,Wal,67,F,15356,1381 +2013,Wal,68,M,12846,1607 +2013,Wal,68,F,14929,1432 +2013,Wal,69,M,11719,1425 +2013,Wal,69,F,13918,1276 +2013,Wal,70,M,10133,1298 +2013,Wal,70,F,12171,1238 +2013,Wal,71,M,9192,1232 +2013,Wal,71,F,11299,1174 +2013,Wal,72,M,10092,1375 +2013,Wal,72,F,12593,1393 +2013,Wal,73,M,10710,1290 +2013,Wal,73,F,13716,1425 +2013,Wal,74,M,10325,1121 +2013,Wal,74,F,13715,1361 +2013,Wal,75,M,9729,1116 +2013,Wal,75,F,12771,1269 +2013,Wal,76,M,9098,1042 +2013,Wal,76,F,12551,1249 +2013,Wal,77,M,8533,987 +2013,Wal,77,F,12110,1282 +2013,Wal,78,M,8476,922 +2013,Wal,78,F,12242,1270 +2013,Wal,79,M,8022,860 +2013,Wal,79,F,11945,1226 +2013,Wal,80,M,7871,810 +2013,Wal,80,F,12670,1127 +2013,Wal,81,M,7470,730 +2013,Wal,81,F,12337,1157 +2013,Wal,82,M,6769,720 +2013,Wal,82,F,11887,1107 +2013,Wal,83,M,5863,624 +2013,Wal,83,F,10681,991 +2013,Wal,84,M,5055,520 +2013,Wal,84,F,9910,864 +2013,Wal,85,M,4429,478 +2013,Wal,85,F,9143,858 +2013,Wal,86,M,3812,415 +2013,Wal,86,F,8398,789 +2013,Wal,87,M,3375,320 +2013,Wal,87,F,7827,718 +2013,Wal,88,M,2688,293 +2013,Wal,88,F,6820,604 +2013,Wal,89,M,2152,222 +2013,Wal,89,F,5753,522 +2013,Wal,90,M,1687,144 +2013,Wal,90,F,5007,436 +2013,Wal,91,M,1382,126 +2013,Wal,91,F,4255,316 +2013,Wal,92,M,978,72 +2013,Wal,92,F,3389,240 +2013,Wal,93,M,572,46 +2013,Wal,93,F,1999,159 +2013,Wal,94,M,266,14 +2013,Wal,94,F,1062,75 +2013,Wal,95,M,187,9 +2013,Wal,95,F,841,55 +2013,Wal,96,M,143,7 +2013,Wal,96,F,629,53 +2013,Wal,97,M,100,2 +2013,Wal,97,F,517,39 +2013,Wal,98,M,77,9 +2013,Wal,98,F,488,33 +2013,Wal,99,M,60,2 +2013,Wal,99,F,301,16 +2013,Wal,100,M,14,6 +2013,Wal,100,F,181,11 +2013,Wal,101,M,8,1 +2013,Wal,101,F,127,6 +2013,Wal,102,M,5,0 +2013,Wal,102,F,65,9 +2013,Wal,103,M,1,1 +2013,Wal,103,F,27,3 +2013,Wal,104,M,1,0 +2013,Wal,104,F,19,1 +2013,Wal,105,M,0,0 +2013,Wal,105,F,16,0 +2013,Wal,106,M,0,0 +2013,Wal,106,F,5,0 +2013,Wal,107,M,0,0 +2013,Wal,107,F,2,1 +2013,Wal,108,M,0,0 +2013,Wal,108,F,1,0 +2013,Wal,109,M,0,0 +2013,Wal,109,F,0,0 +2013,Wal,110,M,0,0 +2013,Wal,110,F,0,0 +2013,Wal,111,M,0,0 +2013,Wal,111,F,0,0 +2013,Wal,112,M,0,0 +2013,Wal,112,F,0,0 +2013,Wal,113,M,0,0 +2013,Wal,113,F,0,0 +2013,Wal,114,M,0,0 +2013,Wal,114,F,0,0 +2013,Wal,115,M,0,0 +2013,Wal,115,F,0,0 +2013,Wal,116,M,0,0 +2013,Wal,116,F,0,0 +2013,Wal,117,M,0,0 +2013,Wal,117,F,0,0 +2013,Wal,118,M,0,0 +2013,Wal,118,F,0,0 +2013,Wal,119,M,0,0 +2013,Wal,119,F,0,0 +2013,Wal,120,M,0,0 +2013,Wal,120,F,0,0 +2014,BruCap,0,M,6393,2936 +2014,BruCap,0,F,6010,2670 +2014,BruCap,1,M,6435,2866 +2014,BruCap,1,F,6142,2784 +2014,BruCap,2,M,6305,2701 +2014,BruCap,2,F,6009,2582 +2014,BruCap,3,M,6448,2635 +2014,BruCap,3,F,6029,2512 +2014,BruCap,4,M,6262,2397 +2014,BruCap,4,F,5953,2329 +2014,BruCap,5,M,6032,2238 +2014,BruCap,5,F,5695,2208 +2014,BruCap,6,M,5931,2131 +2014,BruCap,6,F,5623,2035 +2014,BruCap,7,M,5811,2048 +2014,BruCap,7,F,5530,1875 +2014,BruCap,8,M,5583,1860 +2014,BruCap,8,F,5312,1774 +2014,BruCap,9,M,5420,1733 +2014,BruCap,9,F,5185,1672 +2014,BruCap,10,M,5105,1763 +2014,BruCap,10,F,4927,1613 +2014,BruCap,11,M,4859,1619 +2014,BruCap,11,F,4809,1562 +2014,BruCap,12,M,4946,1557 +2014,BruCap,12,F,4867,1443 +2014,BruCap,13,M,4911,1628 +2014,BruCap,13,F,4610,1540 +2014,BruCap,14,M,4857,1530 +2014,BruCap,14,F,4628,1450 +2014,BruCap,15,M,4611,1417 +2014,BruCap,15,F,4469,1470 +2014,BruCap,16,M,4806,1459 +2014,BruCap,16,F,4481,1425 +2014,BruCap,17,M,4676,1457 +2014,BruCap,17,F,4450,1477 +2014,BruCap,18,M,4641,1568 +2014,BruCap,18,F,4436,1587 +2014,BruCap,19,M,4820,1864 +2014,BruCap,19,F,4452,1865 +2014,BruCap,20,M,4743,2034 +2014,BruCap,20,F,4620,2301 +2014,BruCap,21,M,4920,2137 +2014,BruCap,21,F,4804,2698 +2014,BruCap,22,M,4938,2327 +2014,BruCap,22,F,4909,3072 +2014,BruCap,23,M,5036,2700 +2014,BruCap,23,F,5024,3580 +2014,BruCap,24,M,5161,2890 +2014,BruCap,24,F,5361,3943 +2014,BruCap,25,M,5464,3303 +2014,BruCap,25,F,5587,4489 +2014,BruCap,26,M,5380,3671 +2014,BruCap,26,F,5732,4825 +2014,BruCap,27,M,5462,3954 +2014,BruCap,27,F,5798,4847 +2014,BruCap,28,M,5402,4231 +2014,BruCap,28,F,5480,5091 +2014,BruCap,29,M,5387,4638 +2014,BruCap,29,F,5721,5110 +2014,BruCap,30,M,5294,4567 +2014,BruCap,30,F,5434,5010 +2014,BruCap,31,M,5325,4735 +2014,BruCap,31,F,5537,5163 +2014,BruCap,32,M,5376,4724 +2014,BruCap,32,F,5532,4779 +2014,BruCap,33,M,5408,5037 +2014,BruCap,33,F,5617,4994 +2014,BruCap,34,M,5386,4890 +2014,BruCap,34,F,5292,4768 +2014,BruCap,35,M,5294,4790 +2014,BruCap,35,F,5289,4570 +2014,BruCap,36,M,5216,4721 +2014,BruCap,36,F,5201,4261 +2014,BruCap,37,M,5130,4748 +2014,BruCap,37,F,5022,4203 +2014,BruCap,38,M,5104,4456 +2014,BruCap,38,F,4766,3914 +2014,BruCap,39,M,5106,4419 +2014,BruCap,39,F,4781,3835 +2014,BruCap,40,M,5122,4221 +2014,BruCap,40,F,4884,3513 +2014,BruCap,41,M,5067,3997 +2014,BruCap,41,F,4871,3527 +2014,BruCap,42,M,5124,3764 +2014,BruCap,42,F,4784,3314 +2014,BruCap,43,M,5239,3850 +2014,BruCap,43,F,4980,3186 +2014,BruCap,44,M,5083,3716 +2014,BruCap,44,F,4799,3202 +2014,BruCap,45,M,4985,3637 +2014,BruCap,45,F,4732,2990 +2014,BruCap,46,M,4781,3346 +2014,BruCap,46,F,4554,2734 +2014,BruCap,47,M,4785,3207 +2014,BruCap,47,F,4739,2615 +2014,BruCap,48,M,4963,2933 +2014,BruCap,48,F,4870,2525 +2014,BruCap,49,M,4915,2905 +2014,BruCap,49,F,4863,2505 +2014,BruCap,50,M,4725,2709 +2014,BruCap,50,F,4788,2349 +2014,BruCap,51,M,4609,2525 +2014,BruCap,51,F,4702,2214 +2014,BruCap,52,M,4455,2424 +2014,BruCap,52,F,4730,2136 +2014,BruCap,53,M,4547,2240 +2014,BruCap,53,F,5003,2081 +2014,BruCap,54,M,4433,2073 +2014,BruCap,54,F,4770,2022 +2014,BruCap,55,M,4290,1976 +2014,BruCap,55,F,4719,1827 +2014,BruCap,56,M,4107,1752 +2014,BruCap,56,F,4609,1704 +2014,BruCap,57,M,3974,1812 +2014,BruCap,57,F,4637,1642 +2014,BruCap,58,M,4007,1625 +2014,BruCap,58,F,4530,1622 +2014,BruCap,59,M,3897,1456 +2014,BruCap,59,F,4481,1459 +2014,BruCap,60,M,3898,1331 +2014,BruCap,60,F,4426,1337 +2014,BruCap,61,M,3797,1328 +2014,BruCap,61,F,4332,1335 +2014,BruCap,62,M,3503,1116 +2014,BruCap,62,F,4037,1178 +2014,BruCap,63,M,3546,1201 +2014,BruCap,63,F,4143,1225 +2014,BruCap,64,M,3368,1070 +2014,BruCap,64,F,4005,1081 +2014,BruCap,65,M,3277,1031 +2014,BruCap,65,F,3959,1018 +2014,BruCap,66,M,3219,891 +2014,BruCap,66,F,4044,959 +2014,BruCap,67,M,3122,848 +2014,BruCap,67,F,3881,934 +2014,BruCap,68,M,2662,713 +2014,BruCap,68,F,3499,849 +2014,BruCap,69,M,2794,680 +2014,BruCap,69,F,3515,842 +2014,BruCap,70,M,2594,664 +2014,BruCap,70,F,3263,757 +2014,BruCap,71,M,2315,598 +2014,BruCap,71,F,2964,725 +2014,BruCap,72,M,1900,520 +2014,BruCap,72,F,2523,626 +2014,BruCap,73,M,2195,592 +2014,BruCap,73,F,2974,758 +2014,BruCap,74,M,2161,536 +2014,BruCap,74,F,3016,702 +2014,BruCap,75,M,2118,501 +2014,BruCap,75,F,2956,659 +2014,BruCap,76,M,1979,450 +2014,BruCap,76,F,2799,599 +2014,BruCap,77,M,1936,442 +2014,BruCap,77,F,2782,644 +2014,BruCap,78,M,1824,383 +2014,BruCap,78,F,2833,567 +2014,BruCap,79,M,1794,369 +2014,BruCap,79,F,2758,523 +2014,BruCap,80,M,1675,324 +2014,BruCap,80,F,2748,452 +2014,BruCap,81,M,1654,322 +2014,BruCap,81,F,2785,404 +2014,BruCap,82,M,1539,249 +2014,BruCap,82,F,2655,382 +2014,BruCap,83,M,1408,261 +2014,BruCap,83,F,2784,429 +2014,BruCap,84,M,1234,220 +2014,BruCap,84,F,2545,302 +2014,BruCap,85,M,1152,174 +2014,BruCap,85,F,2371,283 +2014,BruCap,86,M,1004,127 +2014,BruCap,86,F,2207,257 +2014,BruCap,87,M,909,114 +2014,BruCap,87,F,2095,198 +2014,BruCap,88,M,747,107 +2014,BruCap,88,F,1932,169 +2014,BruCap,89,M,738,67 +2014,BruCap,89,F,1744,148 +2014,BruCap,90,M,500,51 +2014,BruCap,90,F,1582,119 +2014,BruCap,91,M,465,53 +2014,BruCap,91,F,1329,104 +2014,BruCap,92,M,426,41 +2014,BruCap,92,F,1140,88 +2014,BruCap,93,M,278,31 +2014,BruCap,93,F,906,79 +2014,BruCap,94,M,144,20 +2014,BruCap,94,F,553,38 +2014,BruCap,95,M,78,13 +2014,BruCap,95,F,313,30 +2014,BruCap,96,M,59,8 +2014,BruCap,96,F,239,18 +2014,BruCap,97,M,38,5 +2014,BruCap,97,F,186,23 +2014,BruCap,98,M,25,2 +2014,BruCap,98,F,157,12 +2014,BruCap,99,M,20,2 +2014,BruCap,99,F,138,10 +2014,BruCap,100,M,16,0 +2014,BruCap,100,F,71,3 +2014,BruCap,101,M,10,2 +2014,BruCap,101,F,54,5 +2014,BruCap,102,M,8,3 +2014,BruCap,102,F,34,1 +2014,BruCap,103,M,1,0 +2014,BruCap,103,F,11,2 +2014,BruCap,104,M,0,0 +2014,BruCap,104,F,10,4 +2014,BruCap,105,M,0,0 +2014,BruCap,105,F,8,2 +2014,BruCap,106,M,0,0 +2014,BruCap,106,F,5,0 +2014,BruCap,107,M,0,0 +2014,BruCap,107,F,2,0 +2014,BruCap,108,M,0,0 +2014,BruCap,108,F,1,0 +2014,BruCap,109,M,0,0 +2014,BruCap,109,F,0,0 +2014,BruCap,110,M,0,0 +2014,BruCap,110,F,0,0 +2014,BruCap,111,M,0,0 +2014,BruCap,111,F,0,0 +2014,BruCap,112,M,0,0 +2014,BruCap,112,F,0,0 +2014,BruCap,113,M,0,1 +2014,BruCap,113,F,0,0 +2014,BruCap,114,M,0,0 +2014,BruCap,114,F,0,0 +2014,BruCap,115,M,0,0 +2014,BruCap,115,F,0,0 +2014,BruCap,116,M,0,0 +2014,BruCap,116,F,0,0 +2014,BruCap,117,M,0,0 +2014,BruCap,117,F,0,0 +2014,BruCap,118,M,0,0 +2014,BruCap,118,F,0,0 +2014,BruCap,119,M,0,0 +2014,BruCap,119,F,0,0 +2014,BruCap,120,M,0,0 +2014,BruCap,120,F,0,0 +2014,Fla,0,M,31080,3442 +2014,Fla,0,F,29730,3292 +2014,Fla,1,M,31967,3450 +2014,Fla,1,F,30620,3297 +2014,Fla,2,M,33027,3337 +2014,Fla,2,F,31363,3216 +2014,Fla,3,M,33717,3271 +2014,Fla,3,F,32278,3177 +2014,Fla,4,M,33904,3063 +2014,Fla,4,F,32066,3011 +2014,Fla,5,M,34462,2959 +2014,Fla,5,F,32784,2830 +2014,Fla,6,M,33433,2891 +2014,Fla,6,F,32210,2774 +2014,Fla,7,M,33239,2732 +2014,Fla,7,F,31983,2612 +2014,Fla,8,M,32878,2649 +2014,Fla,8,F,31016,2524 +2014,Fla,9,M,32322,2568 +2014,Fla,9,F,30661,2501 +2014,Fla,10,M,31145,2554 +2014,Fla,10,F,29782,2381 +2014,Fla,11,M,31183,2422 +2014,Fla,11,F,29642,2404 +2014,Fla,12,M,31408,2391 +2014,Fla,12,F,30190,2267 +2014,Fla,13,M,32200,2535 +2014,Fla,13,F,30882,2362 +2014,Fla,14,M,32055,2381 +2014,Fla,14,F,31068,2237 +2014,Fla,15,M,32970,2311 +2014,Fla,15,F,31363,2160 +2014,Fla,16,M,33590,2309 +2014,Fla,16,F,32343,2209 +2014,Fla,17,M,33619,2293 +2014,Fla,17,F,32455,2149 +2014,Fla,18,M,33736,2480 +2014,Fla,18,F,32467,2202 +2014,Fla,19,M,34141,2625 +2014,Fla,19,F,32481,2317 +2014,Fla,20,M,35459,2605 +2014,Fla,20,F,34386,2572 +2014,Fla,21,M,36535,2866 +2014,Fla,21,F,35195,2981 +2014,Fla,22,M,37023,3104 +2014,Fla,22,F,35245,3569 +2014,Fla,23,M,36449,3428 +2014,Fla,23,F,34992,4096 +2014,Fla,24,M,35053,3759 +2014,Fla,24,F,33646,4606 +2014,Fla,25,M,34371,4154 +2014,Fla,25,F,33331,5053 +2014,Fla,26,M,33987,4297 +2014,Fla,26,F,32600,5221 +2014,Fla,27,M,33838,4556 +2014,Fla,27,F,32682,5343 +2014,Fla,28,M,32687,5061 +2014,Fla,28,F,32201,5486 +2014,Fla,29,M,33536,5159 +2014,Fla,29,F,32976,5541 +2014,Fla,30,M,34406,5124 +2014,Fla,30,F,34173,5399 +2014,Fla,31,M,35484,5281 +2014,Fla,31,F,34714,5366 +2014,Fla,32,M,36660,5175 +2014,Fla,32,F,35630,5149 +2014,Fla,33,M,36262,5391 +2014,Fla,33,F,36330,5274 +2014,Fla,34,M,36875,5202 +2014,Fla,34,F,36075,5052 +2014,Fla,35,M,36108,5005 +2014,Fla,35,F,36069,4886 +2014,Fla,36,M,35500,5037 +2014,Fla,36,F,35476,4766 +2014,Fla,37,M,35012,4914 +2014,Fla,37,F,34566,4604 +2014,Fla,38,M,34210,4821 +2014,Fla,38,F,33761,4557 +2014,Fla,39,M,35482,4757 +2014,Fla,39,F,35278,4334 +2014,Fla,40,M,36880,4638 +2014,Fla,40,F,36267,4198 +2014,Fla,41,M,38510,4743 +2014,Fla,41,F,38287,4188 +2014,Fla,42,M,40005,4637 +2014,Fla,42,F,40114,4024 +2014,Fla,43,M,41282,4742 +2014,Fla,43,F,40851,4111 +2014,Fla,44,M,41217,4560 +2014,Fla,44,F,40767,3845 +2014,Fla,45,M,41499,4524 +2014,Fla,45,F,41138,3799 +2014,Fla,46,M,42896,4150 +2014,Fla,46,F,41617,3446 +2014,Fla,47,M,44165,4174 +2014,Fla,47,F,43407,3372 +2014,Fla,48,M,45577,4004 +2014,Fla,48,F,44594,3285 +2014,Fla,49,M,47156,3926 +2014,Fla,49,F,46624,3109 +2014,Fla,50,M,46724,3671 +2014,Fla,50,F,45917,2886 +2014,Fla,51,M,46135,3422 +2014,Fla,51,F,45190,2736 +2014,Fla,52,M,45347,3214 +2014,Fla,52,F,45339,2516 +2014,Fla,53,M,44472,3154 +2014,Fla,53,F,44211,2506 +2014,Fla,54,M,44843,2885 +2014,Fla,54,F,44598,2307 +2014,Fla,55,M,43754,2905 +2014,Fla,55,F,43266,2096 +2014,Fla,56,M,42877,2602 +2014,Fla,56,F,42437,1998 +2014,Fla,57,M,41528,2506 +2014,Fla,57,F,41744,1918 +2014,Fla,58,M,40645,2366 +2014,Fla,58,F,41128,1834 +2014,Fla,59,M,39523,2278 +2014,Fla,59,F,39906,1778 +2014,Fla,60,M,38403,2086 +2014,Fla,60,F,38379,1660 +2014,Fla,61,M,38092,2011 +2014,Fla,61,F,37987,1578 +2014,Fla,62,M,35930,1938 +2014,Fla,62,F,36364,1464 +2014,Fla,63,M,35262,1867 +2014,Fla,63,F,36174,1579 +2014,Fla,64,M,35111,1946 +2014,Fla,64,F,35665,1507 +2014,Fla,65,M,34702,1849 +2014,Fla,65,F,35994,1449 +2014,Fla,66,M,33859,1763 +2014,Fla,66,F,35341,1403 +2014,Fla,67,M,34325,1717 +2014,Fla,67,F,35696,1310 +2014,Fla,68,M,29907,1426 +2014,Fla,68,F,31933,1127 +2014,Fla,69,M,29349,1400 +2014,Fla,69,F,31504,1199 +2014,Fla,70,M,27612,1336 +2014,Fla,70,F,30083,1055 +2014,Fla,71,M,23746,1196 +2014,Fla,71,F,26065,1041 +2014,Fla,72,M,20895,1101 +2014,Fla,72,F,23702,913 +2014,Fla,73,M,22486,1090 +2014,Fla,73,F,26034,1055 +2014,Fla,74,M,23999,1004 +2014,Fla,74,F,28692,886 +2014,Fla,75,M,24371,951 +2014,Fla,75,F,28870,856 +2014,Fla,76,M,22936,842 +2014,Fla,76,F,27500,796 +2014,Fla,77,M,21170,789 +2014,Fla,77,F,26480,746 +2014,Fla,78,M,20122,728 +2014,Fla,78,F,25873,676 +2014,Fla,79,M,19354,649 +2014,Fla,79,F,25725,678 +2014,Fla,80,M,18163,612 +2014,Fla,80,F,24858,570 +2014,Fla,81,M,17153,533 +2014,Fla,81,F,24893,519 +2014,Fla,82,M,15906,477 +2014,Fla,82,F,23717,416 +2014,Fla,83,M,14418,437 +2014,Fla,83,F,22314,478 +2014,Fla,84,M,11898,340 +2014,Fla,84,F,19737,369 +2014,Fla,85,M,10334,289 +2014,Fla,85,F,17866,356 +2014,Fla,86,M,8914,222 +2014,Fla,86,F,15818,288 +2014,Fla,87,M,7418,177 +2014,Fla,87,F,14448,263 +2014,Fla,88,M,6341,185 +2014,Fla,88,F,12720,211 +2014,Fla,89,M,5093,122 +2014,Fla,89,F,11022,197 +2014,Fla,90,M,4188,87 +2014,Fla,90,F,9389,179 +2014,Fla,91,M,3113,77 +2014,Fla,91,F,7480,128 +2014,Fla,92,M,2389,51 +2014,Fla,92,F,6145,88 +2014,Fla,93,M,1655,42 +2014,Fla,93,F,4856,77 +2014,Fla,94,M,856,23 +2014,Fla,94,F,2861,39 +2014,Fla,95,M,456,17 +2014,Fla,95,F,1478,33 +2014,Fla,96,M,255,9 +2014,Fla,96,F,1063,29 +2014,Fla,97,M,211,7 +2014,Fla,97,F,921,15 +2014,Fla,98,M,176,3 +2014,Fla,98,F,741,20 +2014,Fla,99,M,108,2 +2014,Fla,99,F,551,11 +2014,Fla,100,M,57,3 +2014,Fla,100,F,370,10 +2014,Fla,101,M,34,0 +2014,Fla,101,F,242,7 +2014,Fla,102,M,24,0 +2014,Fla,102,F,146,3 +2014,Fla,103,M,7,0 +2014,Fla,103,F,66,2 +2014,Fla,104,M,5,0 +2014,Fla,104,F,56,0 +2014,Fla,105,M,2,1 +2014,Fla,105,F,20,0 +2014,Fla,106,M,0,0 +2014,Fla,106,F,6,2 +2014,Fla,107,M,0,0 +2014,Fla,107,F,6,0 +2014,Fla,108,M,1,0 +2014,Fla,108,F,3,0 +2014,Fla,109,M,0,0 +2014,Fla,109,F,1,0 +2014,Fla,110,M,0,0 +2014,Fla,110,F,0,0 +2014,Fla,111,M,0,0 +2014,Fla,111,F,1,0 +2014,Fla,112,M,0,0 +2014,Fla,112,F,0,0 +2014,Fla,113,M,0,0 +2014,Fla,113,F,0,0 +2014,Fla,114,M,0,0 +2014,Fla,114,F,0,0 +2014,Fla,115,M,0,0 +2014,Fla,115,F,1,0 +2014,Fla,116,M,0,0 +2014,Fla,116,F,0,0 +2014,Fla,117,M,0,0 +2014,Fla,117,F,0,0 +2014,Fla,118,M,0,0 +2014,Fla,118,F,0,0 +2014,Fla,119,M,0,0 +2014,Fla,119,F,0,0 +2014,Fla,120,M,0,0 +2014,Fla,120,F,0,0 +2014,Wal,0,M,18669,1341 +2014,Wal,0,F,17837,1291 +2014,Wal,1,M,19240,1348 +2014,Wal,1,F,18579,1320 +2014,Wal,2,M,19548,1457 +2014,Wal,2,F,18837,1347 +2014,Wal,3,M,20171,1334 +2014,Wal,3,F,19280,1304 +2014,Wal,4,M,20152,1355 +2014,Wal,4,F,19511,1222 +2014,Wal,5,M,20606,1287 +2014,Wal,5,F,19413,1222 +2014,Wal,6,M,20434,1273 +2014,Wal,6,F,19344,1225 +2014,Wal,7,M,20457,1266 +2014,Wal,7,F,19732,1259 +2014,Wal,8,M,20192,1238 +2014,Wal,8,F,19458,1103 +2014,Wal,9,M,20162,1232 +2014,Wal,9,F,19202,1225 +2014,Wal,10,M,19898,1265 +2014,Wal,10,F,19259,1157 +2014,Wal,11,M,20025,1272 +2014,Wal,11,F,19010,1196 +2014,Wal,12,M,20625,1219 +2014,Wal,12,F,19913,1180 +2014,Wal,13,M,21019,1251 +2014,Wal,13,F,19994,1249 +2014,Wal,14,M,20445,1218 +2014,Wal,14,F,19423,1202 +2014,Wal,15,M,20517,1181 +2014,Wal,15,F,19595,1223 +2014,Wal,16,M,20502,1264 +2014,Wal,16,F,19683,1238 +2014,Wal,17,M,20668,1345 +2014,Wal,17,F,19824,1300 +2014,Wal,18,M,20277,1432 +2014,Wal,18,F,19391,1411 +2014,Wal,19,M,20349,1490 +2014,Wal,19,F,19467,1506 +2014,Wal,20,M,21100,1454 +2014,Wal,20,F,20032,1647 +2014,Wal,21,M,22006,1638 +2014,Wal,21,F,21136,1877 +2014,Wal,22,M,22443,1605 +2014,Wal,22,F,21666,2011 +2014,Wal,23,M,21947,1925 +2014,Wal,23,F,21167,2321 +2014,Wal,24,M,21745,1972 +2014,Wal,24,F,20818,2460 +2014,Wal,25,M,21227,2196 +2014,Wal,25,F,20210,2663 +2014,Wal,26,M,20338,2325 +2014,Wal,26,F,19495,2729 +2014,Wal,27,M,20134,2515 +2014,Wal,27,F,19266,2797 +2014,Wal,28,M,19142,2530 +2014,Wal,28,F,18734,2823 +2014,Wal,29,M,18984,2647 +2014,Wal,29,F,18647,2930 +2014,Wal,30,M,18850,2723 +2014,Wal,30,F,18160,2702 +2014,Wal,31,M,19071,2820 +2014,Wal,31,F,18839,3043 +2014,Wal,32,M,19288,2824 +2014,Wal,32,F,19449,2950 +2014,Wal,33,M,19449,2979 +2014,Wal,33,F,19511,3093 +2014,Wal,34,M,19290,2928 +2014,Wal,34,F,18865,2954 +2014,Wal,35,M,18996,3033 +2014,Wal,35,F,18911,2935 +2014,Wal,36,M,19135,2898 +2014,Wal,36,F,19137,2905 +2014,Wal,37,M,19469,2791 +2014,Wal,37,F,19631,2792 +2014,Wal,38,M,19573,2944 +2014,Wal,38,F,19874,2796 +2014,Wal,39,M,20379,3072 +2014,Wal,39,F,20390,2933 +2014,Wal,40,M,21260,3261 +2014,Wal,40,F,21345,2940 +2014,Wal,41,M,21960,3264 +2014,Wal,41,F,22092,3004 +2014,Wal,42,M,22281,3301 +2014,Wal,42,F,22531,2847 +2014,Wal,43,M,21948,3233 +2014,Wal,43,F,21912,2974 +2014,Wal,44,M,21648,3209 +2014,Wal,44,F,21902,2821 +2014,Wal,45,M,21270,3170 +2014,Wal,45,F,21735,2880 +2014,Wal,46,M,21603,3171 +2014,Wal,46,F,21874,2847 +2014,Wal,47,M,21947,3462 +2014,Wal,47,F,22308,2950 +2014,Wal,48,M,22695,3375 +2014,Wal,48,F,22990,2788 +2014,Wal,49,M,23296,3203 +2014,Wal,49,F,23871,2801 +2014,Wal,50,M,22728,3193 +2014,Wal,50,F,23514,2702 +2014,Wal,51,M,22023,3106 +2014,Wal,51,F,22954,2427 +2014,Wal,52,M,22397,3039 +2014,Wal,52,F,23365,2462 +2014,Wal,53,M,22287,3192 +2014,Wal,53,F,22950,2435 +2014,Wal,54,M,22104,2983 +2014,Wal,54,F,23560,2305 +2014,Wal,55,M,21517,2959 +2014,Wal,55,F,23087,2252 +2014,Wal,56,M,21226,2868 +2014,Wal,56,F,22535,2178 +2014,Wal,57,M,20501,2889 +2014,Wal,57,F,22126,2143 +2014,Wal,58,M,20138,2804 +2014,Wal,58,F,22023,2087 +2014,Wal,59,M,19964,2651 +2014,Wal,59,F,21624,2073 +2014,Wal,60,M,19569,2533 +2014,Wal,60,F,21220,1960 +2014,Wal,61,M,18994,2516 +2014,Wal,61,F,20834,1922 +2014,Wal,62,M,18343,2345 +2014,Wal,62,F,20322,1887 +2014,Wal,63,M,18672,2315 +2014,Wal,63,F,20315,1922 +2014,Wal,64,M,18457,2255 +2014,Wal,64,F,20266,1741 +2014,Wal,65,M,18586,2201 +2014,Wal,65,F,20639,1870 +2014,Wal,66,M,18227,2137 +2014,Wal,66,F,20288,1708 +2014,Wal,67,M,17567,2011 +2014,Wal,67,F,20022,1594 +2014,Wal,68,M,12796,1538 +2014,Wal,68,F,15196,1344 +2014,Wal,69,M,12550,1549 +2014,Wal,69,F,14782,1400 +2014,Wal,70,M,11411,1392 +2014,Wal,70,F,13727,1252 +2014,Wal,71,M,9846,1243 +2014,Wal,71,F,12032,1205 +2014,Wal,72,M,8969,1190 +2014,Wal,72,F,11099,1144 +2014,Wal,73,M,9785,1322 +2014,Wal,73,F,12377,1363 +2014,Wal,74,M,10320,1241 +2014,Wal,74,F,13446,1379 +2014,Wal,75,M,9928,1061 +2014,Wal,75,F,13426,1324 +2014,Wal,76,M,9317,1043 +2014,Wal,76,F,12464,1233 +2014,Wal,77,M,8671,968 +2014,Wal,77,F,12237,1210 +2014,Wal,78,M,8078,931 +2014,Wal,78,F,11775,1242 +2014,Wal,79,M,7977,861 +2014,Wal,79,F,11831,1232 +2014,Wal,80,M,7548,803 +2014,Wal,80,F,11462,1174 +2014,Wal,81,M,7337,756 +2014,Wal,81,F,12131,1085 +2014,Wal,82,M,6918,667 +2014,Wal,82,F,11698,1102 +2014,Wal,83,M,6229,657 +2014,Wal,83,F,11210,1060 +2014,Wal,84,M,5296,561 +2014,Wal,84,F,9942,929 +2014,Wal,85,M,4536,455 +2014,Wal,85,F,9174,780 +2014,Wal,86,M,3880,409 +2014,Wal,86,F,8325,791 +2014,Wal,87,M,3278,349 +2014,Wal,87,F,7537,715 +2014,Wal,88,M,2880,270 +2014,Wal,88,F,6909,642 +2014,Wal,89,M,2208,223 +2014,Wal,89,F,5944,531 +2014,Wal,90,M,1754,167 +2014,Wal,90,F,4903,442 +2014,Wal,91,M,1381,109 +2014,Wal,91,F,4234,369 +2014,Wal,92,M,1070,103 +2014,Wal,92,F,3501,270 +2014,Wal,93,M,727,57 +2014,Wal,93,F,2716,196 +2014,Wal,94,M,425,37 +2014,Wal,94,F,1545,133 +2014,Wal,95,M,195,13 +2014,Wal,95,F,780,57 +2014,Wal,96,M,124,5 +2014,Wal,96,F,631,36 +2014,Wal,97,M,89,4 +2014,Wal,97,F,467,32 +2014,Wal,98,M,73,1 +2014,Wal,98,F,365,28 +2014,Wal,99,M,48,4 +2014,Wal,99,F,323,25 +2014,Wal,100,M,40,1 +2014,Wal,100,F,205,10 +2014,Wal,101,M,9,5 +2014,Wal,101,F,117,5 +2014,Wal,102,M,3,1 +2014,Wal,102,F,78,4 +2014,Wal,103,M,3,0 +2014,Wal,103,F,35,3 +2014,Wal,104,M,1,1 +2014,Wal,104,F,14,2 +2014,Wal,105,M,0,0 +2014,Wal,105,F,10,1 +2014,Wal,106,M,0,0 +2014,Wal,106,F,8,0 +2014,Wal,107,M,0,0 +2014,Wal,107,F,1,0 +2014,Wal,108,M,0,0 +2014,Wal,108,F,1,1 +2014,Wal,109,M,0,0 +2014,Wal,109,F,1,0 +2014,Wal,110,M,0,0 +2014,Wal,110,F,0,0 +2014,Wal,111,M,0,0 +2014,Wal,111,F,0,0 +2014,Wal,112,M,0,0 +2014,Wal,112,F,0,0 +2014,Wal,113,M,0,0 +2014,Wal,113,F,0,0 +2014,Wal,114,M,0,0 +2014,Wal,114,F,0,0 +2014,Wal,115,M,0,0 +2014,Wal,115,F,0,0 +2014,Wal,116,M,0,0 +2014,Wal,116,F,0,0 +2014,Wal,117,M,0,0 +2014,Wal,117,F,0,0 +2014,Wal,118,M,0,0 +2014,Wal,118,F,0,0 +2014,Wal,119,M,0,0 +2014,Wal,119,F,0,0 +2014,Wal,120,M,0,0 +2014,Wal,120,F,0,0 +2015,BruCap,0,M,6271,3025 +2015,BruCap,0,F,6020,2891 +2015,BruCap,1,M,6216,2961 +2015,BruCap,1,F,5882,2745 +2015,BruCap,2,M,6254,2800 +2015,BruCap,2,F,6023,2746 +2015,BruCap,3,M,6109,2682 +2015,BruCap,3,F,5861,2570 +2015,BruCap,4,M,6321,2617 +2015,BruCap,4,F,5886,2497 +2015,BruCap,5,M,6115,2407 +2015,BruCap,5,F,5837,2347 +2015,BruCap,6,M,5932,2222 +2015,BruCap,6,F,5572,2226 +2015,BruCap,7,M,5826,2118 +2015,BruCap,7,F,5552,2033 +2015,BruCap,8,M,5693,2008 +2015,BruCap,8,F,5425,1868 +2015,BruCap,9,M,5504,1874 +2015,BruCap,9,F,5243,1774 +2015,BruCap,10,M,5352,1743 +2015,BruCap,10,F,5124,1670 +2015,BruCap,11,M,5052,1748 +2015,BruCap,11,F,4865,1627 +2015,BruCap,12,M,4808,1626 +2015,BruCap,12,F,4758,1544 +2015,BruCap,13,M,4886,1604 +2015,BruCap,13,F,4807,1470 +2015,BruCap,14,M,4846,1637 +2015,BruCap,14,F,4587,1538 +2015,BruCap,15,M,4806,1577 +2015,BruCap,15,F,4593,1476 +2015,BruCap,16,M,4613,1421 +2015,BruCap,16,F,4429,1504 +2015,BruCap,17,M,4784,1540 +2015,BruCap,17,F,4466,1468 +2015,BruCap,18,M,4715,1628 +2015,BruCap,18,F,4517,1679 +2015,BruCap,19,M,4681,1818 +2015,BruCap,19,F,4461,1955 +2015,BruCap,20,M,4824,2123 +2015,BruCap,20,F,4464,2255 +2015,BruCap,21,M,4758,2237 +2015,BruCap,21,F,4640,2806 +2015,BruCap,22,M,4921,2396 +2015,BruCap,22,F,4887,3132 +2015,BruCap,23,M,4970,2723 +2015,BruCap,23,F,5020,3586 +2015,BruCap,24,M,5209,3113 +2015,BruCap,24,F,5247,4169 +2015,BruCap,25,M,5357,3304 +2015,BruCap,25,F,5567,4482 +2015,BruCap,26,M,5623,3824 +2015,BruCap,26,F,5658,4981 +2015,BruCap,27,M,5435,4077 +2015,BruCap,27,F,5730,5144 +2015,BruCap,28,M,5428,4284 +2015,BruCap,28,F,5686,5150 +2015,BruCap,29,M,5361,4464 +2015,BruCap,29,F,5364,5262 +2015,BruCap,30,M,5272,4810 +2015,BruCap,30,F,5549,5220 +2015,BruCap,31,M,5177,4726 +2015,BruCap,31,F,5292,5087 +2015,BruCap,32,M,5230,4860 +2015,BruCap,32,F,5359,5213 +2015,BruCap,33,M,5231,4859 +2015,BruCap,33,F,5345,4781 +2015,BruCap,34,M,5312,5135 +2015,BruCap,34,F,5491,5041 +2015,BruCap,35,M,5294,4918 +2015,BruCap,35,F,5146,4777 +2015,BruCap,36,M,5216,4841 +2015,BruCap,36,F,5169,4573 +2015,BruCap,37,M,5140,4741 +2015,BruCap,37,F,5059,4316 +2015,BruCap,38,M,5042,4719 +2015,BruCap,38,F,4906,4201 +2015,BruCap,39,M,5022,4443 +2015,BruCap,39,F,4652,3870 +2015,BruCap,40,M,5044,4445 +2015,BruCap,40,F,4709,3808 +2015,BruCap,41,M,5059,4182 +2015,BruCap,41,F,4833,3519 +2015,BruCap,42,M,5004,3996 +2015,BruCap,42,F,4835,3482 +2015,BruCap,43,M,5035,3764 +2015,BruCap,43,F,4736,3318 +2015,BruCap,44,M,5181,3813 +2015,BruCap,44,F,4913,3182 +2015,BruCap,45,M,4995,3699 +2015,BruCap,45,F,4769,3184 +2015,BruCap,46,M,4926,3614 +2015,BruCap,46,F,4695,2991 +2015,BruCap,47,M,4748,3349 +2015,BruCap,47,F,4546,2752 +2015,BruCap,48,M,4768,3187 +2015,BruCap,48,F,4724,2622 +2015,BruCap,49,M,4932,2894 +2015,BruCap,49,F,4819,2509 +2015,BruCap,50,M,4841,2891 +2015,BruCap,50,F,4813,2498 +2015,BruCap,51,M,4678,2673 +2015,BruCap,51,F,4767,2339 +2015,BruCap,52,M,4593,2517 +2015,BruCap,52,F,4676,2229 +2015,BruCap,53,M,4426,2409 +2015,BruCap,53,F,4683,2145 +2015,BruCap,54,M,4502,2226 +2015,BruCap,54,F,4967,2068 +2015,BruCap,55,M,4394,2046 +2015,BruCap,55,F,4752,2013 +2015,BruCap,56,M,4213,1951 +2015,BruCap,56,F,4670,1811 +2015,BruCap,57,M,4038,1704 +2015,BruCap,57,F,4563,1668 +2015,BruCap,58,M,3906,1789 +2015,BruCap,58,F,4594,1616 +2015,BruCap,59,M,3933,1610 +2015,BruCap,59,F,4460,1589 +2015,BruCap,60,M,3827,1419 +2015,BruCap,60,F,4397,1404 +2015,BruCap,61,M,3782,1280 +2015,BruCap,61,F,4366,1315 +2015,BruCap,62,M,3716,1275 +2015,BruCap,62,F,4263,1314 +2015,BruCap,63,M,3433,1095 +2015,BruCap,63,F,3974,1155 +2015,BruCap,64,M,3468,1161 +2015,BruCap,64,F,4082,1197 +2015,BruCap,65,M,3276,1008 +2015,BruCap,65,F,3894,1017 +2015,BruCap,66,M,3197,971 +2015,BruCap,66,F,3862,979 +2015,BruCap,67,M,3166,851 +2015,BruCap,67,F,3976,923 +2015,BruCap,68,M,3058,804 +2015,BruCap,68,F,3813,892 +2015,BruCap,69,M,2582,679 +2015,BruCap,69,F,3444,814 +2015,BruCap,70,M,2705,649 +2015,BruCap,70,F,3483,811 +2015,BruCap,71,M,2506,623 +2015,BruCap,71,F,3204,724 +2015,BruCap,72,M,2218,573 +2015,BruCap,72,F,2906,689 +2015,BruCap,73,M,1826,493 +2015,BruCap,73,F,2479,592 +2015,BruCap,74,M,2106,560 +2015,BruCap,74,F,2905,738 +2015,BruCap,75,M,2066,503 +2015,BruCap,75,F,2937,670 +2015,BruCap,76,M,2037,475 +2015,BruCap,76,F,2900,643 +2015,BruCap,77,M,1872,419 +2015,BruCap,77,F,2735,581 +2015,BruCap,78,M,1847,420 +2015,BruCap,78,F,2698,619 +2015,BruCap,79,M,1725,355 +2015,BruCap,79,F,2744,546 +2015,BruCap,80,M,1688,341 +2015,BruCap,80,F,2664,489 +2015,BruCap,81,M,1548,297 +2015,BruCap,81,F,2634,428 +2015,BruCap,82,M,1545,293 +2015,BruCap,82,F,2664,375 +2015,BruCap,83,M,1428,223 +2015,BruCap,83,F,2529,363 +2015,BruCap,84,M,1282,246 +2015,BruCap,84,F,2642,413 +2015,BruCap,85,M,1108,198 +2015,BruCap,85,F,2396,274 +2015,BruCap,86,M,1027,157 +2015,BruCap,86,F,2222,263 +2015,BruCap,87,M,882,111 +2015,BruCap,87,F,2013,238 +2015,BruCap,88,M,783,100 +2015,BruCap,88,F,1872,182 +2015,BruCap,89,M,639,94 +2015,BruCap,89,F,1710,154 +2015,BruCap,90,M,604,53 +2015,BruCap,90,F,1521,126 +2015,BruCap,91,M,413,41 +2015,BruCap,91,F,1364,103 +2015,BruCap,92,M,373,39 +2015,BruCap,92,F,1121,95 +2015,BruCap,93,M,331,37 +2015,BruCap,93,F,945,79 +2015,BruCap,94,M,201,27 +2015,BruCap,94,F,746,69 +2015,BruCap,95,M,111,14 +2015,BruCap,95,F,432,31 +2015,BruCap,96,M,59,13 +2015,BruCap,96,F,226,24 +2015,BruCap,97,M,36,5 +2015,BruCap,97,F,187,14 +2015,BruCap,98,M,30,3 +2015,BruCap,98,F,138,15 +2015,BruCap,99,M,17,1 +2015,BruCap,99,F,105,6 +2015,BruCap,100,M,17,2 +2015,BruCap,100,F,98,7 +2015,BruCap,101,M,13,0 +2015,BruCap,101,F,42,3 +2015,BruCap,102,M,4,1 +2015,BruCap,102,F,30,4 +2015,BruCap,103,M,4,1 +2015,BruCap,103,F,26,1 +2015,BruCap,104,M,0,0 +2015,BruCap,104,F,7,2 +2015,BruCap,105,M,0,0 +2015,BruCap,105,F,4,3 +2015,BruCap,106,M,0,0 +2015,BruCap,106,F,4,2 +2015,BruCap,107,M,0,0 +2015,BruCap,107,F,2,0 +2015,BruCap,108,M,0,0 +2015,BruCap,108,F,0,0 +2015,BruCap,109,M,0,0 +2015,BruCap,109,F,0,0 +2015,BruCap,110,M,0,0 +2015,BruCap,110,F,0,0 +2015,BruCap,111,M,0,0 +2015,BruCap,111,F,0,0 +2015,BruCap,112,M,0,0 +2015,BruCap,112,F,0,0 +2015,BruCap,113,M,0,0 +2015,BruCap,113,F,0,0 +2015,BruCap,114,M,0,1 +2015,BruCap,114,F,0,0 +2015,BruCap,115,M,0,0 +2015,BruCap,115,F,0,0 +2015,BruCap,116,M,0,0 +2015,BruCap,116,F,0,0 +2015,BruCap,117,M,0,0 +2015,BruCap,117,F,0,0 +2015,BruCap,118,M,0,0 +2015,BruCap,118,F,0,0 +2015,BruCap,119,M,0,0 +2015,BruCap,119,F,0,0 +2015,BruCap,120,M,0,0 +2015,BruCap,120,F,0,0 +2015,Fla,0,M,30889,3653 +2015,Fla,0,F,29359,3449 +2015,Fla,1,M,31344,3513 +2015,Fla,1,F,30052,3295 +2015,Fla,2,M,32275,3597 +2015,Fla,2,F,30891,3393 +2015,Fla,3,M,33276,3440 +2015,Fla,3,F,31589,3263 +2015,Fla,4,M,33964,3350 +2015,Fla,4,F,32462,3245 +2015,Fla,5,M,34037,3181 +2015,Fla,5,F,32239,3162 +2015,Fla,6,M,34597,3070 +2015,Fla,6,F,32952,2902 +2015,Fla,7,M,33525,2995 +2015,Fla,7,F,32291,2863 +2015,Fla,8,M,33423,2868 +2015,Fla,8,F,32089,2692 +2015,Fla,9,M,32983,2735 +2015,Fla,9,F,31134,2623 +2015,Fla,10,M,32441,2662 +2015,Fla,10,F,30750,2619 +2015,Fla,11,M,31230,2665 +2015,Fla,11,F,29858,2479 +2015,Fla,12,M,31275,2535 +2015,Fla,12,F,29738,2464 +2015,Fla,13,M,31495,2498 +2015,Fla,13,F,30282,2352 +2015,Fla,14,M,32268,2622 +2015,Fla,14,F,30959,2473 +2015,Fla,15,M,32121,2449 +2015,Fla,15,F,31147,2354 +2015,Fla,16,M,33043,2395 +2015,Fla,16,F,31455,2270 +2015,Fla,17,M,33660,2452 +2015,Fla,17,F,32419,2280 +2015,Fla,18,M,33654,2493 +2015,Fla,18,F,32513,2303 +2015,Fla,19,M,33734,2680 +2015,Fla,19,F,32522,2378 +2015,Fla,20,M,34131,2981 +2015,Fla,20,F,32533,2710 +2015,Fla,21,M,35430,2988 +2015,Fla,21,F,34404,3016 +2015,Fla,22,M,36517,3340 +2015,Fla,22,F,35177,3501 +2015,Fla,23,M,36984,3557 +2015,Fla,23,F,35147,4149 +2015,Fla,24,M,36257,3922 +2015,Fla,24,F,34836,4637 +2015,Fla,25,M,34898,4264 +2015,Fla,25,F,33547,5057 +2015,Fla,26,M,34149,4637 +2015,Fla,26,F,33235,5495 +2015,Fla,27,M,33846,4680 +2015,Fla,27,F,32553,5695 +2015,Fla,28,M,33769,5017 +2015,Fla,28,F,32709,5729 +2015,Fla,29,M,32610,5440 +2015,Fla,29,F,32208,5800 +2015,Fla,30,M,33483,5431 +2015,Fla,30,F,33063,5825 +2015,Fla,31,M,34456,5390 +2015,Fla,31,F,34301,5635 +2015,Fla,32,M,35481,5564 +2015,Fla,32,F,34865,5552 +2015,Fla,33,M,36669,5393 +2015,Fla,33,F,35758,5400 +2015,Fla,34,M,36344,5541 +2015,Fla,34,F,36436,5537 +2015,Fla,35,M,36934,5369 +2015,Fla,35,F,36160,5277 +2015,Fla,36,M,36153,5109 +2015,Fla,36,F,36198,5110 +2015,Fla,37,M,35562,5215 +2015,Fla,37,F,35600,4895 +2015,Fla,38,M,35124,5040 +2015,Fla,38,F,34664,4749 +2015,Fla,39,M,34321,4922 +2015,Fla,39,F,33877,4689 +2015,Fla,40,M,35571,4863 +2015,Fla,40,F,35333,4497 +2015,Fla,41,M,36928,4687 +2015,Fla,41,F,36324,4293 +2015,Fla,42,M,38546,4825 +2015,Fla,42,F,38373,4262 +2015,Fla,43,M,40044,4677 +2015,Fla,43,F,40121,4125 +2015,Fla,44,M,41280,4770 +2015,Fla,44,F,40884,4179 +2015,Fla,45,M,41252,4614 +2015,Fla,45,F,40759,3878 +2015,Fla,46,M,41502,4587 +2015,Fla,46,F,41152,3851 +2015,Fla,47,M,42876,4165 +2015,Fla,47,F,41592,3474 +2015,Fla,48,M,44104,4207 +2015,Fla,48,F,43368,3412 +2015,Fla,49,M,45491,4027 +2015,Fla,49,F,44560,3295 +2015,Fla,50,M,47101,3921 +2015,Fla,50,F,46577,3138 +2015,Fla,51,M,46602,3651 +2015,Fla,51,F,45815,2904 +2015,Fla,52,M,46003,3408 +2015,Fla,52,F,45109,2708 +2015,Fla,53,M,45198,3211 +2015,Fla,53,F,45262,2490 +2015,Fla,54,M,44300,3115 +2015,Fla,54,F,44113,2494 +2015,Fla,55,M,44645,2875 +2015,Fla,55,F,44489,2286 +2015,Fla,56,M,43529,2857 +2015,Fla,56,F,43117,2087 +2015,Fla,57,M,42663,2568 +2015,Fla,57,F,42297,1980 +2015,Fla,58,M,41292,2477 +2015,Fla,58,F,41618,1905 +2015,Fla,59,M,40387,2350 +2015,Fla,59,F,40999,1822 +2015,Fla,60,M,39214,2239 +2015,Fla,60,F,39769,1754 +2015,Fla,61,M,38076,2035 +2015,Fla,61,F,38194,1619 +2015,Fla,62,M,37746,1973 +2015,Fla,62,F,37811,1546 +2015,Fla,63,M,35582,1890 +2015,Fla,63,F,36157,1421 +2015,Fla,64,M,34902,1842 +2015,Fla,64,F,35940,1546 +2015,Fla,65,M,34673,1870 +2015,Fla,65,F,35443,1477 +2015,Fla,66,M,34216,1796 +2015,Fla,66,F,35740,1403 +2015,Fla,67,M,33369,1693 +2015,Fla,67,F,35072,1361 +2015,Fla,68,M,33775,1652 +2015,Fla,68,F,35398,1279 +2015,Fla,69,M,29382,1376 +2015,Fla,69,F,31669,1095 +2015,Fla,70,M,28794,1345 +2015,Fla,70,F,31189,1172 +2015,Fla,71,M,27040,1289 +2015,Fla,71,F,29750,1017 +2015,Fla,72,M,23246,1143 +2015,Fla,72,F,25768,1011 +2015,Fla,73,M,20383,1060 +2015,Fla,73,F,23388,879 +2015,Fla,74,M,21941,1055 +2015,Fla,74,F,25667,1016 +2015,Fla,75,M,23265,963 +2015,Fla,75,F,28241,865 +2015,Fla,76,M,23608,907 +2015,Fla,76,F,28361,823 +2015,Fla,77,M,22120,798 +2015,Fla,77,F,26997,772 +2015,Fla,78,M,20346,754 +2015,Fla,78,F,25843,705 +2015,Fla,79,M,19212,695 +2015,Fla,79,F,25200,657 +2015,Fla,80,M,18423,609 +2015,Fla,80,F,24914,661 +2015,Fla,81,M,17151,573 +2015,Fla,81,F,23958,550 +2015,Fla,82,M,16046,497 +2015,Fla,82,F,23881,485 +2015,Fla,83,M,14796,429 +2015,Fla,83,F,22603,393 +2015,Fla,84,M,13271,400 +2015,Fla,84,F,21124,431 +2015,Fla,85,M,10765,315 +2015,Fla,85,F,18506,339 +2015,Fla,86,M,9279,253 +2015,Fla,86,F,16545,322 +2015,Fla,87,M,7843,191 +2015,Fla,87,F,14511,252 +2015,Fla,88,M,6442,153 +2015,Fla,88,F,13091,215 +2015,Fla,89,M,5438,151 +2015,Fla,89,F,11290,193 +2015,Fla,90,M,4279,104 +2015,Fla,90,F,9625,171 +2015,Fla,91,M,3417,72 +2015,Fla,91,F,8043,151 +2015,Fla,92,M,2522,57 +2015,Fla,92,F,6322,108 +2015,Fla,93,M,1857,38 +2015,Fla,93,F,5055,67 +2015,Fla,94,M,1238,34 +2015,Fla,94,F,3939,63 +2015,Fla,95,M,650,14 +2015,Fla,95,F,2235,26 +2015,Fla,96,M,314,13 +2015,Fla,96,F,1116,22 +2015,Fla,97,M,184,6 +2015,Fla,97,F,792,18 +2015,Fla,98,M,140,5 +2015,Fla,98,F,652,9 +2015,Fla,99,M,132,2 +2015,Fla,99,F,516,16 +2015,Fla,100,M,62,1 +2015,Fla,100,F,381,8 +2015,Fla,101,M,41,2 +2015,Fla,101,F,240,4 +2015,Fla,102,M,22,0 +2015,Fla,102,F,155,4 +2015,Fla,103,M,13,0 +2015,Fla,103,F,91,2 +2015,Fla,104,M,6,0 +2015,Fla,104,F,38,1 +2015,Fla,105,M,3,0 +2015,Fla,105,F,33,0 +2015,Fla,106,M,0,0 +2015,Fla,106,F,13,0 +2015,Fla,107,M,0,0 +2015,Fla,107,F,2,2 +2015,Fla,108,M,0,0 +2015,Fla,108,F,1,0 +2015,Fla,109,M,0,0 +2015,Fla,109,F,2,0 +2015,Fla,110,M,0,0 +2015,Fla,110,F,1,0 +2015,Fla,111,M,0,0 +2015,Fla,111,F,0,0 +2015,Fla,112,M,0,0 +2015,Fla,112,F,0,0 +2015,Fla,113,M,0,0 +2015,Fla,113,F,0,0 +2015,Fla,114,M,0,0 +2015,Fla,114,F,0,0 +2015,Fla,115,M,0,0 +2015,Fla,115,F,0,0 +2015,Fla,116,M,0,0 +2015,Fla,116,F,1,0 +2015,Fla,117,M,0,0 +2015,Fla,117,F,0,0 +2015,Fla,118,M,0,0 +2015,Fla,118,F,0,0 +2015,Fla,119,M,0,0 +2015,Fla,119,F,0,0 +2015,Fla,120,M,0,0 +2015,Fla,120,F,0,0 +2015,Wal,0,M,18582,1387 +2015,Wal,0,F,17408,1389 +2015,Wal,1,M,18880,1400 +2015,Wal,1,F,18018,1338 +2015,Wal,2,M,19377,1407 +2015,Wal,2,F,18737,1329 +2015,Wal,3,M,19715,1507 +2015,Wal,3,F,18980,1378 +2015,Wal,4,M,20265,1379 +2015,Wal,4,F,19414,1344 +2015,Wal,5,M,20277,1415 +2015,Wal,5,F,19596,1282 +2015,Wal,6,M,20702,1343 +2015,Wal,6,F,19480,1301 +2015,Wal,7,M,20518,1341 +2015,Wal,7,F,19435,1283 +2015,Wal,8,M,20524,1340 +2015,Wal,8,F,19812,1299 +2015,Wal,9,M,20258,1304 +2015,Wal,9,F,19510,1161 +2015,Wal,10,M,20231,1278 +2015,Wal,10,F,19259,1281 +2015,Wal,11,M,19991,1293 +2015,Wal,11,F,19336,1184 +2015,Wal,12,M,20115,1294 +2015,Wal,12,F,19082,1266 +2015,Wal,13,M,20688,1274 +2015,Wal,13,F,19951,1200 +2015,Wal,14,M,21068,1254 +2015,Wal,14,F,20032,1266 +2015,Wal,15,M,20500,1239 +2015,Wal,15,F,19478,1250 +2015,Wal,16,M,20549,1241 +2015,Wal,16,F,19640,1265 +2015,Wal,17,M,20584,1303 +2015,Wal,17,F,19731,1328 +2015,Wal,18,M,20722,1463 +2015,Wal,18,F,19910,1407 +2015,Wal,19,M,20258,1485 +2015,Wal,19,F,19369,1497 +2015,Wal,20,M,20338,1589 +2015,Wal,20,F,19440,1655 +2015,Wal,21,M,21090,1578 +2015,Wal,21,F,20003,1856 +2015,Wal,22,M,21988,1692 +2015,Wal,22,F,21056,2045 +2015,Wal,23,M,22349,1706 +2015,Wal,23,F,21541,2198 +2015,Wal,24,M,21786,2071 +2015,Wal,24,F,20953,2443 +2015,Wal,25,M,21554,2109 +2015,Wal,25,F,20533,2627 +2015,Wal,26,M,21043,2303 +2015,Wal,26,F,20039,2761 +2015,Wal,27,M,20190,2470 +2015,Wal,27,F,19381,2866 +2015,Wal,28,M,20088,2585 +2015,Wal,28,F,19291,2911 +2015,Wal,29,M,19148,2670 +2015,Wal,29,F,18792,2970 +2015,Wal,30,M,19015,2777 +2015,Wal,30,F,18715,3057 +2015,Wal,31,M,18880,2824 +2015,Wal,31,F,18239,2840 +2015,Wal,32,M,19097,2849 +2015,Wal,32,F,18937,3120 +2015,Wal,33,M,19364,2879 +2015,Wal,33,F,19532,3032 +2015,Wal,34,M,19531,3023 +2015,Wal,34,F,19616,3161 +2015,Wal,35,M,19382,2974 +2015,Wal,35,F,18965,3054 +2015,Wal,36,M,19061,3073 +2015,Wal,36,F,18980,2997 +2015,Wal,37,M,19208,2937 +2015,Wal,37,F,19230,2960 +2015,Wal,38,M,19547,2800 +2015,Wal,38,F,19713,2851 +2015,Wal,39,M,19655,2944 +2015,Wal,39,F,19930,2858 +2015,Wal,40,M,20436,3119 +2015,Wal,40,F,20452,2943 +2015,Wal,41,M,21310,3283 +2015,Wal,41,F,21368,2997 +2015,Wal,42,M,21997,3252 +2015,Wal,42,F,22119,3007 +2015,Wal,43,M,22310,3301 +2015,Wal,43,F,22548,2878 +2015,Wal,44,M,21970,3275 +2015,Wal,44,F,21936,2974 +2015,Wal,45,M,21683,3179 +2015,Wal,45,F,21944,2833 +2015,Wal,46,M,21238,3160 +2015,Wal,46,F,21751,2871 +2015,Wal,47,M,21566,3177 +2015,Wal,47,F,21886,2832 +2015,Wal,48,M,21922,3483 +2015,Wal,48,F,22278,2942 +2015,Wal,49,M,22639,3345 +2015,Wal,49,F,22990,2785 +2015,Wal,50,M,23267,3164 +2015,Wal,50,F,23825,2801 +2015,Wal,51,M,22653,3166 +2015,Wal,51,F,23492,2664 +2015,Wal,52,M,21922,3092 +2015,Wal,52,F,22889,2437 +2015,Wal,53,M,22308,3011 +2015,Wal,53,F,23345,2437 +2015,Wal,54,M,22209,3161 +2015,Wal,54,F,22896,2435 +2015,Wal,55,M,21954,2936 +2015,Wal,55,F,23504,2301 +2015,Wal,56,M,21413,2920 +2015,Wal,56,F,23023,2226 +2015,Wal,57,M,21000,2840 +2015,Wal,57,F,22434,2166 +2015,Wal,58,M,20347,2872 +2015,Wal,58,F,22027,2114 +2015,Wal,59,M,19942,2755 +2015,Wal,59,F,21934,2058 +2015,Wal,60,M,19745,2609 +2015,Wal,60,F,21505,2049 +2015,Wal,61,M,19347,2493 +2015,Wal,61,F,21120,1932 +2015,Wal,62,M,18744,2471 +2015,Wal,62,F,20685,1892 +2015,Wal,63,M,18098,2303 +2015,Wal,63,F,20152,1872 +2015,Wal,64,M,18401,2272 +2015,Wal,64,F,20155,1902 +2015,Wal,65,M,18129,2217 +2015,Wal,65,F,20092,1705 +2015,Wal,66,M,18229,2119 +2015,Wal,66,F,20448,1834 +2015,Wal,67,M,17877,2084 +2015,Wal,67,F,20069,1681 +2015,Wal,68,M,17215,1937 +2015,Wal,68,F,19828,1547 +2015,Wal,69,M,12470,1490 +2015,Wal,69,F,15025,1305 +2015,Wal,70,M,12227,1501 +2015,Wal,70,F,14563,1376 +2015,Wal,71,M,11102,1358 +2015,Wal,71,F,13517,1224 +2015,Wal,72,M,9577,1206 +2015,Wal,72,F,11847,1171 +2015,Wal,73,M,8692,1151 +2015,Wal,73,F,10932,1128 +2015,Wal,74,M,9488,1262 +2015,Wal,74,F,12167,1334 +2015,Wal,75,M,9972,1185 +2015,Wal,75,F,13173,1340 +2015,Wal,76,M,9585,1011 +2015,Wal,76,F,13068,1287 +2015,Wal,77,M,8918,1011 +2015,Wal,77,F,12161,1200 +2015,Wal,78,M,8253,913 +2015,Wal,78,F,11915,1172 +2015,Wal,79,M,7644,901 +2015,Wal,79,F,11379,1206 +2015,Wal,80,M,7476,808 +2015,Wal,80,F,11414,1182 +2015,Wal,81,M,7078,732 +2015,Wal,81,F,10973,1129 +2015,Wal,82,M,6798,704 +2015,Wal,82,F,11545,1043 +2015,Wal,83,M,6332,602 +2015,Wal,83,F,11065,1060 +2015,Wal,84,M,5650,593 +2015,Wal,84,F,10479,993 +2015,Wal,85,M,4776,496 +2015,Wal,85,F,9246,881 +2015,Wal,86,M,3984,405 +2015,Wal,86,F,8369,712 +2015,Wal,87,M,3368,349 +2015,Wal,87,F,7599,724 +2015,Wal,88,M,2812,291 +2015,Wal,88,F,6762,636 +2015,Wal,89,M,2450,232 +2015,Wal,89,F,6088,580 +2015,Wal,90,M,1828,180 +2015,Wal,90,F,5189,455 +2015,Wal,91,M,1418,129 +2015,Wal,91,F,4207,383 +2015,Wal,92,M,1118,90 +2015,Wal,92,F,3503,298 +2015,Wal,93,M,837,80 +2015,Wal,93,F,2811,204 +2015,Wal,94,M,556,46 +2015,Wal,94,F,2163,157 +2015,Wal,95,M,316,27 +2015,Wal,95,F,1189,107 +2015,Wal,96,M,145,9 +2015,Wal,96,F,576,48 +2015,Wal,97,M,92,3 +2015,Wal,97,F,453,25 +2015,Wal,98,M,65,4 +2015,Wal,98,F,317,20 +2015,Wal,99,M,49,1 +2015,Wal,99,F,239,21 +2015,Wal,100,M,28,4 +2015,Wal,100,F,204,18 +2015,Wal,101,M,24,1 +2015,Wal,101,F,125,4 +2015,Wal,102,M,7,1 +2015,Wal,102,F,80,2 +2015,Wal,103,M,1,1 +2015,Wal,103,F,50,3 +2015,Wal,104,M,1,0 +2015,Wal,104,F,15,0 +2015,Wal,105,M,1,1 +2015,Wal,105,F,10,1 +2015,Wal,106,M,0,0 +2015,Wal,106,F,4,1 +2015,Wal,107,M,0,0 +2015,Wal,107,F,5,0 +2015,Wal,108,M,0,0 +2015,Wal,108,F,0,0 +2015,Wal,109,M,0,0 +2015,Wal,109,F,1,1 +2015,Wal,110,M,0,0 +2015,Wal,110,F,0,0 +2015,Wal,111,M,0,0 +2015,Wal,111,F,0,0 +2015,Wal,112,M,0,0 +2015,Wal,112,F,0,0 +2015,Wal,113,M,0,0 +2015,Wal,113,F,0,0 +2015,Wal,114,M,0,0 +2015,Wal,114,F,0,0 +2015,Wal,115,M,0,0 +2015,Wal,115,F,0,0 +2015,Wal,116,M,0,0 +2015,Wal,116,F,0,0 +2015,Wal,117,M,0,0 +2015,Wal,117,F,0,0 +2015,Wal,118,M,0,0 +2015,Wal,118,F,0,0 +2015,Wal,119,M,0,0 +2015,Wal,119,F,0,0 +2015,Wal,120,M,0,0 +2015,Wal,120,F,0,0 +2016,BruCap,0,M,6155,3104 +2016,BruCap,0,F,5900,2817 +2016,BruCap,1,M,6165,3068 +2016,BruCap,1,F,5916,2946 +2016,BruCap,2,M,6053,2918 +2016,BruCap,2,F,5736,2776 +2016,BruCap,3,M,6131,2749 +2016,BruCap,3,F,5883,2734 +2016,BruCap,4,M,5989,2653 +2016,BruCap,4,F,5784,2523 +2016,BruCap,5,M,6237,2590 +2016,BruCap,5,F,5780,2521 +2016,BruCap,6,M,6012,2423 +2016,BruCap,6,F,5759,2290 +2016,BruCap,7,M,5862,2212 +2016,BruCap,7,F,5518,2234 +2016,BruCap,8,M,5783,2101 +2016,BruCap,8,F,5474,2066 +2016,BruCap,9,M,5651,1983 +2016,BruCap,9,F,5354,1896 +2016,BruCap,10,M,5416,1874 +2016,BruCap,10,F,5200,1785 +2016,BruCap,11,M,5326,1790 +2016,BruCap,11,F,5066,1698 +2016,BruCap,12,M,5014,1742 +2016,BruCap,12,F,4806,1660 +2016,BruCap,13,M,4741,1634 +2016,BruCap,13,F,4735,1578 +2016,BruCap,14,M,4866,1624 +2016,BruCap,14,F,4755,1501 +2016,BruCap,15,M,4808,1685 +2016,BruCap,15,F,4571,1550 +2016,BruCap,16,M,4824,1603 +2016,BruCap,16,F,4595,1522 +2016,BruCap,17,M,4622,1481 +2016,BruCap,17,F,4431,1534 +2016,BruCap,18,M,4825,1751 +2016,BruCap,18,F,4523,1691 +2016,BruCap,19,M,4701,1916 +2016,BruCap,19,F,4544,2004 +2016,BruCap,20,M,4691,2045 +2016,BruCap,20,F,4514,2348 +2016,BruCap,21,M,4857,2276 +2016,BruCap,21,F,4465,2695 +2016,BruCap,22,M,4820,2462 +2016,BruCap,22,F,4718,3156 +2016,BruCap,23,M,5039,2718 +2016,BruCap,23,F,4974,3547 +2016,BruCap,24,M,5181,3127 +2016,BruCap,24,F,5252,4173 +2016,BruCap,25,M,5477,3590 +2016,BruCap,25,F,5539,4635 +2016,BruCap,26,M,5566,3826 +2016,BruCap,26,F,5721,4904 +2016,BruCap,27,M,5774,4241 +2016,BruCap,27,F,5748,5299 +2016,BruCap,28,M,5468,4391 +2016,BruCap,28,F,5735,5480 +2016,BruCap,29,M,5401,4571 +2016,BruCap,29,F,5549,5336 +2016,BruCap,30,M,5278,4725 +2016,BruCap,30,F,5253,5419 +2016,BruCap,31,M,5186,5016 +2016,BruCap,31,F,5412,5318 +2016,BruCap,32,M,5065,4857 +2016,BruCap,32,F,5157,5138 +2016,BruCap,33,M,5118,5011 +2016,BruCap,33,F,5237,5181 +2016,BruCap,34,M,5121,4871 +2016,BruCap,34,F,5227,4750 +2016,BruCap,35,M,5192,5218 +2016,BruCap,35,F,5387,5043 +2016,BruCap,36,M,5146,4918 +2016,BruCap,36,F,5072,4721 +2016,BruCap,37,M,5192,4814 +2016,BruCap,37,F,5062,4523 +2016,BruCap,38,M,5064,4804 +2016,BruCap,38,F,4999,4260 +2016,BruCap,39,M,4964,4689 +2016,BruCap,39,F,4850,4143 +2016,BruCap,40,M,4970,4432 +2016,BruCap,40,F,4588,3829 +2016,BruCap,41,M,5027,4400 +2016,BruCap,41,F,4678,3768 +2016,BruCap,42,M,5027,4144 +2016,BruCap,42,F,4768,3515 +2016,BruCap,43,M,4940,3966 +2016,BruCap,43,F,4817,3460 +2016,BruCap,44,M,5030,3754 +2016,BruCap,44,F,4741,3319 +2016,BruCap,45,M,5147,3813 +2016,BruCap,45,F,4878,3185 +2016,BruCap,46,M,4958,3690 +2016,BruCap,46,F,4756,3126 +2016,BruCap,47,M,4883,3569 +2016,BruCap,47,F,4695,2995 +2016,BruCap,48,M,4719,3351 +2016,BruCap,48,F,4522,2709 +2016,BruCap,49,M,4716,3179 +2016,BruCap,49,F,4695,2629 +2016,BruCap,50,M,4925,2841 +2016,BruCap,50,F,4814,2505 +2016,BruCap,51,M,4829,2838 +2016,BruCap,51,F,4792,2491 +2016,BruCap,52,M,4635,2640 +2016,BruCap,52,F,4740,2333 +2016,BruCap,53,M,4541,2511 +2016,BruCap,53,F,4641,2225 +2016,BruCap,54,M,4387,2381 +2016,BruCap,54,F,4662,2126 +2016,BruCap,55,M,4457,2196 +2016,BruCap,55,F,4953,2059 +2016,BruCap,56,M,4338,2011 +2016,BruCap,56,F,4700,1969 +2016,BruCap,57,M,4133,1929 +2016,BruCap,57,F,4643,1771 +2016,BruCap,58,M,3988,1674 +2016,BruCap,58,F,4500,1652 +2016,BruCap,59,M,3864,1757 +2016,BruCap,59,F,4541,1577 +2016,BruCap,60,M,3861,1565 +2016,BruCap,60,F,4410,1552 +2016,BruCap,61,M,3741,1375 +2016,BruCap,61,F,4310,1371 +2016,BruCap,62,M,3690,1222 +2016,BruCap,62,F,4284,1276 +2016,BruCap,63,M,3651,1224 +2016,BruCap,63,F,4192,1252 +2016,BruCap,64,M,3339,1066 +2016,BruCap,64,F,3889,1109 +2016,BruCap,65,M,3380,1073 +2016,BruCap,65,F,4008,1137 +2016,BruCap,66,M,3166,923 +2016,BruCap,66,F,3822,965 +2016,BruCap,67,M,3112,918 +2016,BruCap,67,F,3814,927 +2016,BruCap,68,M,3076,797 +2016,BruCap,68,F,3922,888 +2016,BruCap,69,M,2969,752 +2016,BruCap,69,F,3757,860 +2016,BruCap,70,M,2517,653 +2016,BruCap,70,F,3374,779 +2016,BruCap,71,M,2623,610 +2016,BruCap,71,F,3418,786 +2016,BruCap,72,M,2429,590 +2016,BruCap,72,F,3138,700 +2016,BruCap,73,M,2151,546 +2016,BruCap,73,F,2849,674 +2016,BruCap,74,M,1746,481 +2016,BruCap,74,F,2431,583 +2016,BruCap,75,M,2018,524 +2016,BruCap,75,F,2838,714 +2016,BruCap,76,M,1969,482 +2016,BruCap,76,F,2864,636 +2016,BruCap,77,M,1939,452 +2016,BruCap,77,F,2811,622 +2016,BruCap,78,M,1771,394 +2016,BruCap,78,F,2632,565 +2016,BruCap,79,M,1741,395 +2016,BruCap,79,F,2616,594 +2016,BruCap,80,M,1604,332 +2016,BruCap,80,F,2639,520 +2016,BruCap,81,M,1587,310 +2016,BruCap,81,F,2561,468 +2016,BruCap,82,M,1432,271 +2016,BruCap,82,F,2522,399 +2016,BruCap,83,M,1423,264 +2016,BruCap,83,F,2525,347 +2016,BruCap,84,M,1296,198 +2016,BruCap,84,F,2395,344 +2016,BruCap,85,M,1159,219 +2016,BruCap,85,F,2457,378 +2016,BruCap,86,M,991,175 +2016,BruCap,86,F,2223,257 +2016,BruCap,87,M,902,134 +2016,BruCap,87,F,2032,243 +2016,BruCap,88,M,757,100 +2016,BruCap,88,F,1805,212 +2016,BruCap,89,M,676,86 +2016,BruCap,89,F,1649,153 +2016,BruCap,90,M,539,74 +2016,BruCap,90,F,1477,136 +2016,BruCap,91,M,499,49 +2016,BruCap,91,F,1298,105 +2016,BruCap,92,M,332,35 +2016,BruCap,92,F,1141,78 +2016,BruCap,93,M,287,27 +2016,BruCap,93,F,906,74 +2016,BruCap,94,M,237,23 +2016,BruCap,94,F,739,65 +2016,BruCap,95,M,154,19 +2016,BruCap,95,F,566,53 +2016,BruCap,96,M,80,9 +2016,BruCap,96,F,327,25 +2016,BruCap,97,M,43,9 +2016,BruCap,97,F,171,21 +2016,BruCap,98,M,23,4 +2016,BruCap,98,F,135,9 +2016,BruCap,99,M,20,2 +2016,BruCap,99,F,92,8 +2016,BruCap,100,M,12,0 +2016,BruCap,100,F,60,3 +2016,BruCap,101,M,12,2 +2016,BruCap,101,F,66,5 +2016,BruCap,102,M,8,0 +2016,BruCap,102,F,26,1 +2016,BruCap,103,M,2,1 +2016,BruCap,103,F,17,2 +2016,BruCap,104,M,2,1 +2016,BruCap,104,F,14,0 +2016,BruCap,105,M,0,0 +2016,BruCap,105,F,2,2 +2016,BruCap,106,M,0,0 +2016,BruCap,106,F,3,3 +2016,BruCap,107,M,0,0 +2016,BruCap,107,F,1,2 +2016,BruCap,108,M,0,0 +2016,BruCap,108,F,1,0 +2016,BruCap,109,M,0,0 +2016,BruCap,109,F,0,0 +2016,BruCap,110,M,0,0 +2016,BruCap,110,F,0,0 +2016,BruCap,111,M,0,0 +2016,BruCap,111,F,0,0 +2016,BruCap,112,M,0,0 +2016,BruCap,112,F,0,0 +2016,BruCap,113,M,0,0 +2016,BruCap,113,F,0,0 +2016,BruCap,114,M,0,0 +2016,BruCap,114,F,0,0 +2016,BruCap,115,M,0,1 +2016,BruCap,115,F,0,0 +2016,BruCap,116,M,0,0 +2016,BruCap,116,F,0,0 +2016,BruCap,117,M,0,0 +2016,BruCap,117,F,0,0 +2016,BruCap,118,M,0,0 +2016,BruCap,118,F,0,0 +2016,BruCap,119,M,0,0 +2016,BruCap,119,F,0,0 +2016,BruCap,120,M,0,0 +2016,BruCap,120,F,0,0 +2016,Fla,0,M,29993,3717 +2016,Fla,0,F,28483,3587 +2016,Fla,1,M,31292,3716 +2016,Fla,1,F,29721,3575 +2016,Fla,2,M,31718,3597 +2016,Fla,2,F,30353,3387 +2016,Fla,3,M,32555,3678 +2016,Fla,3,F,31191,3472 +2016,Fla,4,M,33558,3529 +2016,Fla,4,F,31857,3317 +2016,Fla,5,M,34183,3436 +2016,Fla,5,F,32741,3300 +2016,Fla,6,M,34234,3333 +2016,Fla,6,F,32440,3254 +2016,Fla,7,M,34775,3227 +2016,Fla,7,F,33092,3040 +2016,Fla,8,M,33668,3108 +2016,Fla,8,F,32497,2923 +2016,Fla,9,M,33581,2989 +2016,Fla,9,F,32244,2806 +2016,Fla,10,M,33119,2856 +2016,Fla,10,F,31283,2738 +2016,Fla,11,M,32534,2766 +2016,Fla,11,F,30911,2662 +2016,Fla,12,M,31389,2711 +2016,Fla,12,F,29995,2547 +2016,Fla,13,M,31420,2604 +2016,Fla,13,F,29836,2505 +2016,Fla,14,M,31621,2581 +2016,Fla,14,F,30393,2459 +2016,Fla,15,M,32396,2729 +2016,Fla,15,F,31067,2561 +2016,Fla,16,M,32213,2571 +2016,Fla,16,F,31218,2438 +2016,Fla,17,M,33164,2526 +2016,Fla,17,F,31579,2372 +2016,Fla,18,M,33759,2640 +2016,Fla,18,F,32552,2486 +2016,Fla,19,M,33667,2726 +2016,Fla,19,F,32534,2539 +2016,Fla,20,M,33763,3045 +2016,Fla,20,F,32595,2691 +2016,Fla,21,M,34133,3461 +2016,Fla,21,F,32591,3173 +2016,Fla,22,M,35441,3350 +2016,Fla,22,F,34413,3602 +2016,Fla,23,M,36475,3809 +2016,Fla,23,F,35166,4161 +2016,Fla,24,M,36826,4054 +2016,Fla,24,F,35041,4677 +2016,Fla,25,M,36071,4434 +2016,Fla,25,F,34712,5240 +2016,Fla,26,M,34727,4831 +2016,Fla,26,F,33424,5536 +2016,Fla,27,M,34060,5125 +2016,Fla,27,F,33209,5899 +2016,Fla,28,M,33795,5179 +2016,Fla,28,F,32588,6061 +2016,Fla,29,M,33728,5427 +2016,Fla,29,F,32775,6040 +2016,Fla,30,M,32645,5745 +2016,Fla,30,F,32361,6043 +2016,Fla,31,M,33537,5740 +2016,Fla,31,F,33229,5995 +2016,Fla,32,M,34597,5665 +2016,Fla,32,F,34467,5844 +2016,Fla,33,M,35605,5779 +2016,Fla,33,F,35065,5715 +2016,Fla,34,M,36822,5597 +2016,Fla,34,F,35934,5589 +2016,Fla,35,M,36553,5742 +2016,Fla,35,F,36654,5639 +2016,Fla,36,M,37061,5521 +2016,Fla,36,F,36386,5425 +2016,Fla,37,M,36269,5282 +2016,Fla,37,F,36400,5284 +2016,Fla,38,M,35754,5231 +2016,Fla,38,F,35809,5000 +2016,Fla,39,M,35277,5123 +2016,Fla,39,F,34808,4837 +2016,Fla,40,M,34429,5066 +2016,Fla,40,F,34016,4837 +2016,Fla,41,M,35611,5034 +2016,Fla,41,F,35453,4551 +2016,Fla,42,M,37075,4766 +2016,Fla,42,F,36435,4321 +2016,Fla,43,M,38652,4855 +2016,Fla,43,F,38478,4319 +2016,Fla,44,M,40122,4760 +2016,Fla,44,F,40172,4147 +2016,Fla,45,M,41313,4819 +2016,Fla,45,F,40953,4206 +2016,Fla,46,M,41285,4614 +2016,Fla,46,F,40818,3911 +2016,Fla,47,M,41550,4593 +2016,Fla,47,F,41200,3868 +2016,Fla,48,M,42838,4205 +2016,Fla,48,F,41596,3488 +2016,Fla,49,M,44081,4255 +2016,Fla,49,F,43344,3409 +2016,Fla,50,M,45466,4008 +2016,Fla,50,F,44534,3272 +2016,Fla,51,M,47043,3929 +2016,Fla,51,F,46547,3079 +2016,Fla,52,M,46506,3596 +2016,Fla,52,F,45747,2886 +2016,Fla,53,M,45872,3364 +2016,Fla,53,F,45049,2659 +2016,Fla,54,M,45033,3162 +2016,Fla,54,F,45200,2474 +2016,Fla,55,M,44109,3068 +2016,Fla,55,F,44000,2448 +2016,Fla,56,M,44452,2811 +2016,Fla,56,F,44382,2280 +2016,Fla,57,M,43288,2807 +2016,Fla,57,F,42969,2078 +2016,Fla,58,M,42439,2525 +2016,Fla,58,F,42135,1957 +2016,Fla,59,M,40984,2458 +2016,Fla,59,F,41456,1875 +2016,Fla,60,M,40058,2336 +2016,Fla,60,F,40789,1784 +2016,Fla,61,M,38895,2211 +2016,Fla,61,F,39614,1716 +2016,Fla,62,M,37688,1996 +2016,Fla,62,F,38026,1590 +2016,Fla,63,M,37384,1950 +2016,Fla,63,F,37573,1528 +2016,Fla,64,M,35241,1858 +2016,Fla,64,F,35924,1394 +2016,Fla,65,M,34453,1785 +2016,Fla,65,F,35709,1522 +2016,Fla,66,M,34279,1816 +2016,Fla,66,F,35239,1427 +2016,Fla,67,M,33776,1748 +2016,Fla,67,F,35489,1376 +2016,Fla,68,M,32876,1652 +2016,Fla,68,F,34813,1315 +2016,Fla,69,M,33223,1612 +2016,Fla,69,F,35088,1252 +2016,Fla,70,M,28844,1337 +2016,Fla,70,F,31394,1076 +2016,Fla,71,M,28235,1317 +2016,Fla,71,F,30885,1146 +2016,Fla,72,M,26473,1240 +2016,Fla,72,F,29399,987 +2016,Fla,73,M,22643,1095 +2016,Fla,73,F,25421,980 +2016,Fla,74,M,19855,1035 +2016,Fla,74,F,23018,849 +2016,Fla,75,M,21317,1009 +2016,Fla,75,F,25273,970 +2016,Fla,76,M,22510,924 +2016,Fla,76,F,27735,831 +2016,Fla,77,M,22679,867 +2016,Fla,77,F,27797,801 +2016,Fla,78,M,21255,759 +2016,Fla,78,F,26363,735 +2016,Fla,79,M,19446,696 +2016,Fla,79,F,25148,668 +2016,Fla,80,M,18227,643 +2016,Fla,80,F,24415,635 +2016,Fla,81,M,17374,557 +2016,Fla,81,F,24031,635 +2016,Fla,82,M,16092,526 +2016,Fla,82,F,22908,509 +2016,Fla,83,M,14869,448 +2016,Fla,83,F,22697,454 +2016,Fla,84,M,13575,388 +2016,Fla,84,F,21365,365 +2016,Fla,85,M,12077,365 +2016,Fla,85,F,19745,401 +2016,Fla,86,M,9665,278 +2016,Fla,86,F,17169,312 +2016,Fla,87,M,8175,215 +2016,Fla,87,F,15094,302 +2016,Fla,88,M,6795,159 +2016,Fla,88,F,12998,238 +2016,Fla,89,M,5474,132 +2016,Fla,89,F,11553,189 +2016,Fla,90,M,4535,124 +2016,Fla,90,F,9754,163 +2016,Fla,91,M,3490,78 +2016,Fla,91,F,8213,151 +2016,Fla,92,M,2717,61 +2016,Fla,92,F,6650,122 +2016,Fla,93,M,1962,44 +2016,Fla,93,F,5106,91 +2016,Fla,94,M,1370,30 +2016,Fla,94,F,3987,56 +2016,Fla,95,M,899,23 +2016,Fla,95,F,3008,49 +2016,Fla,96,M,481,10 +2016,Fla,96,F,1684,23 +2016,Fla,97,M,218,10 +2016,Fla,97,F,768,14 +2016,Fla,98,M,123,3 +2016,Fla,98,F,559,14 +2016,Fla,99,M,84,3 +2016,Fla,99,F,421,5 +2016,Fla,100,M,79,1 +2016,Fla,100,F,332,9 +2016,Fla,101,M,36,0 +2016,Fla,101,F,216,2 +2016,Fla,102,M,25,0 +2016,Fla,102,F,141,2 +2016,Fla,103,M,11,0 +2016,Fla,103,F,86,3 +2016,Fla,104,M,8,0 +2016,Fla,104,F,45,1 +2016,Fla,105,M,3,0 +2016,Fla,105,F,22,1 +2016,Fla,106,M,0,0 +2016,Fla,106,F,16,0 +2016,Fla,107,M,0,0 +2016,Fla,107,F,8,0 +2016,Fla,108,M,0,0 +2016,Fla,108,F,0,1 +2016,Fla,109,M,0,0 +2016,Fla,109,F,1,0 +2016,Fla,110,M,0,0 +2016,Fla,110,F,1,0 +2016,Fla,111,M,0,0 +2016,Fla,111,F,0,0 +2016,Fla,112,M,0,0 +2016,Fla,112,F,0,0 +2016,Fla,113,M,0,0 +2016,Fla,113,F,0,0 +2016,Fla,114,M,0,0 +2016,Fla,114,F,0,0 +2016,Fla,115,M,1,0 +2016,Fla,115,F,0,0 +2016,Fla,116,M,0,0 +2016,Fla,116,F,0,0 +2016,Fla,117,M,0,0 +2016,Fla,117,F,1,0 +2016,Fla,118,M,0,0 +2016,Fla,118,F,0,0 +2016,Fla,119,M,0,0 +2016,Fla,119,F,0,0 +2016,Fla,120,M,0,0 +2016,Fla,120,F,0,0 +2016,Wal,0,M,17869,1472 +2016,Wal,0,F,17242,1454 +2016,Wal,1,M,18820,1432 +2016,Wal,1,F,17604,1443 +2016,Wal,2,M,19076,1444 +2016,Wal,2,F,18189,1358 +2016,Wal,3,M,19533,1417 +2016,Wal,3,F,18908,1358 +2016,Wal,4,M,19866,1533 +2016,Wal,4,F,19117,1438 +2016,Wal,5,M,20408,1410 +2016,Wal,5,F,19518,1412 +2016,Wal,6,M,20387,1456 +2016,Wal,6,F,19690,1353 +2016,Wal,7,M,20754,1428 +2016,Wal,7,F,19563,1363 +2016,Wal,8,M,20578,1399 +2016,Wal,8,F,19510,1336 +2016,Wal,9,M,20585,1367 +2016,Wal,9,F,19914,1334 +2016,Wal,10,M,20363,1349 +2016,Wal,10,F,19543,1204 +2016,Wal,11,M,20316,1319 +2016,Wal,11,F,19317,1328 +2016,Wal,12,M,20036,1337 +2016,Wal,12,F,19437,1196 +2016,Wal,13,M,20176,1347 +2016,Wal,13,F,19131,1302 +2016,Wal,14,M,20741,1294 +2016,Wal,14,F,20017,1230 +2016,Wal,15,M,21141,1305 +2016,Wal,15,F,20089,1301 +2016,Wal,16,M,20549,1302 +2016,Wal,16,F,19555,1322 +2016,Wal,17,M,20609,1289 +2016,Wal,17,F,19738,1346 +2016,Wal,18,M,20644,1397 +2016,Wal,18,F,19809,1437 +2016,Wal,19,M,20742,1537 +2016,Wal,19,F,19945,1497 +2016,Wal,20,M,20262,1601 +2016,Wal,20,F,19378,1624 +2016,Wal,21,M,20303,1702 +2016,Wal,21,F,19420,1856 +2016,Wal,22,M,21041,1727 +2016,Wal,22,F,19949,2070 +2016,Wal,23,M,21890,1835 +2016,Wal,23,F,20936,2194 +2016,Wal,24,M,22146,1859 +2016,Wal,24,F,21339,2413 +2016,Wal,25,M,21526,2227 +2016,Wal,25,F,20635,2622 +2016,Wal,26,M,21336,2220 +2016,Wal,26,F,20343,2773 +2016,Wal,27,M,20884,2473 +2016,Wal,27,F,19902,2941 +2016,Wal,28,M,20102,2618 +2016,Wal,28,F,19327,3040 +2016,Wal,29,M,20058,2685 +2016,Wal,29,F,19325,3057 +2016,Wal,30,M,19240,2789 +2016,Wal,30,F,18870,3131 +2016,Wal,31,M,19067,2839 +2016,Wal,31,F,18787,3169 +2016,Wal,32,M,18978,2882 +2016,Wal,32,F,18318,2927 +2016,Wal,33,M,19180,2927 +2016,Wal,33,F,19092,3204 +2016,Wal,34,M,19442,2971 +2016,Wal,34,F,19642,3116 +2016,Wal,35,M,19622,3071 +2016,Wal,35,F,19721,3240 +2016,Wal,36,M,19513,3038 +2016,Wal,36,F,19058,3148 +2016,Wal,37,M,19128,3041 +2016,Wal,37,F,19062,3080 +2016,Wal,38,M,19330,2953 +2016,Wal,38,F,19348,3026 +2016,Wal,39,M,19629,2814 +2016,Wal,39,F,19791,2887 +2016,Wal,40,M,19774,2952 +2016,Wal,40,F,19989,2923 +2016,Wal,41,M,20530,3165 +2016,Wal,41,F,20510,2985 +2016,Wal,42,M,21333,3293 +2016,Wal,42,F,21415,3008 +2016,Wal,43,M,22039,3309 +2016,Wal,43,F,22146,3003 +2016,Wal,44,M,22332,3298 +2016,Wal,44,F,22558,2899 +2016,Wal,45,M,21980,3270 +2016,Wal,45,F,21960,2984 +2016,Wal,46,M,21692,3172 +2016,Wal,46,F,21928,2835 +2016,Wal,47,M,21240,3207 +2016,Wal,47,F,21736,2912 +2016,Wal,48,M,21589,3194 +2016,Wal,48,F,21889,2822 +2016,Wal,49,M,21932,3443 +2016,Wal,49,F,22278,2936 +2016,Wal,50,M,22624,3325 +2016,Wal,50,F,22961,2807 +2016,Wal,51,M,23197,3138 +2016,Wal,51,F,23759,2811 +2016,Wal,52,M,22614,3155 +2016,Wal,52,F,23427,2656 +2016,Wal,53,M,21880,3032 +2016,Wal,53,F,22864,2417 +2016,Wal,54,M,22240,2971 +2016,Wal,54,F,23265,2424 +2016,Wal,55,M,22149,3142 +2016,Wal,55,F,22837,2403 +2016,Wal,56,M,21845,2920 +2016,Wal,56,F,23435,2284 +2016,Wal,57,M,21269,2854 +2016,Wal,57,F,22938,2216 +2016,Wal,58,M,20857,2809 +2016,Wal,58,F,22344,2143 +2016,Wal,59,M,20149,2835 +2016,Wal,59,F,21927,2117 +2016,Wal,60,M,19722,2710 +2016,Wal,60,F,21785,2059 +2016,Wal,61,M,19517,2571 +2016,Wal,61,F,21347,2030 +2016,Wal,62,M,19069,2461 +2016,Wal,62,F,20960,1894 +2016,Wal,63,M,18471,2439 +2016,Wal,63,F,20510,1874 +2016,Wal,64,M,17828,2266 +2016,Wal,64,F,19984,1845 +2016,Wal,65,M,18080,2213 +2016,Wal,65,F,19945,1866 +2016,Wal,66,M,17794,2155 +2016,Wal,66,F,19892,1669 +2016,Wal,67,M,17907,2040 +2016,Wal,67,F,20251,1805 +2016,Wal,68,M,17465,2030 +2016,Wal,68,F,19856,1639 +2016,Wal,69,M,16834,1868 +2016,Wal,69,F,19581,1511 +2016,Wal,70,M,12137,1445 +2016,Wal,70,F,14851,1277 +2016,Wal,71,M,11895,1454 +2016,Wal,71,F,14331,1349 +2016,Wal,72,M,10775,1326 +2016,Wal,72,F,13329,1188 +2016,Wal,73,M,9308,1158 +2016,Wal,73,F,11670,1144 +2016,Wal,74,M,8399,1102 +2016,Wal,74,F,10703,1104 +2016,Wal,75,M,9126,1230 +2016,Wal,75,F,11878,1296 +2016,Wal,76,M,9578,1139 +2016,Wal,76,F,12874,1310 +2016,Wal,77,M,9143,958 +2016,Wal,77,F,12735,1257 +2016,Wal,78,M,8490,945 +2016,Wal,78,F,11797,1171 +2016,Wal,79,M,7820,858 +2016,Wal,79,F,11505,1129 +2016,Wal,80,M,7147,833 +2016,Wal,80,F,10926,1147 +2016,Wal,81,M,6977,737 +2016,Wal,81,F,10921,1120 +2016,Wal,82,M,6543,673 +2016,Wal,82,F,10459,1072 +2016,Wal,83,M,6221,628 +2016,Wal,83,F,10911,973 +2016,Wal,84,M,5745,564 +2016,Wal,84,F,10344,983 +2016,Wal,85,M,5100,520 +2016,Wal,85,F,9698,925 +2016,Wal,86,M,4215,435 +2016,Wal,86,F,8454,809 +2016,Wal,87,M,3458,339 +2016,Wal,87,F,7573,648 +2016,Wal,88,M,2879,295 +2016,Wal,88,F,6779,635 +2016,Wal,89,M,2358,240 +2016,Wal,89,F,5909,553 +2016,Wal,90,M,1991,202 +2016,Wal,90,F,5218,506 +2016,Wal,91,M,1505,138 +2016,Wal,91,F,4354,403 +2016,Wal,92,M,1087,83 +2016,Wal,92,F,3491,320 +2016,Wal,93,M,867,68 +2016,Wal,93,F,2821,244 +2016,Wal,94,M,611,56 +2016,Wal,94,F,2173,162 +2016,Wal,95,M,383,39 +2016,Wal,95,F,1648,122 +2016,Wal,96,M,219,19 +2016,Wal,96,F,882,86 +2016,Wal,97,M,103,6 +2016,Wal,97,F,422,35 +2016,Wal,98,M,53,4 +2016,Wal,98,F,295,19 +2016,Wal,99,M,39,2 +2016,Wal,99,F,208,15 +2016,Wal,100,M,29,1 +2016,Wal,100,F,152,13 +2016,Wal,101,M,14,2 +2016,Wal,101,F,141,12 +2016,Wal,102,M,13,1 +2016,Wal,102,F,80,4 +2016,Wal,103,M,2,1 +2016,Wal,103,F,43,2 +2016,Wal,104,M,0,1 +2016,Wal,104,F,24,3 +2016,Wal,105,M,1,0 +2016,Wal,105,F,8,0 +2016,Wal,106,M,1,1 +2016,Wal,106,F,4,1 +2016,Wal,107,M,0,0 +2016,Wal,107,F,1,0 +2016,Wal,108,M,0,0 +2016,Wal,108,F,2,0 +2016,Wal,109,M,0,0 +2016,Wal,109,F,0,0 +2016,Wal,110,M,0,0 +2016,Wal,110,F,1,1 +2016,Wal,111,M,0,0 +2016,Wal,111,F,0,0 +2016,Wal,112,M,0,0 +2016,Wal,112,F,0,0 +2016,Wal,113,M,0,0 +2016,Wal,113,F,0,0 +2016,Wal,114,M,0,0 +2016,Wal,114,F,0,0 +2016,Wal,115,M,0,0 +2016,Wal,115,F,0,0 +2016,Wal,116,M,0,0 +2016,Wal,116,F,0,0 +2016,Wal,117,M,0,0 +2016,Wal,117,F,0,0 +2016,Wal,118,M,0,0 +2016,Wal,118,F,0,0 +2016,Wal,119,M,0,0 +2016,Wal,119,F,0,0 +2016,Wal,120,M,0,0 +2016,Wal,120,F,0,0 diff --git a/larray/tests/data/qx.csv b/larray/tests/data/qx.csv new file mode 100644 index 000000000..b1727e1d0 --- /dev/null +++ b/larray/tests/data/qx.csv @@ -0,0 +1,18877 @@ +time,geo,age,sex\nat,BE,FO +1991,BruCap,0,M,0.001673840267814443,0.0029448885149347924 +1991,BruCap,0,F,0.002961500493583416,0.002285191956124315 +1991,BruCap,1,M,0.0002561475409836065,0.0 +1991,BruCap,1,F,0.0002653223666755107,0.001338688085676038 +1991,BruCap,2,M,0.0002638522427440633,0.0004228329809725159 +1991,BruCap,2,F,0.0,0.0 +1991,BruCap,3,M,0.0,0.0004355400696864112 +1991,BruCap,3,F,0.0,0.0004480286738351255 +1991,BruCap,4,M,0.0005715918833952558,0.0 +1991,BruCap,4,F,0.0,0.0009107468123861566 +1991,BruCap,5,M,0.0,0.0004385964912280702 +1991,BruCap,5,F,0.0,0.0 +1991,BruCap,6,M,0.0003032140691328078,0.0004380201489268507 +1991,BruCap,6,F,0.0006441223832528183,0.0 +1991,BruCap,7,M,0.0003169572107765452,0.0008795074758135447 +1991,BruCap,7,F,0.0,0.0 +1991,BruCap,8,M,0.0006361323155216285,0.0004257130693912303 +1991,BruCap,8,F,0.0,0.0 +1991,BruCap,9,M,0.0006150061500615006,0.00040176777822418635 +1991,BruCap,9,F,0.00032133676092544985,0.0004306632213608958 +1991,BruCap,10,M,0.0003112356053532525,0.0 +1991,BruCap,10,F,0.0006365372374283894,0.0004246284501061572 +1991,BruCap,11,M,0.0003188775510204082,0.0 +1991,BruCap,11,F,0.0,0.0008869179600886918 +1991,BruCap,12,M,0.0,0.0004275331338178709 +1991,BruCap,12,F,0.0003297065611605672,0.0004325259515570935 +1991,BruCap,13,M,0.0003362474781439138,0.0 +1991,BruCap,13,F,0.0,0.0 +1991,BruCap,14,M,0.0003394433129667346,0.00089126559714795 +1991,BruCap,14,F,0.0,0.0 +1991,BruCap,15,M,0.0006587615283267457,0.0009128251939753537 +1991,BruCap,15,F,0.0,0.0 +1991,BruCap,16,M,0.0,0.0004420866489832007 +1991,BruCap,16,F,0.0,0.0 +1991,BruCap,17,M,0.0003024803387779795,0.001378043178686266 +1991,BruCap,17,F,0.0003075976622577669,0.0 +1991,BruCap,18,M,0.001426940639269407,0.0 +1991,BruCap,18,F,0.00029231218941829884,0.0004420866489832007 +1991,BruCap,19,M,0.0,0.002142245072836333 +1991,BruCap,19,F,0.000814774579033134,0.0 +1991,BruCap,20,M,0.001018848700967906,0.0004011231448054553 +1991,BruCap,20,F,0.0007589172780166963,0.0004111842105263158 +1991,BruCap,21,M,0.0010167768174885608,0.001574803149606299 +1991,BruCap,21,F,0.0002475247524752476,0.0003951007506914263 +1991,BruCap,22,M,0.0009332711152589829,0.001542614731970691 +1991,BruCap,22,F,0.0002306805074971165,0.0003992015968063872 +1991,BruCap,23,M,0.001969365426695843,0.0015533980582524269 +1991,BruCap,23,F,0.0004144218814753419,0.0007886435331230284 +1991,BruCap,24,M,0.001676445934618609,0.0003497726477789437 +1991,BruCap,24,F,0.000576036866359447,0.0010623229461756366 +1991,BruCap,25,M,0.001342281879194631,0.0016863406408094439 +1991,BruCap,25,F,0.0001838235294117647,0.00034566194262011747 +1991,BruCap,26,M,0.001305970149253732,0.0019361084220716359 +1991,BruCap,26,F,0.0005207429265752471,0.0003367003367003366 +1991,BruCap,27,M,0.0014633254069873786,0.002315580549123387 +1991,BruCap,27,F,0.0003634381246592768,0.0 +1991,BruCap,28,M,0.001541425818882467,0.0003154574132492114 +1991,BruCap,28,F,0.0005687203791469196,0.00034626038781163435 +1991,BruCap,29,M,0.0021589793915603533,0.000986842105263158 +1991,BruCap,29,F,0.0,0.001048584411045089 +1991,BruCap,30,M,0.0019751135690302193,0.0009652509652509653 +1991,BruCap,30,F,0.0013227513227513233,0.00034293552812071334 +1991,BruCap,31,M,0.0007883326763894362,0.0003430531732418525 +1991,BruCap,31,F,0.0009712509712509713,0.0007493443237167477 +1991,BruCap,32,M,0.001905972045743329,0.00104384133611691 +1991,BruCap,32,F,0.0005881199764752007,0.0 +1991,BruCap,33,M,0.001263956182852328,0.001130795326045986 +1991,BruCap,33,F,0.001420166362345304,0.0004103405826836274 +1991,BruCap,34,M,0.0022286605749944283,0.001096491228070175 +1991,BruCap,34,F,0.002044571662236761,0.0 +1991,BruCap,35,M,0.002011173184357542,0.001916443081640475 +1991,BruCap,35,F,0.00042435815828559313,0.0 +1991,BruCap,36,M,0.002443358507330076,0.002012072434607646 +1991,BruCap,36,F,0.0008525149190110827,0.0004545454545454545 +1991,BruCap,37,M,0.001796945193171609,0.001245847176079734 +1991,BruCap,37,F,0.0006313131313131314,0.0009398496240601504 +1991,BruCap,38,M,0.003256571295650152,0.001201441730076092 +1991,BruCap,38,F,0.001264222503160557,0.0004686035613870666 +1991,BruCap,39,M,0.0037444418441376077,0.002770083102493075 +1991,BruCap,39,F,0.0021290185224611463,0.0005470459518599561 +1991,BruCap,40,M,0.00380952380952381,0.0008861320336730172 +1991,BruCap,40,F,0.003383379149925989,0.002031488065007618 +1991,BruCap,41,M,0.001894836570345808,0.0019851116625310174 +1991,BruCap,41,F,0.001486515183690805,0.001769911504424779 +1991,BruCap,42,M,0.0037200651011392704,0.001477104874446086 +1991,BruCap,42,F,0.001252086811352254,0.001185536455245999 +1991,BruCap,43,M,0.002951191827468786,0.002548419979612641 +1991,BruCap,43,F,0.003194250349371132,0.003174603174603175 +1991,BruCap,44,M,0.003978779840848807,0.001644736842105263 +1991,BruCap,44,F,0.001615182717544922,0.0019582245430809398 +1991,BruCap,45,M,0.005017163982043834,0.0006285355122564425 +1991,BruCap,45,F,0.002329373398555789,0.0007112375533428165 +1991,BruCap,46,M,0.006,0.002400960384153662 +1991,BruCap,46,F,0.003083021360933715,0.002162941600576784 +1991,BruCap,47,M,0.0051506567087303634,0.0038734667527437054 +1991,BruCap,47,F,0.003484320557491289,0.002243829468960359 +1991,BruCap,48,M,0.006361708573159649,0.003851091142490373 +1991,BruCap,48,F,0.004022526146419952,0.001593625498007968 +1991,BruCap,49,M,0.008457374830852503,0.0 +1991,BruCap,49,F,0.004384682841274482,0.0008764241893076249 +1991,BruCap,50,M,0.01077521700089793,0.005402160864345739 +1991,BruCap,50,F,0.003744316662209147,0.001402524544179523 +1991,BruCap,51,M,0.0053717839977381965,0.004713804713804714 +1991,BruCap,51,F,0.003383276945384244,0.0016433853738701733 +1991,BruCap,52,M,0.01072840203274986,0.0032488628979857053 +1991,BruCap,52,F,0.005120702267739576,0.002640845070422535 +1991,BruCap,53,M,0.008993816750983699,0.005046863734679163 +1991,BruCap,53,F,0.004399902224395014,0.003581020590868397 +1991,BruCap,54,M,0.01105615362234507,0.0028011204481792717 +1991,BruCap,54,F,0.003455936805726981,0.0008826125330979699 +1991,BruCap,55,M,0.012857142857142859,0.008627450980392156 +1991,BruCap,55,F,0.005299927728258251,0.003481288076588338 +1991,BruCap,56,M,0.009231604670105892,0.007911392405063292 +1991,BruCap,56,F,0.006583588055490242,0.005870841487279843 +1991,BruCap,57,M,0.01513513513513514,0.008271298593879239 +1991,BruCap,57,F,0.0069851284362325355,0.004410143329658214 +1991,BruCap,58,M,0.01710261569416499,0.01209677419354839 +1991,BruCap,58,F,0.007019783024888321,0.004246284501061571 +1991,BruCap,59,M,0.015753938484621158,0.008695652173913044 +1991,BruCap,59,F,0.00579950289975145,0.006928406466512702 +1991,BruCap,60,M,0.01645153125790939,0.014159292035398232 +1991,BruCap,60,F,0.008304364619544225,0.009771986970684038 +1991,BruCap,61,M,0.01418622646376064,0.014955134596211369 +1991,BruCap,61,F,0.00790433725172274,0.001377410468319559 +1991,BruCap,62,M,0.01889267908685384,0.012944983818770229 +1991,BruCap,62,F,0.006950122649223222,0.0054054054054054074 +1991,BruCap,63,M,0.02083333333333333,0.01904761904761905 +1991,BruCap,63,F,0.01115844998985595,0.01098901098901099 +1991,BruCap,64,M,0.02132639791937581,0.01925545571245186 +1991,BruCap,64,F,0.0100058858151854,0.009302325581395349 +1991,BruCap,65,M,0.02451612903225807,0.0309423347398031 +1991,BruCap,65,F,0.01349553316859913,0.0034423407917383822 +1991,BruCap,66,M,0.024912805181863482,0.03435804701627486 +1991,BruCap,66,F,0.00999259807549963,0.007736943907156673 +1991,BruCap,67,M,0.028966597077244263,0.020236087689713318 +1991,BruCap,67,F,0.01330258957076978,0.01523809523809524 +1991,BruCap,68,M,0.0286607608129234,0.02816901408450705 +1991,BruCap,68,F,0.014781834372217282,0.008492569002123142 +1991,BruCap,69,M,0.03204172876304024,0.02375809935205184 +1991,BruCap,69,F,0.01806496439117596,0.0194647201946472 +1991,BruCap,70,M,0.039285714285714285,0.023474178403755867 +1991,BruCap,70,F,0.01713607058025111,0.01464435146443515 +1991,BruCap,71,M,0.04222914503288335,0.04924242424242424 +1991,BruCap,71,F,0.02350728725905031,0.01916932907348243 +1991,BruCap,72,M,0.04241071428571429,0.05069124423963134 +1991,BruCap,72,F,0.02295918367346939,0.0242914979757085 +1991,BruCap,73,M,0.04345372460496614,0.027649769585253458 +1991,BruCap,73,F,0.0275974025974026,0.02489626556016598 +1991,BruCap,74,M,0.05496828752642706,0.03592814371257485 +1991,BruCap,74,F,0.030984204131227218,0.01818181818181818 +1991,BruCap,75,M,0.06422836752899197,0.04624277456647399 +1991,BruCap,75,F,0.029854490717511287,0.021739130434782608 +1991,BruCap,76,M,0.07241788682231895,0.08695652173913042 +1991,BruCap,76,F,0.03270732221987762,0.03389830508474577 +1991,BruCap,77,M,0.0743731406714832,0.0446927374301676 +1991,BruCap,77,F,0.03910493156636976,0.0391304347826087 +1991,BruCap,78,M,0.07289719626168224,0.042857142857142864 +1991,BruCap,78,F,0.03965248384940967,0.044 +1991,BruCap,79,M,0.09897959183673467,0.07246376811594203 +1991,BruCap,79,F,0.052093476144109065,0.039408866995073885 +1991,BruCap,80,M,0.09210526315789473,0.04918032786885247 +1991,BruCap,80,F,0.05937423010593744,0.04629629629629629 +1991,BruCap,81,M,0.1063553826199741,0.101010101010101 +1991,BruCap,81,F,0.06666666666666668,0.0427807486631016 +1991,BruCap,82,M,0.115018315018315,0.1441441441441442 +1991,BruCap,82,F,0.06632939853850478,0.06 +1991,BruCap,83,M,0.1192109777015438,0.1372549019607843 +1991,BruCap,83,F,0.08509965200885795,0.0880503144654088 +1991,BruCap,84,M,0.1554054054054054,0.1481481481481482 +1991,BruCap,84,F,0.08022322985699337,0.08724832214765099 +1991,BruCap,85,M,0.1398843930635838,0.0576923076923077 +1991,BruCap,85,F,0.0904152114862243,0.09027777777777778 +1991,BruCap,86,M,0.1654879773691655,0.1343283582089552 +1991,BruCap,86,F,0.108314606741573,0.09482758620689652 +1991,BruCap,87,M,0.1990369181380417,0.1481481481481482 +1991,BruCap,87,F,0.1305015353121802,0.1153846153846154 +1991,BruCap,88,M,0.1802575107296138,0.2105263157894737 +1991,BruCap,88,F,0.1411901983663944,0.1506849315068493 +1991,BruCap,89,M,0.193298969072165,0.1142857142857143 +1991,BruCap,89,F,0.1524347212420607,0.1645569620253165 +1991,BruCap,90,M,0.2437275985663083,0.2 +1991,BruCap,90,F,0.1766304347826087,0.1066666666666667 +1991,BruCap,91,M,0.2110552763819096,0.2 +1991,BruCap,91,F,0.1658986175115208,0.1162790697674419 +1991,BruCap,92,M,0.2215189873417722,0.1666666666666667 +1991,BruCap,92,F,0.2102803738317757,0.1333333333333333 +1991,BruCap,93,M,0.2522522522522523,0.2307692307692308 +1991,BruCap,93,F,0.2213279678068411,0.25 +1991,BruCap,94,M,0.2297297297297298,0.0 +1991,BruCap,94,F,0.2347826086956522,0.1904761904761905 +1991,BruCap,95,M,0.3043478260869566,0.0 +1991,BruCap,95,F,0.2150943396226415,0.35 +1991,BruCap,96,M,0.2195121951219512,0.0 +1991,BruCap,96,F,0.2487562189054727,0.4285714285714286 +1991,BruCap,97,M,0.2068965517241379,0.2857142857142857 +1991,BruCap,97,F,0.2892561983471074,0.0 +1991,BruCap,98,M,0.4,0.0 +1991,BruCap,98,F,0.3068181818181818,0.0 +1991,BruCap,99,M,0.5,0.0 +1991,BruCap,99,F,0.1914893617021277,0.0 +1991,BruCap,100,M,0.4285714285714286,0.25 +1991,BruCap,100,F,0.375,0.3333333333333333 +1991,BruCap,101,M,0.75,0.0 +1991,BruCap,101,F,0.3333333333333333,0.0 +1991,BruCap,102,M,0.3333333333333333,0.0 +1991,BruCap,102,F,0.2142857142857143,0.0 +1991,BruCap,103,M,1.0,0.0 +1991,BruCap,103,F,0.4,0.0 +1991,BruCap,104,M,0.0,0.0 +1991,BruCap,104,F,0.3333333333333333,0.0 +1991,BruCap,105,M,1.0,0.0 +1991,BruCap,105,F,0.6666666666666666,0.0 +1991,BruCap,106,M,0.0,0.0 +1991,BruCap,106,F,0.0,0.3333333333333333 +1991,BruCap,107,M,0.0,0.0 +1991,BruCap,107,F,0.0,0.0 +1991,BruCap,108,M,0.0,0.0 +1991,BruCap,108,F,0.0,0.0 +1991,BruCap,109,M,0.0,0.0 +1991,BruCap,109,F,0.0,0.0 +1991,BruCap,110,M,0.0,0.0 +1991,BruCap,110,F,0.0,0.0 +1991,BruCap,111,M,0.0,0.0 +1991,BruCap,111,F,0.0,0.0 +1991,BruCap,112,M,0.0,0.0 +1991,BruCap,112,F,0.0,0.0 +1991,BruCap,113,M,0.0,0.0 +1991,BruCap,113,F,0.0,0.0 +1991,BruCap,114,M,0.0,0.0 +1991,BruCap,114,F,0.0,0.0 +1991,BruCap,115,M,0.0,0.0 +1991,BruCap,115,F,0.0,0.0 +1991,BruCap,116,M,0.0,0.0 +1991,BruCap,116,F,0.0,0.0 +1991,BruCap,117,M,0.0,0.0 +1991,BruCap,117,F,0.0,0.0 +1991,BruCap,118,M,0.0,0.0 +1991,BruCap,118,F,0.0,0.0 +1991,BruCap,119,M,0.0,0.0 +1991,BruCap,119,F,0.0,0.0 +1991,BruCap,120,M,0.0,0.0 +1991,BruCap,120,F,0.0,0.0 +1991,Fla,0,M,0.0013449296153501301,0.0023375409069658717 +1991,Fla,0,F,0.00151309775241938,0.002819548872180451 +1991,Fla,1,M,0.000308708671626586,0.00046382189239332097 +1991,Fla,1,F,0.0003889537145079736,0.000944733112895607 +1991,Fla,2,M,0.00021838148125038998,0.0 +1991,Fla,2,F,0.00016324931435287969,0.000500751126690035 +1991,Fla,3,M,0.000344482024301641,0.0009182736455463727 +1991,Fla,3,F,0.0001988071570576541,0.0 +1991,Fla,4,M,0.0002810216698932118,0.0009332711152589829 +1991,Fla,4,F,0.00016506553101581332,0.0 +1991,Fla,5,M,0.00016080789888399318,0.0 +1991,Fla,5,F,0.000201450443190975,0.0009925558312655087 +1991,Fla,6,M,0.0001878875180058872,0.0 +1991,Fla,6,F,0.0002301042043325335,0.00048590864917395527 +1991,Fla,7,M,0.0002123206648669963,0.0004798464491362764 +1991,Fla,7,F,3.171683212280758e-05,0.0 +1991,Fla,8,M,0.0001774045711244493,0.0009029345372460496 +1991,Fla,8,F,9.40674777373636e-05,0.0 +1991,Fla,9,M,0.0001997260899338051,0.0 +1991,Fla,9,F,0.0001831893261685953,0.0 +1991,Fla,10,M,0.0001733953703436118,0.0 +1991,Fla,10,F,0.00024134914170211488,0.0 +1991,Fla,11,M,0.000227021198104373,0.0 +1991,Fla,11,F,6.05638494382703e-05,0.0 +1991,Fla,12,M,0.000145032632342277,0.0004721435316336166 +1991,Fla,12,F,0.0001214587192178059,0.001392111368909513 +1991,Fla,13,M,0.00032465615961277383,0.0004805382027871216 +1991,Fla,13,F,0.0001228576693900117,0.0 +1991,Fla,14,M,0.0003890235508872729,0.0005040322580645161 +1991,Fla,14,F,9.473883660708646e-05,0.0 +1991,Fla,15,M,0.000519639309185389,0.0 +1991,Fla,15,F,0.00032344664747549885,0.0 +1991,Fla,16,M,0.0008792497069167644,0.001075847229693383 +1991,Fla,16,F,0.00036896965224610286,0.001041124414367517 +1991,Fla,17,M,0.001092100473243538,0.0005313496280552603 +1991,Fla,17,F,0.00035517670040845315,0.0005219206680584551 +1991,Fla,18,M,0.001126307320997587,0.001925854597977853 +1991,Fla,18,F,0.0006453785285369549,0.0 +1991,Fla,19,M,0.0012103108181186106,0.00045892611289582384 +1991,Fla,19,F,0.00047860884362785496,0.00047058823529411766 +1991,Fla,20,M,0.001198053163609135,0.0009144947416552351 +1991,Fla,20,F,0.00033877104289362585,0.0009000900090009002 +1991,Fla,21,M,0.001319753977937698,0.0008673026886383347 +1991,Fla,21,F,0.0005467468562055769,0.0 +1991,Fla,22,M,0.001232164420020208,0.002203613926840018 +1991,Fla,22,F,0.00033397559409120096,0.0009170105456212746 +1991,Fla,23,M,0.0010896600734336141,0.00043840420868040335 +1991,Fla,23,F,0.0003014242294843134,0.0004621072088724584 +1991,Fla,24,M,0.001321310183360764,0.001468968049944914 +1991,Fla,24,F,0.0003624501631025734,0.0004037141703673799 +1991,Fla,25,M,0.001096761197036506,0.00177999288002848 +1991,Fla,25,F,0.00044578963421787373,0.001265822784810127 +1991,Fla,26,M,0.001052722038413612,0.002015451797111186 +1991,Fla,26,F,0.0006025844176133192,0.0 +1991,Fla,27,M,0.001253159907525441,0.0006990562740300594 +1991,Fla,27,F,0.0004046671612598638,0.0008661758336942398 +1991,Fla,28,M,0.001071858252214809,0.002983095790520385 +1991,Fla,28,F,0.0004772944224737488,0.0004468275245755138 +1991,Fla,29,M,0.001160651716888578,0.0017927572606669059 +1991,Fla,29,F,0.0006308437535203334,0.0 +1991,Fla,30,M,0.0007630675314765357,0.000992063492063492 +1991,Fla,30,F,0.00046233153794586105,0.0008873114463176574 +1991,Fla,31,M,0.001031946426611044,0.001430615164520744 +1991,Fla,31,F,0.00047504863593177403,0.0 +1991,Fla,32,M,0.001252432178561045,0.0006754474839581223 +1991,Fla,32,F,0.0004642741074330285,0.0 +1991,Fla,33,M,0.0011286172181842814,0.001452960406828914 +1991,Fla,33,F,0.0007267441860465116,0.001103752759381898 +1991,Fla,34,M,0.001534419826564062,0.0014678899082568812 +1991,Fla,34,F,0.0006891143692227265,0.0005221932114882506 +1991,Fla,35,M,0.001338530903625775,0.0003573981415296641 +1991,Fla,35,F,0.0006224563083552789,0.001646542261251372 +1991,Fla,36,M,0.001217910447761194,0.00078064012490242 +1991,Fla,36,F,0.0005399037989594582,0.0 +1991,Fla,37,M,0.0015302404663589998,0.00131233595800525 +1991,Fla,37,F,0.0008084074373484238,0.0012682308180088778 +1991,Fla,38,M,0.001211915553724217,0.00206953642384106 +1991,Fla,38,F,0.0009649078259103144,0.000649772579597141 +1991,Fla,39,M,0.001625190452006095,0.001755155770074594 +1991,Fla,39,F,0.0009205923354112418,0.0007087172218284907 +1991,Fla,40,M,0.0018333935857046948,0.001197126895450918 +1991,Fla,40,F,0.001343059542306376,0.0006548788474132286 +1991,Fla,41,M,0.002063904601742853,0.0008264462809917355 +1991,Fla,41,F,0.0016657852987837132,0.0 +1991,Fla,42,M,0.002526605926039354,0.003066141042487955 +1991,Fla,42,F,0.001432776721285852,0.0 +1991,Fla,43,M,0.00250851101953055,0.0009161704076958314 +1991,Fla,43,F,0.001106078162856842,0.0007189072609633358 +1991,Fla,44,M,0.002760095484384325,0.003363767419509851 +1991,Fla,44,F,0.001841429571802786,0.0015873015873015884 +1991,Fla,45,M,0.002986741102581996,0.001089324618736384 +1991,Fla,45,F,0.0019438012749049536,0.0 +1991,Fla,46,M,0.003598133468263339,0.002219755826859046 +1991,Fla,46,F,0.0021004776428612533,0.0008583690987124463 +1991,Fla,47,M,0.0037502563651812147,0.004415011037527594 +1991,Fla,47,F,0.002184974558515415,0.0009033423667570008 +1991,Fla,48,M,0.003960263122566789,0.0036122817579771218 +1991,Fla,48,F,0.002539987643303357,0.000900900900900901 +1991,Fla,49,M,0.004432194867592835,0.003073140749846343 +1991,Fla,49,F,0.002757798233518429,0.002008032128514056 +1991,Fla,50,M,0.004643962848297214,0.004555808656036446 +1991,Fla,50,F,0.002552134054199268,0.0016806722689075633 +1991,Fla,51,M,0.00533725959326401,0.004804804804804805 +1991,Fla,51,F,0.0027182841951190373,0.0010121457489878536 +1991,Fla,52,M,0.005215278395116603,0.005535055350553504 +1991,Fla,52,F,0.002896091738825182,0.003770028275212064 +1991,Fla,53,M,0.005793742757821553,0.008736559139784945 +1991,Fla,53,F,0.0034503631961259077,0.002145922746781116 +1991,Fla,54,M,0.00664389357234636,0.005726556907659271 +1991,Fla,54,F,0.003837534154053971,0.0 +1991,Fla,55,M,0.007714258835335068,0.00975975975975976 +1991,Fla,55,F,0.004260797596787543,0.0023809523809523807 +1991,Fla,56,M,0.008919104347283727,0.006792452830188679 +1991,Fla,56,F,0.003926505410184936,0.004509582863585118 +1991,Fla,57,M,0.0101688647849131,0.008540372670807454 +1991,Fla,57,F,0.004233090155813744,0.0024390243902439033 +1991,Fla,58,M,0.01049773755656109,0.0171606864274571 +1991,Fla,58,F,0.004939547973923782,0.00639386189258312 +1991,Fla,59,M,0.011909428045949293,0.01248884924174844 +1991,Fla,59,F,0.006054720968755355,0.013372956909361073 +1991,Fla,60,M,0.013527161438408573,0.01122625215889465 +1991,Fla,60,F,0.006755209525990382,0.002684563758389262 +1991,Fla,61,M,0.014644765485849991,0.014807502467917082 +1991,Fla,61,F,0.006257249252182406,0.008875739644970414 +1991,Fla,62,M,0.0156139105748758,0.01698513800424629 +1991,Fla,62,F,0.0070295489891135324,0.007267441860465115 +1991,Fla,63,M,0.01754324532530289,0.01783723522853958 +1991,Fla,63,F,0.008224899598393575,0.004901960784313725 +1991,Fla,64,M,0.02034573522088639,0.0215311004784689 +1991,Fla,64,F,0.00919771946955618,0.003125 +1991,Fla,65,M,0.02280639431616341,0.02187120291616039 +1991,Fla,65,F,0.01017261658772292,0.014446227929374 +1991,Fla,66,M,0.02285208801739708,0.02345679012345679 +1991,Fla,66,F,0.011315142894090259,0.006944444444444444 +1991,Fla,67,M,0.02781441977914296,0.0299625468164794 +1991,Fla,67,F,0.0129126213592233,0.008156606851549755 +1991,Fla,68,M,0.03020256337686492,0.02936857562408223 +1991,Fla,68,F,0.01360892254169651,0.02527075812274368 +1991,Fla,69,M,0.03177515533130395,0.042584434654919234 +1991,Fla,69,F,0.01648708739524543,0.02307692307692308 +1991,Fla,70,M,0.03635816014801428,0.04737732656514382 +1991,Fla,70,F,0.017502348724729458,0.01221995926680245 +1991,Fla,71,M,0.04024732352436023,0.04612159329140461 +1991,Fla,71,F,0.02168663720442845,0.02469135802469136 +1991,Fla,72,M,0.04685160722148833,0.0410958904109589 +1991,Fla,72,F,0.023883150207250483,0.01683501683501684 +1991,Fla,73,M,0.049856095070095634,0.05128205128205128 +1991,Fla,73,F,0.02723086164319562,0.03249097472924188 +1991,Fla,74,M,0.057479795480785086,0.05704697986577181 +1991,Fla,74,F,0.02810500508282007,0.03508771929824561 +1991,Fla,75,M,0.06084110154415427,0.06493506493506493 +1991,Fla,75,F,0.03122937084243132,0.03846153846153847 +1991,Fla,76,M,0.06465402083889928,0.07523510971786834 +1991,Fla,76,F,0.03633512544802868,0.030716723549488064 +1991,Fla,77,M,0.0743565979895915,0.045112781954887216 +1991,Fla,77,F,0.0393498324073649,0.030075187969924814 +1991,Fla,78,M,0.08394698085419734,0.04641350210970464 +1991,Fla,78,F,0.04720574762524712,0.05660377358490566 +1991,Fla,79,M,0.08349918581508955,0.06862745098039216 +1991,Fla,79,F,0.05482362940926477,0.044843049327354265 +1991,Fla,80,M,0.09488836662749706,0.06382978723404255 +1991,Fla,80,F,0.06080931263858092,0.08866995073891626 +1991,Fla,81,M,0.1091230395405346,0.12209302325581403 +1991,Fla,81,F,0.07119175357164385,0.05172413793103448 +1991,Fla,82,M,0.1210802508639447,0.1724137931034483 +1991,Fla,82,F,0.07371628630705394,0.07262569832402235 +1991,Fla,83,M,0.1266312921267747,0.14400000000000002 +1991,Fla,83,F,0.08638856812933025,0.05882352941176471 +1991,Fla,84,M,0.1377684651650079,0.1666666666666667 +1991,Fla,84,F,0.09940003243067942,0.1013513513513514 +1991,Fla,85,M,0.1553191489361702,0.1477272727272727 +1991,Fla,85,F,0.1081105822043208,0.1120689655172414 +1991,Fla,86,M,0.1662881655311633,0.1578947368421053 +1991,Fla,86,F,0.11175152097342303,0.0547945205479452 +1991,Fla,87,M,0.1791510611735331,0.1224489795918368 +1991,Fla,87,F,0.1346623794212219,0.1264367816091954 +1991,Fla,88,M,0.1904196357878068,0.2068965517241379 +1991,Fla,88,F,0.1511574428943738,0.1940298507462687 +1991,Fla,89,M,0.1942374565325385,0.25 +1991,Fla,89,F,0.1549295774647887,0.09090909090909093 +1991,Fla,90,M,0.2242090784044017,0.2666666666666667 +1991,Fla,90,F,0.1807853791059521,0.24 +1991,Fla,91,M,0.2467419635099913,0.1818181818181818 +1991,Fla,91,F,0.2040816326530612,0.054054054054054064 +1991,Fla,92,M,0.2140127388535032,0.3076923076923077 +1991,Fla,92,F,0.2119006849315069,0.2307692307692308 +1991,Fla,93,M,0.2676518883415435,0.2 +1991,Fla,93,F,0.234375,0.1428571428571429 +1991,Fla,94,M,0.2686915887850468,0.1428571428571429 +1991,Fla,94,F,0.2585924713584289,0.1764705882352941 +1991,Fla,95,M,0.3129251700680273,0.25 +1991,Fla,95,F,0.2777777777777778,0.2307692307692308 +1991,Fla,96,M,0.339622641509434,0.5 +1991,Fla,96,F,0.2976190476190476,0.3333333333333333 +1991,Fla,97,M,0.35,0.4 +1991,Fla,97,F,0.3062330623306233,0.6 +1991,Fla,98,M,0.4057971014492754,0.0 +1991,Fla,98,F,0.2995391705069124,0.5 +1991,Fla,99,M,0.2727272727272727,0.0 +1991,Fla,99,F,0.3525179856115108,0.0 +1991,Fla,100,M,0.36,0.0 +1991,Fla,100,F,0.4337349397590362,0.0 +1991,Fla,101,M,0.45,0.0 +1991,Fla,101,F,0.4821428571428572,0.8 +1991,Fla,102,M,0.6,0.0 +1991,Fla,102,F,0.2571428571428571,0.0 +1991,Fla,103,M,0.6,0.0 +1991,Fla,103,F,0.4285714285714286,0.0 +1991,Fla,104,M,0.0,0.0 +1991,Fla,104,F,0.3,1.0 +1991,Fla,105,M,0.5,0.0 +1991,Fla,105,F,0.75,0.0 +1991,Fla,106,M,0.0,0.0 +1991,Fla,106,F,0.0,0.0 +1991,Fla,107,M,0.0,0.0 +1991,Fla,107,F,0.5,0.0 +1991,Fla,108,M,0.0,0.0 +1991,Fla,108,F,0.0,0.0 +1991,Fla,109,M,0.0,0.0 +1991,Fla,109,F,0.0,0.0 +1991,Fla,110,M,0.0,0.0 +1991,Fla,110,F,0.0,0.0 +1991,Fla,111,M,0.0,0.0 +1991,Fla,111,F,0.0,0.0 +1991,Fla,112,M,0.0,0.0 +1991,Fla,112,F,0.0,0.0 +1991,Fla,113,M,0.0,0.0 +1991,Fla,113,F,0.0,0.0 +1991,Fla,114,M,0.0,0.0 +1991,Fla,114,F,0.0,0.0 +1991,Fla,115,M,0.0,0.0 +1991,Fla,115,F,0.0,0.0 +1991,Fla,116,M,0.0,0.0 +1991,Fla,116,F,0.0,0.0 +1991,Fla,117,M,0.0,0.0 +1991,Fla,117,F,0.0,0.0 +1991,Fla,118,M,0.0,0.0 +1991,Fla,118,F,0.0,0.0 +1991,Fla,119,M,0.0,0.0 +1991,Fla,119,F,0.0,0.0 +1991,Fla,120,M,0.0,0.0 +1991,Fla,120,F,0.0,0.0 +1991,Wal,0,M,0.002405228758169935,0.0009661835748792268 +1991,Wal,0,F,0.001316439032417311,0.003004506760140211 +1991,Wal,1,M,0.0006206682528188683,0.000925925925925926 +1991,Wal,1,F,0.00038113906130894036,0.0004844961240310077 +1991,Wal,2,M,0.0003628258954024776,0.001339285714285714 +1991,Wal,2,F,0.0002733136547501913,0.0004631773969430292 +1991,Wal,3,M,0.0002686583203481812,0.0 +1991,Wal,3,F,0.0002251618350689558,0.0009280742459396752 +1991,Wal,4,M,0.0002675656873762509,0.0 +1991,Wal,4,F,0.00022596316800361542,0.0009276437847866419 +1991,Wal,5,M,0.00022116554240849282,0.00044503782821539846 +1991,Wal,5,F,0.00023284242388963263,0.0004655493482309125 +1991,Wal,6,M,0.0002250351617440225,0.0 +1991,Wal,6,F,0.0001169727453503334,0.0 +1991,Wal,7,M,0.0003374198627825891,0.0004249893752656184 +1991,Wal,7,F,0.00012133713523023721,0.0 +1991,Wal,8,M,0.0001674200569228194,0.0 +1991,Wal,8,F,0.0001743679163034002,0.0 +1991,Wal,9,M,0.0002202885780372288,0.0 +1991,Wal,9,F,0.0002836235747915367,0.0004078303425774878 +1991,Wal,10,M,0.0001096972356296621,0.0 +1991,Wal,10,F,0.0001698465719300232,0.0 +1991,Wal,11,M,0.0001664632116302297,0.0 +1991,Wal,11,F,5.874750323111268e-05,0.0 +1991,Wal,12,M,0.00011257458065968701,0.0 +1991,Wal,12,F,0.0002339728591483388,0.0 +1991,Wal,13,M,0.0004409414099101582,0.0007751937984496124 +1991,Wal,13,F,0.00011660447761194034,0.0003885003885003885 +1991,Wal,14,M,0.0004359910621832253,0.0015533980582524269 +1991,Wal,14,F,0.0003962413675987773,0.0008156606851549756 +1991,Wal,15,M,0.0003759600408185187,0.0 +1991,Wal,15,F,0.0002241775486185059,0.001221001221001221 +1991,Wal,16,M,0.0007189072609633358,0.001092100473243538 +1991,Wal,16,F,0.0001087725023114157,0.0007830853563038371 +1991,Wal,17,M,0.0008326802507836991,0.002123893805309735 +1991,Wal,17,F,0.0005163955589981926,0.00036376864314296113 +1991,Wal,18,M,0.0015784942121878892,0.002229299363057325 +1991,Wal,18,F,0.00030025521693439436,0.001022843504943744 +1991,Wal,19,M,0.001358631998126025,0.001278772378516624 +1991,Wal,19,F,0.0006342082154356522,0.0 +1991,Wal,20,M,0.001724468288944242,0.0003179650238473768 +1991,Wal,20,F,0.0003027703486905183,0.000992063492063492 +1991,Wal,21,M,0.0018361923169847789,0.00125 +1991,Wal,21,F,0.000502563071665494,0.0 +1991,Wal,22,M,0.001741553465691397,0.0009210930303960699 +1991,Wal,22,F,0.00035776346723908817,0.0006589785831960461 +1991,Wal,23,M,0.001668302257114819,0.0003101736972704714 +1991,Wal,23,F,0.0006619818718810469,0.000341180484476288 +1991,Wal,24,M,0.001900955351920453,0.001295672454003628 +1991,Wal,24,F,0.00020097472742802594,0.0017846519928613922 +1991,Wal,25,M,0.0020383010997345468,0.001740860482467048 +1991,Wal,25,F,0.0003904915312149168,0.0009052504526252262 +1991,Wal,26,M,0.0017912092959169608,0.0012422360248447212 +1991,Wal,26,F,0.000562957402889848,0.00030129557095510696 +1991,Wal,27,M,0.0014940704080679801,0.001493651979088873 +1991,Wal,27,F,0.0006536863239482654,0.0003154574132492114 +1991,Wal,28,M,0.0017376194613379669,0.0012591286829513981 +1991,Wal,28,F,0.0005252853254381359,0.0009832841691248774 +1991,Wal,29,M,0.0016786347104355132,0.0010121457489878536 +1991,Wal,29,F,0.0005949656750572082,0.0 +1991,Wal,30,M,0.00169053768490256,0.001873097635214236 +1991,Wal,30,F,0.0007468608504877935,0.000986842105263158 +1991,Wal,31,M,0.0015679763881202733,0.00098159509202454 +1991,Wal,31,F,0.0008017817371937637,0.0010063737001006366 +1991,Wal,32,M,0.001683108139697976,0.0007251631617113853 +1991,Wal,32,F,0.0010900667665894538,0.0010166045408336161 +1991,Wal,33,M,0.002537713238404061,0.001221001221001221 +1991,Wal,33,F,0.0008270538503951482,0.00070298769771529 +1991,Wal,34,M,0.002015161692735822,0.002137767220902613 +1991,Wal,34,F,0.0008329862557267803,0.0 +1991,Wal,35,M,0.0021664821144865443,0.001741293532338309 +1991,Wal,35,F,0.001333517266749437,0.0010548523206751052 +1991,Wal,36,M,0.002550529355149182,0.002269861286254729 +1991,Wal,36,F,0.001342903449872656,0.00111358574610245 +1991,Wal,37,M,0.003289473684210526,0.002165087956698241 +1991,Wal,37,F,0.00125856523563138,0.0008143322475570032 +1991,Wal,38,M,0.002486253884771695,0.0016629711751662973 +1991,Wal,38,F,0.0011765813253012054,0.0004093327875562833 +1991,Wal,39,M,0.00271096214511041,0.0015019525382997901 +1991,Wal,39,F,0.0019013214183857781,0.0004168403501458942 +1991,Wal,40,M,0.003301419610432486,0.001441753171856978 +1991,Wal,40,F,0.001836850037678975,0.002404809619238477 +1991,Wal,41,M,0.0031624657792882088,0.003668602873738918 +1991,Wal,41,F,0.0019683194301246603,0.00129926375054136 +1991,Wal,42,M,0.0029768719945042358,0.002146580803434529 +1991,Wal,42,F,0.001494091547063884,0.0008322929671244277 +1991,Wal,43,M,0.0031006338060279967,0.001889763779527559 +1991,Wal,43,F,0.0025972842431422572,0.0004587155963302753 +1991,Wal,44,M,0.004577941794740038,0.001660026560424967 +1991,Wal,44,F,0.0027842439180245557,0.0024142926122646072 +1991,Wal,45,M,0.0045796737766624854,0.002465078060805259 +1991,Wal,45,F,0.002513013821576019,0.0034622042700519326 +1991,Wal,46,M,0.005238214018458469,0.0046335299073294025 +1991,Wal,46,F,0.0023055454435141373,0.001105583195135434 +1991,Wal,47,M,0.005248123297681526,0.0074487895716946 +1991,Wal,47,F,0.0027608346709470308,0.0006067961165048543 +1991,Wal,48,M,0.005758157389635317,0.0038406144983197314 +1991,Wal,48,F,0.0027185892725936807,0.001233806292412092 +1991,Wal,49,M,0.006883553224616898,0.003503503503503504 +1991,Wal,49,F,0.002320365070771135,0.003217503217503218 +1991,Wal,50,M,0.0056513761467889894,0.003795866722901729 +1991,Wal,50,F,0.0038714137573453173,0.001645639056500274 +1991,Wal,51,M,0.007255139056831924,0.006395614435815441 +1991,Wal,51,F,0.004487658937920718,0.001651982378854626 +1991,Wal,52,M,0.008747122657020717,0.00825242718446602 +1991,Wal,52,F,0.004368932038834953,0.002726281352235551 +1991,Wal,53,M,0.008729722298597746,0.0052656773575873615 +1991,Wal,53,F,0.004464285714285714,0.004174120453190221 +1991,Wal,54,M,0.009202023040179828,0.00542406311637081 +1991,Wal,54,F,0.0037971424893808725,0.004651162790697674 +1991,Wal,55,M,0.01062631949331457,0.008345606283750612 +1991,Wal,55,F,0.005372561560601214,0.004592422502870264 +1991,Wal,56,M,0.01196444087962035,0.01010611419909045 +1991,Wal,56,F,0.004970849953973611,0.0028522532800912717 +1991,Wal,57,M,0.01393567135592101,0.01112797167425392 +1991,Wal,57,F,0.006015311702515493,0.003932584269662922 +1991,Wal,58,M,0.01336163836163836,0.0136986301369863 +1991,Wal,58,F,0.006005338078291815,0.004576659038901603 +1991,Wal,59,M,0.01660792162016847,0.0162900683131897 +1991,Wal,59,F,0.008060182697474477,0.0058173356602675965 +1991,Wal,60,M,0.01941105769230769,0.016973811833171683 +1991,Wal,60,F,0.008709043598321916,0.011160714285714293 +1991,Wal,61,M,0.0191721686135094,0.01598401598401599 +1991,Wal,61,F,0.008125587308606491,0.006384213580963436 +1991,Wal,62,M,0.02186776434268073,0.02127659574468085 +1991,Wal,62,F,0.008866405570060923,0.00857843137254902 +1991,Wal,63,M,0.02132085283411336,0.02489019033674964 +1991,Wal,63,F,0.01014581138770305,0.0076335877862595426 +1991,Wal,64,M,0.02476555276713777,0.02873563218390805 +1991,Wal,64,F,0.01196852114985244,0.01008303677342823 +1991,Wal,65,M,0.02778143515470704,0.0328879753340185 +1991,Wal,65,F,0.01183337755372778,0.006049606775559589 +1991,Wal,66,M,0.031093007467752887,0.03976975405546835 +1991,Wal,66,F,0.011814209418999841,0.01386263390044109 +1991,Wal,67,M,0.033373656870419134,0.03082003302146395 +1991,Wal,67,F,0.01400452114462149,0.014824797843665768 +1991,Wal,68,M,0.03698394495412844,0.03905765654060756 +1991,Wal,68,F,0.01587650387298797,0.017642907551164433 +1991,Wal,69,M,0.04105912223431266,0.04852320675105485 +1991,Wal,69,F,0.01790500696901469,0.01274362818590705 +1991,Wal,70,M,0.04260536398467433,0.04292527821939587 +1991,Wal,70,F,0.01834862385321101,0.01791530944625407 +1991,Wal,71,M,0.0496055333405382,0.0461133069828722 +1991,Wal,71,F,0.02128949162815365,0.02132701421800948 +1991,Wal,72,M,0.048566878980891716,0.05882352941176471 +1991,Wal,72,F,0.02516470461172913,0.01785714285714286 +1991,Wal,73,M,0.058190795274202074,0.05555555555555555 +1991,Wal,73,F,0.03253481894150418,0.027290448343079917 +1991,Wal,74,M,0.056719303899452136,0.0611439842209073 +1991,Wal,74,F,0.03026725340774928,0.04065040650406504 +1991,Wal,75,M,0.0674785100286533,0.07871198568872988 +1991,Wal,75,F,0.03566663701858935,0.029498525073746312 +1991,Wal,76,M,0.07264516129032259,0.06440071556350628 +1991,Wal,76,F,0.03717557251908397,0.040927694406548434 +1991,Wal,77,M,0.08183079056865465,0.07285974499089254 +1991,Wal,77,F,0.04502693575621131,0.05491329479768786 +1991,Wal,78,M,0.09075235109717868,0.08977035490605427 +1991,Wal,78,F,0.05389466786796625,0.04489164086687307 +1991,Wal,79,M,0.09379078873764683,0.1170483460559797 +1991,Wal,79,F,0.059651045948661725,0.06949152542372881 +1991,Wal,80,M,0.1078665077473182,0.125 +1991,Wal,80,F,0.0614889792829439,0.07604562737642585 +1991,Wal,81,M,0.1241830065359477,0.1205357142857143 +1991,Wal,81,F,0.07394581381136688,0.07228915662650602 +1991,Wal,82,M,0.1414569536423841,0.1189427312775331 +1991,Wal,82,F,0.07999130529290295,0.08924485125858124 +1991,Wal,83,M,0.1403131716303347,0.1436781609195402 +1991,Wal,83,F,0.09079357745177312,0.09408602150537634 +1991,Wal,84,M,0.15423242467718806,0.1401273885350319 +1991,Wal,84,F,0.1046013911182451,0.120253164556962 +1991,Wal,85,M,0.1592328278322926,0.1788617886178862 +1991,Wal,85,F,0.1191162343900096,0.1346801346801347 +1991,Wal,86,M,0.1782283884738527,0.2272727272727273 +1991,Wal,86,F,0.1207293326252434,0.0842911877394636 +1991,Wal,87,M,0.2122610415293342,0.2093023255813954 +1991,Wal,87,F,0.1385759829968119,0.1058823529411765 +1991,Wal,88,M,0.2128922815945717,0.2794117647058824 +1991,Wal,88,F,0.1693147964250249,0.1373626373626374 +1991,Wal,89,M,0.2145922746781116,0.1777777777777778 +1991,Wal,89,F,0.176806626678092,0.1715976331360947 +1991,Wal,90,M,0.2646198830409357,0.3111111111111111 +1991,Wal,90,F,0.1856589147286822,0.2258064516129032 +1991,Wal,91,M,0.2810707456978968,0.39130434782608703 +1991,Wal,91,F,0.2178533475026568,0.2394366197183099 +1991,Wal,92,M,0.2658959537572254,0.2 +1991,Wal,92,F,0.2386917188587335,0.2 +1991,Wal,93,M,0.28125,0.368421052631579 +1991,Wal,93,F,0.25,0.2068965517241379 +1991,Wal,94,M,0.3473053892215569,0.3333333333333333 +1991,Wal,94,F,0.2513157894736842,0.1481481481481482 +1991,Wal,95,M,0.4468085106382979,0.0 +1991,Wal,95,F,0.2741652021089631,0.2666666666666667 +1991,Wal,96,M,0.3013698630136986,0.0 +1991,Wal,96,F,0.2537313432835821,0.2380952380952381 +1991,Wal,97,M,0.4081632653061225,0.0 +1991,Wal,97,F,0.3444976076555024,0.25 +1991,Wal,98,M,0.4782608695652174,0.0 +1991,Wal,98,F,0.3422818791946309,0.2 +1991,Wal,99,M,0.25,0.0 +1991,Wal,99,F,0.3333333333333333,0.2 +1991,Wal,100,M,0.7272727272727273,0.0 +1991,Wal,100,F,0.3877551020408163,0.3333333333333333 +1991,Wal,101,M,0.25,0.5 +1991,Wal,101,F,0.5161290322580645,0.0 +1991,Wal,102,M,1.0,0.0 +1991,Wal,102,F,0.36,0.0 +1991,Wal,103,M,1.0,0.0 +1991,Wal,103,F,0.6363636363636364,0.0 +1991,Wal,104,M,1.0,0.0 +1991,Wal,104,F,0.3333333333333333,0.0 +1991,Wal,105,M,0.0,0.0 +1991,Wal,105,F,0.0,0.0 +1991,Wal,106,M,0.0,0.0 +1991,Wal,106,F,1.0,0.0 +1991,Wal,107,M,0.0,0.0 +1991,Wal,107,F,0.0,0.0 +1991,Wal,108,M,0.0,0.0 +1991,Wal,108,F,0.0,0.0 +1991,Wal,109,M,0.0,0.0 +1991,Wal,109,F,0.0,0.0 +1991,Wal,110,M,0.0,0.0 +1991,Wal,110,F,0.0,0.0 +1991,Wal,111,M,0.0,0.0 +1991,Wal,111,F,0.0,0.0 +1991,Wal,112,M,0.0,0.0 +1991,Wal,112,F,0.0,0.0 +1991,Wal,113,M,0.0,0.0 +1991,Wal,113,F,0.0,0.0 +1991,Wal,114,M,0.0,0.0 +1991,Wal,114,F,0.0,0.0 +1991,Wal,115,M,0.0,0.0 +1991,Wal,115,F,0.0,0.0 +1991,Wal,116,M,0.0,0.0 +1991,Wal,116,F,0.0,0.0 +1991,Wal,117,M,0.0,0.0 +1991,Wal,117,F,0.0,0.0 +1991,Wal,118,M,0.0,0.0 +1991,Wal,118,F,0.0,0.0 +1991,Wal,119,M,0.0,0.0 +1991,Wal,119,F,0.0,0.0 +1991,Wal,120,M,0.0,0.0 +1991,Wal,120,F,0.0,0.0 +1992,BruCap,0,M,0.0028557829604950037,0.001322168356104011 +1992,BruCap,0,F,0.0012456402590931741,0.0 +1992,BruCap,1,M,0.0,0.0008240626287597857 +1992,BruCap,1,F,0.000261164794985636,0.0008845643520566123 +1992,BruCap,2,M,0.00027196083763937986,0.001279863481228669 +1992,BruCap,2,F,0.0002785515320334262,0.0 +1992,BruCap,3,M,0.001097092704333516,0.0 +1992,BruCap,3,F,0.0,0.0 +1992,BruCap,4,M,0.0,0.0 +1992,BruCap,4,F,0.0003067484662576688,0.0004510599909788002 +1992,BruCap,5,M,0.0,0.0 +1992,BruCap,5,F,0.0,0.0 +1992,BruCap,6,M,0.0,0.0 +1992,BruCap,6,F,0.00033863867253640373,0.0 +1992,BruCap,7,M,0.0,0.00089126559714795 +1992,BruCap,7,F,0.0,0.0004595588235294118 +1992,BruCap,8,M,0.0003235198964736332,0.00089126559714795 +1992,BruCap,8,F,0.000657030223390276,0.0 +1992,BruCap,9,M,0.0,0.0004310344827586207 +1992,BruCap,9,F,0.0,0.0 +1992,BruCap,10,M,0.0003103662321539417,0.0008173273395995097 +1992,BruCap,10,F,0.0003270111183780249,0.0 +1992,BruCap,11,M,0.00031416902293433867,0.0 +1992,BruCap,11,F,0.0,0.0004315925766076824 +1992,BruCap,12,M,0.0,0.0008361204013377926 +1992,BruCap,12,F,0.0006795786612300374,0.0 +1992,BruCap,13,M,0.0003370407819346141,0.0 +1992,BruCap,13,F,0.000333555703802535,0.0 +1992,BruCap,14,M,0.0003400204012240735,0.0 +1992,BruCap,14,F,0.0,0.00045662100456621 +1992,BruCap,15,M,0.0006818956699624957,0.0 +1992,BruCap,15,F,0.00103555402140145,0.0004692632566870014 +1992,BruCap,16,M,0.000985869208018403,0.0009376465072667604 +1992,BruCap,16,F,0.0003381805884342238,0.0 +1992,BruCap,17,M,0.0003331112591605597,0.00135013501350135 +1992,BruCap,17,F,0.0010152284263959394,0.0004897159647404506 +1992,BruCap,18,M,0.0003034901365705615,0.001798561151079137 +1992,BruCap,18,F,0.0012198841110094539,0.0004545454545454545 +1992,BruCap,19,M,0.0,0.0008431703204047218 +1992,BruCap,19,F,0.0008573878250928838,0.0004217629692113034 +1992,BruCap,20,M,0.001045751633986928,0.0033319450229071213 +1992,BruCap,20,F,0.001317523056653492,0.0004016064257028113 +1992,BruCap,21,M,0.001512096774193549,0.0019149751053236309 +1992,BruCap,21,F,0.0007349338559529642,0.0008093889113719142 +1992,BruCap,22,M,0.0009903441445902454,0.0 +1992,BruCap,22,F,0.0002378686964795433,0.0003846153846153846 +1992,BruCap,23,M,0.002743484224965706,0.0 +1992,BruCap,23,F,0.001107910480833149,0.0 +1992,BruCap,24,M,0.001290877796901894,0.0007448789571694597 +1992,BruCap,24,F,0.0,0.0003777861730260674 +1992,BruCap,25,M,0.0022793203481143802,0.001657824933687003 +1992,BruCap,25,F,0.0007649646203863071,0.0 +1992,BruCap,26,M,0.0005836575875486381,0.0012734797835084366 +1992,BruCap,26,F,0.0005580357142857144,0.0006704659738518273 +1992,BruCap,27,M,0.001316531878879067,0.0009442870632672332 +1992,BruCap,27,F,0.0005396654074473826,0.000663129973474801 +1992,BruCap,28,M,0.001708752610594266,0.0012974375608173858 +1992,BruCap,28,F,0.0005631687629059508,0.0007024938531787848 +1992,BruCap,29,M,0.001413855786709756,0.001575795776867318 +1992,BruCap,29,F,0.0001966955153422502,0.0006949270326615705 +1992,BruCap,30,M,0.002899751449875725,0.0009693053311793213 +1992,BruCap,30,F,0.0009633911368015414,0.0003513703443429375 +1992,BruCap,31,M,0.0008303923603902845,0.0009680542110358179 +1992,BruCap,31,F,0.001173479366321142,0.001040582726326743 +1992,BruCap,32,M,0.00266011868221813,0.002097168822090179 +1992,BruCap,32,F,0.001221498371335505,0.0003750937734433609 +1992,BruCap,33,M,0.0008770006577504934,0.0013947001394700141 +1992,BruCap,33,F,0.0008074283407347598,0.001172791243158718 +1992,BruCap,34,M,0.001311475409836066,0.0007581501137225169 +1992,BruCap,34,F,0.001253656498119515,0.0004184100418410042 +1992,BruCap,35,M,0.0027586206896551718,0.0 +1992,BruCap,35,F,0.001054629824931449,0.00041511000415110015 +1992,BruCap,36,M,0.0020675396278428677,0.001150747986191024 +1992,BruCap,36,F,0.0006471095772217427,0.0008726003490401396 +1992,BruCap,37,M,0.0018294077292476559,0.002923976608187135 +1992,BruCap,37,F,0.0021915406530791147,0.00138121546961326 +1992,BruCap,38,M,0.002755453501722159,0.0012684989429175481 +1992,BruCap,38,F,0.001704303365999148,0.0009675858732462506 +1992,BruCap,39,M,0.002351834430856068,0.0004199916001679967 +1992,BruCap,39,F,0.000642535874919683,0.001447876447876448 +1992,BruCap,40,M,0.004312410158121706,0.0038535645472061657 +1992,BruCap,40,F,0.0017421602787456448,0.0005592841163310962 +1992,BruCap,41,M,0.0036746692797648218,0.0 +1992,BruCap,41,F,0.002151462994836489,0.00051440329218107 +1992,BruCap,42,M,0.003838771593090211,0.0005081300813008131 +1992,BruCap,42,F,0.001499892864795372,0.001829268292682927 +1992,BruCap,43,M,0.005177688867968933,0.00152827305145186 +1992,BruCap,43,F,0.002540220152413209,0.001794258373205742 +1992,BruCap,44,M,0.0034754402224281733,0.002644103648863036 +1992,BruCap,44,F,0.001217038539553753,0.0006447453255963892 +1992,BruCap,45,M,0.004933841668535546,0.00335946248600224 +1992,BruCap,45,F,0.003480753480753481,0.002652519893899204 +1992,BruCap,46,M,0.005637583892617449,0.0025364616360177552 +1992,BruCap,46,F,0.0035494557501183147,0.002192982456140351 +1992,BruCap,47,M,0.004076433121019108,0.001880877742946709 +1992,BruCap,47,F,0.002231146809460063,0.0007326007326007326 +1992,BruCap,48,M,0.0055176037834997384,0.00533689126084056 +1992,BruCap,48,F,0.003291794027745121,0.003095975232198143 +1992,BruCap,49,M,0.004324992276799507,0.007853403141361256 +1992,BruCap,49,F,0.0037919826652221024,0.003231017770597739 +1992,BruCap,50,M,0.010366275051831379,0.0060652009097801355 +1992,BruCap,50,F,0.0023717758671805518,0.0017793594306049821 +1992,BruCap,51,M,0.00827966881324747,0.001840490797546013 +1992,BruCap,51,F,0.004638472032742157,0.00211864406779661 +1992,BruCap,52,M,0.008340523439746908,0.006863417982155114 +1992,BruCap,52,F,0.0053816046966731895,0.001666666666666667 +1992,BruCap,53,M,0.008933717579250721,0.00398936170212766 +1992,BruCap,53,F,0.004215224398710638,0.002664298401420959 +1992,BruCap,54,M,0.006932409012131714,0.0014760147601476019 +1992,BruCap,54,F,0.004945598417408506,0.0009124087591240877 +1992,BruCap,55,M,0.009158050221565732,0.005830903790087464 +1992,BruCap,55,F,0.0052737317930688105,0.002669039145907474 +1992,BruCap,56,M,0.01174743024963289,0.005613472333600641 +1992,BruCap,56,F,0.00783162016642193,0.0026857654431512988 +1992,BruCap,57,M,0.010854439187308659,0.012126111560226359 +1992,BruCap,57,F,0.008147615624251139,0.0010101010101010099 +1992,BruCap,58,M,0.01166666666666667,0.006003430531732418 +1992,BruCap,58,F,0.007826887661141806,0.004555808656036446 +1992,BruCap,59,M,0.015080603224128969,0.01086048454469507 +1992,BruCap,59,F,0.007405793944674362,0.005446623093681918 +1992,BruCap,60,M,0.01733954451345756,0.01003009027081244 +1992,BruCap,60,F,0.0063465199915379725,0.004784688995215311 +1992,BruCap,61,M,0.017461558509252018,0.012962962962962959 +1992,BruCap,61,F,0.009242871189773844,0.010146561443066521 +1992,BruCap,62,M,0.02217472615549025,0.01464435146443515 +1992,BruCap,62,F,0.008853201564751905,0.00723589001447178 +1992,BruCap,63,M,0.02282608695652174,0.01812004530011325 +1992,BruCap,63,F,0.01044932079414838,0.004189944134078211 +1992,BruCap,64,M,0.02146985962014864,0.0100250626566416 +1992,BruCap,64,F,0.010147028370262993,0.004958677685950414 +1992,BruCap,65,M,0.02752293577981652,0.0252808988764045 +1992,BruCap,65,F,0.01058306709265176,0.01349072512647555 +1992,BruCap,66,M,0.02598446289847308,0.02476780185758514 +1992,BruCap,66,F,0.01239589386015882,0.0054249547920434 +1992,BruCap,67,M,0.02901554404145078,0.02376237623762377 +1992,BruCap,67,F,0.014304536043666482,0.01226993865030675 +1992,BruCap,68,M,0.0330982094411286,0.016393442622950817 +1992,BruCap,68,F,0.0146606334841629,0.01803607214428858 +1992,BruCap,69,M,0.03625541125541126,0.03289473684210526 +1992,BruCap,69,F,0.014005092761004,0.018140589569161 +1992,BruCap,70,M,0.037218919617472215,0.027649769585253458 +1992,BruCap,70,F,0.01900870492094511,0.007853403141361256 +1992,BruCap,71,M,0.04172238566461621,0.04060913705583756 +1992,BruCap,71,F,0.02098508498092265,0.01773835920177384 +1992,BruCap,72,M,0.04941860465116279,0.03813559322033898 +1992,BruCap,72,F,0.022076661814653082,0.020408163265306117 +1992,BruCap,73,M,0.04264018691588785,0.025 +1992,BruCap,73,F,0.02388743455497383,0.01255230125523013 +1992,BruCap,74,M,0.06205250596658711,0.04060913705583756 +1992,BruCap,74,F,0.03115577889447237,0.02564102564102564 +1992,BruCap,75,M,0.06366197183098593,0.09210526315789473 +1992,BruCap,75,F,0.02741884651749134,0.01449275362318841 +1992,BruCap,76,M,0.06567593480345159,0.049689440993788817 +1992,BruCap,76,F,0.030169050715214567,0.03286384976525822 +1992,BruCap,77,M,0.0668103448275862,0.07692307692307693 +1992,BruCap,77,F,0.03667105841018885,0.022624434389140267 +1992,BruCap,78,M,0.08383233532934131,0.09146341463414634 +1992,BruCap,78,F,0.048585766423357664,0.02293577981651377 +1992,BruCap,79,M,0.08046558704453441,0.07575757575757576 +1992,BruCap,79,F,0.053420805998125584,0.02542372881355933 +1992,BruCap,80,M,0.09863169897377423,0.032786885245901634 +1992,BruCap,80,F,0.05177323323841574,0.03664921465968586 +1992,BruCap,81,M,0.1144845034788109,0.054545454545454536 +1992,BruCap,81,F,0.058683584456780326,0.04950495049504952 +1992,BruCap,82,M,0.1071953010279001,0.1097560975609756 +1992,BruCap,82,F,0.06720916214587101,0.05232558139534884 +1992,BruCap,83,M,0.117056856187291,0.1170212765957447 +1992,BruCap,83,F,0.07687632938316621,0.02222222222222222 +1992,BruCap,84,M,0.1237721021611002,0.1176470588235294 +1992,BruCap,84,F,0.07641311933007676,0.09027777777777778 +1992,BruCap,85,M,0.1485714285714286,0.09523809523809523 +1992,BruCap,85,F,0.09227799227799227,0.1060606060606061 +1992,BruCap,86,M,0.1639566395663957,0.1666666666666667 +1992,BruCap,86,F,0.1,0.1085271317829457 +1992,BruCap,87,M,0.1462585034013606,0.1929824561403509 +1992,BruCap,87,F,0.1324130879345603,0.1568627450980392 +1992,BruCap,88,M,0.1700404858299595,0.2727272727272727 +1992,BruCap,88,F,0.1464435146443515,0.1294117647058824 +1992,BruCap,89,M,0.1952506596306069,0.1379310344827586 +1992,BruCap,89,F,0.1457182320441989,0.1090909090909091 +1992,BruCap,90,M,0.2272727272727273,0.103448275862069 +1992,BruCap,90,F,0.1549657534246576,0.1333333333333333 +1992,BruCap,91,M,0.2087378640776699,0.1363636363636364 +1992,BruCap,91,F,0.1537598204264871,0.09230769230769233 +1992,BruCap,92,M,0.2352941176470588,0.2 +1992,BruCap,92,F,0.1797752808988764,0.375 +1992,BruCap,93,M,0.2833333333333334,0.0 +1992,BruCap,93,F,0.2324649298597195,0.1794871794871795 +1992,BruCap,94,M,0.2588235294117648,0.0 +1992,BruCap,94,F,0.2595628415300547,0.1304347826086957 +1992,BruCap,95,M,0.1454545454545455,0.75 +1992,BruCap,95,F,0.2684824902723736,0.2352941176470588 +1992,BruCap,96,M,0.5,0.25 +1992,BruCap,96,F,0.2461538461538462,0.25 +1992,BruCap,97,M,0.2962962962962963,0.0 +1992,BruCap,97,F,0.2827586206896552,0.0 +1992,BruCap,98,M,0.2,0.0 +1992,BruCap,98,F,0.3373493975903614,0.0 +1992,BruCap,99,M,0.1666666666666667,0.0 +1992,BruCap,99,F,0.35,0.1666666666666667 +1992,BruCap,100,M,0.25,0.5 +1992,BruCap,100,F,0.4166666666666667,0.0 +1992,BruCap,101,M,0.5,0.5 +1992,BruCap,101,F,0.25,0.0 +1992,BruCap,102,M,0.0,0.0 +1992,BruCap,102,F,0.3,0.0 +1992,BruCap,103,M,0.0,0.0 +1992,BruCap,103,F,0.3333333333333333,0.0 +1992,BruCap,104,M,0.0,0.0 +1992,BruCap,104,F,0.3333333333333333,0.0 +1992,BruCap,105,M,0.0,0.0 +1992,BruCap,105,F,0.0,1.0 +1992,BruCap,106,M,0.0,0.0 +1992,BruCap,106,F,0.0,0.0 +1992,BruCap,107,M,0.0,0.0 +1992,BruCap,107,F,0.0,0.0 +1992,BruCap,108,M,0.0,0.0 +1992,BruCap,108,F,0.0,0.0 +1992,BruCap,109,M,0.0,0.0 +1992,BruCap,109,F,0.0,0.0 +1992,BruCap,110,M,0.0,0.0 +1992,BruCap,110,F,0.0,0.0 +1992,BruCap,111,M,0.0,0.0 +1992,BruCap,111,F,0.0,0.0 +1992,BruCap,112,M,0.0,0.0 +1992,BruCap,112,F,0.0,0.0 +1992,BruCap,113,M,0.0,0.0 +1992,BruCap,113,F,0.0,0.0 +1992,BruCap,114,M,0.0,0.0 +1992,BruCap,114,F,0.0,0.0 +1992,BruCap,115,M,0.0,0.0 +1992,BruCap,115,F,0.0,0.0 +1992,BruCap,116,M,0.0,0.0 +1992,BruCap,116,F,0.0,0.0 +1992,BruCap,117,M,0.0,0.0 +1992,BruCap,117,F,0.0,0.0 +1992,BruCap,118,M,0.0,0.0 +1992,BruCap,118,F,0.0,0.0 +1992,BruCap,119,M,0.0,0.0 +1992,BruCap,119,F,0.0,0.0 +1992,BruCap,120,M,0.0,0.0 +1992,BruCap,120,F,0.0,0.0 +1992,Fla,0,M,0.0020391276080146572,0.0004268032437046522 +1992,Fla,0,F,0.001837433821239489,0.0027586206896551718 +1992,Fla,1,M,0.000655444659615671,0.0008908685968819599 +1992,Fla,1,F,0.00034490327031009936,0.0018091361374943469 +1992,Fla,2,M,0.0002762685330140897,0.0008976660682226213 +1992,Fla,2,F,0.0002902008835004676,0.0 +1992,Fla,3,M,0.0003421674754261541,0.0008676789587852494 +1992,Fla,3,F,0.00022764227642276425,0.00048309178743961346 +1992,Fla,4,M,9.377637460535777e-05,0.0008952551477170994 +1992,Fla,4,F,0.0001983798975037196,0.0 +1992,Fla,5,M,0.0002493532400336627,0.0004506534474988733 +1992,Fla,5,F,0.0001317653259544751,0.0005042864346949069 +1992,Fla,6,M,0.0002887577002053388,0.0 +1992,Fla,6,F,3.35042047776996e-05,0.0 +1992,Fla,7,M,0.000343868204695364,0.00045372050816696913 +1992,Fla,7,F,0.00016417126346204361,0.0 +1992,Fla,8,M,0.0003636143264044603,0.0 +1992,Fla,8,F,3.162355322244007e-05,0.0009302325581395347 +1992,Fla,9,M,0.0001181020992648144,0.001344688480502017 +1992,Fla,9,F,6.260760682422915e-05,0.00044464206313917306 +1992,Fla,10,M,0.0002278034056609147,0.0004361098996947232 +1992,Fla,10,F,0.000213362594489149,0.0 +1992,Fla,11,M,0.0002307670118556553,0.00040567951318458417 +1992,Fla,11,F,6.0231892787230835e-05,0.0 +1992,Fla,12,M,0.00042510982003684286,0.0004249893752656184 +1992,Fla,12,F,6.0470460180201964e-05,0.0 +1992,Fla,13,M,0.0001738475357111813,0.00046382189239332097 +1992,Fla,13,F,0.0002122627206016132,0.0 +1992,Fla,14,M,0.0002654397451778447,0.00046663555762949143 +1992,Fla,14,F,0.00015334130708130158,0.0004692632566870014 +1992,Fla,15,M,0.00047846889952153117,0.001480750246791708 +1992,Fla,15,F,0.0003155370440489714,0.0 +1992,Fla,16,M,0.0006721456722984327,0.0 +1992,Fla,16,F,0.000129315918789603,0.0 +1992,Fla,17,M,0.0006741111990386588,0.001561686621551276 +1992,Fla,17,F,0.0003997539975399754,0.0005025125628140704 +1992,Fla,18,M,0.0008694920483549773,0.0004914004914004914 +1992,Fla,18,F,0.00047351287363125197,0.0 +1992,Fla,19,M,0.001208248308452368,0.0009191176470588236 +1992,Fla,19,F,0.0003646666105641112,0.0 +1992,Fla,20,M,0.0011075338055376686,0.003014642549526271 +1992,Fla,20,F,0.0003716879944777784,0.0008988764044943821 +1992,Fla,21,M,0.001000275075645803,0.0008532423208191126 +1992,Fla,21,F,0.0005217028380634388,0.0004228329809725159 +1992,Fla,22,M,0.001173474483171877,0.0020016012810248197 +1992,Fla,22,F,0.0003389476977629452,0.0004170141784820684 +1992,Fla,23,M,0.0009888018193953477,0.0016109544905356429 +1992,Fla,23,F,0.0003345772744820487,0.0 +1992,Fla,24,M,0.001046099712322579,0.0011485451761102607 +1992,Fla,24,F,0.0003779479943559767,0.0004299226139294927 +1992,Fla,25,M,0.0008386525648790942,0.00237449118046133 +1992,Fla,25,F,0.0003629851902042397,0.0007671653241273494 +1992,Fla,26,M,0.0009876099838391091,0.0006445375443119562 +1992,Fla,26,F,0.00047014574518100603,0.0004051863857374392 +1992,Fla,27,M,0.001078027640628706,0.0006205398696866272 +1992,Fla,27,F,0.00022328904767221166,0.0003850596842510589 +1992,Fla,28,M,0.001038286826735886,0.000982961992136304 +1992,Fla,28,F,0.0002697114087925919,0.0004053506282934739 +1992,Fla,29,M,0.001007181643019793,0.000317258883248731 +1992,Fla,29,F,0.0005907479778242298,0.0 +1992,Fla,30,M,0.0009861932938856016,0.001704739174906239 +1992,Fla,30,F,0.0004054327995134807,0.00047080979284369113 +1992,Fla,31,M,0.001301206981648495,0.001248829222603809 +1992,Fla,31,F,0.0005309203388656771,0.0012733446519524619 +1992,Fla,32,M,0.0010542962572482866,0.002425502425502426 +1992,Fla,32,F,0.00042921363543949216,0.001879699248120301 +1992,Fla,33,M,0.0012971328890280446,0.0003295978905735003 +1992,Fla,33,F,0.0005567412081284215,0.0004847309743092584 +1992,Fla,34,M,0.001286536508294775,0.001432664756446992 +1992,Fla,34,F,0.0005622715771717742,0.0005373455131649651 +1992,Fla,35,M,0.0010460980542576187,0.0017895490336435219 +1992,Fla,35,F,0.0006887215902344027,0.0005058168942842691 +1992,Fla,36,M,0.001574914202435241,0.002130681818181818 +1992,Fla,36,F,0.0007416267942583733,0.001060445387062566 +1992,Fla,37,M,0.001647485793419608,0.0015273004963726618 +1992,Fla,37,F,0.0009066405292820387,0.0005770340450086555 +1992,Fla,38,M,0.001749356139754119,0.001281503630926955 +1992,Fla,38,F,0.0009091138665117806,0.001223241590214067 +1992,Fla,39,M,0.001504489201650085,0.001649484536082475 +1992,Fla,39,F,0.001141552511415525,0.0012586532410320964 +1992,Fla,40,M,0.0018565143307647308,0.001304347826086957 +1992,Fla,40,F,0.001525954379225973,0.0013908205841446446 +1992,Fla,41,M,0.001628875042014634,0.0023856858846918487 +1992,Fla,41,F,0.0013444757862547134,0.0006430868167202572 +1992,Fla,42,M,0.002605230894973437,0.004103405826836274 +1992,Fla,42,F,0.001455796717840127,0.002617801047120419 +1992,Fla,43,M,0.0023258191483923733,0.003028991778450887 +1992,Fla,43,F,0.001486310299869622,0.0007147962830593281 +1992,Fla,44,M,0.00289966641005902,0.003184713375796179 +1992,Fla,44,F,0.0018174155823631672,0.002108222066057625 +1992,Fla,45,M,0.003091035995612723,0.0028625954198473282 +1992,Fla,45,F,0.001349317556697286,0.0023166023166023174 +1992,Fla,46,M,0.003781088953618642,0.003820960698689956 +1992,Fla,46,F,0.002003893278369404,0.004255319148936171 +1992,Fla,47,M,0.004062861495923031,0.004417448923246825 +1992,Fla,47,F,0.002333083702978282,0.005794701986754967 +1992,Fla,48,M,0.004584998824359276,0.0027442371020856213 +1992,Fla,48,F,0.002489054159419421,0.0017683465959328032 +1992,Fla,49,M,0.004243853149208488,0.004767580452920143 +1992,Fla,49,F,0.0025108344225080828,0.003487358326068004 +1992,Fla,50,M,0.004673770798280052,0.00247066090179123 +1992,Fla,50,F,0.00291164283847848,0.0009784735812133072 +1992,Fla,51,M,0.005509921238549168,0.0005665722379603398 +1992,Fla,51,F,0.003665344004304257,0.002477291494632535 +1992,Fla,52,M,0.005889971629456025,0.0041617122473246145 +1992,Fla,52,F,0.0034142981221360327,0.003972194637537239 +1992,Fla,53,M,0.006846664483672194,0.006832298136645962 +1992,Fla,53,F,0.003519164784891053,0.0009487666034155598 +1992,Fla,54,M,0.007261029411764706,0.006715916722632639 +1992,Fla,54,F,0.003581509697392783,0.00419287211740042 +1992,Fla,55,M,0.007093987451524419,0.0056777856635912 +1992,Fla,55,F,0.0038190273799624257,0.004530011325028313 +1992,Fla,56,M,0.008145224940805051,0.004477611940298508 +1992,Fla,56,F,0.004396212493851451,0.0035169988276670576 +1992,Fla,57,M,0.008680064156995944,0.006782215523737754 +1992,Fla,57,F,0.005112628191633334,0.00111358574610245 +1992,Fla,58,M,0.0109503810857054,0.014797507788162 +1992,Fla,58,F,0.004941694036821647,0.0 +1992,Fla,59,M,0.01155065220041448,0.007109004739336493 +1992,Fla,59,F,0.005764353239566521,0.002544529262086514 +1992,Fla,60,M,0.013281345193127821,0.01158645276292335 +1992,Fla,60,F,0.006375279995405204,0.0121765601217656 +1992,Fla,61,M,0.01608554160855416,0.01215277777777778 +1992,Fla,61,F,0.006994214661946292,0.005319148936170214 +1992,Fla,62,M,0.015512169029152182,0.021169354838709683 +1992,Fla,62,F,0.007859269947502533,0.007396449704142011 +1992,Fla,63,M,0.01753482945576831,0.01295896328293737 +1992,Fla,63,F,0.00866816873200651,0.014662756598240468 +1992,Fla,64,M,0.02108412280076929,0.02132435465768799 +1992,Fla,64,F,0.008486379684513977,0.008116883116883116 +1992,Fla,65,M,0.022248838559814167,0.01820388349514563 +1992,Fla,65,F,0.01022806683184042,0.009419152276295131 +1992,Fla,66,M,0.024670275769356542,0.036764705882352935 +1992,Fla,66,F,0.010883523821754207,0.014563106796116509 +1992,Fla,67,M,0.025003771307889583,0.03258145363408521 +1992,Fla,67,F,0.01133690538421328,0.015817223198594032 +1992,Fla,68,M,0.03033355286096153,0.022077922077922082 +1992,Fla,68,F,0.01412281276623632,0.0180327868852459 +1992,Fla,69,M,0.033687278784093284,0.04491017964071857 +1992,Fla,69,F,0.015304359842465282,0.02407407407407408 +1992,Fla,70,M,0.03244964709932864,0.03343465045592705 +1992,Fla,70,F,0.01699746254649101,0.02348336594911937 +1992,Fla,71,M,0.03982854081085909,0.036458333333333336 +1992,Fla,71,F,0.01991792259251397,0.027027027027027032 +1992,Fla,72,M,0.04489357896619567,0.05739514348785873 +1992,Fla,72,F,0.02214159456693646,0.02795031055900621 +1992,Fla,73,M,0.04939981532779317,0.03693181818181819 +1992,Fla,73,F,0.02487528650397735,0.030612244897959183 +1992,Fla,74,M,0.0551219512195122,0.062314540059347175 +1992,Fla,74,F,0.02757012550579521,0.03383458646616541 +1992,Fla,75,M,0.0581913499344692,0.04301075268817205 +1992,Fla,75,F,0.03395460417051117,0.03260869565217391 +1992,Fla,76,M,0.06714664645699127,0.08710801393728224 +1992,Fla,76,F,0.03480083857442348,0.036231884057971016 +1992,Fla,77,M,0.07262091596518762,0.06164383561643835 +1992,Fla,77,F,0.04084003159410863,0.046099290780141834 +1992,Fla,78,M,0.08170966499807471,0.0873015873015873 +1992,Fla,78,F,0.04653384931441402,0.03846153846153847 +1992,Fla,79,M,0.08300228214014031,0.1052631578947368 +1992,Fla,79,F,0.05,0.04382470119521913 +1992,Fla,80,M,0.0944998518811099,0.08333333333333333 +1992,Fla,80,F,0.056850738722543676,0.07906976744186046 +1992,Fla,81,M,0.1074826989619377,0.1194029850746269 +1992,Fla,81,F,0.06708001180986123,0.07936507936507936 +1992,Fla,82,M,0.1135799404170805,0.1059602649006623 +1992,Fla,82,F,0.07619479929965631,0.06363636363636363 +1992,Fla,83,M,0.1281864530225783,0.07692307692307693 +1992,Fla,83,F,0.07922732362821948,0.1212121212121212 +1992,Fla,84,M,0.1448253239298016,0.0980392156862745 +1992,Fla,84,F,0.09467035136202133,0.08333333333333333 +1992,Fla,85,M,0.1518961671060637,0.1234567901234568 +1992,Fla,85,F,0.1064423249955012,0.08333333333333333 +1992,Fla,86,M,0.1602918973326623,0.1466666666666667 +1992,Fla,86,F,0.1185884283955683,0.1862745098039216 +1992,Fla,87,M,0.1654044229021509,0.2063492063492064 +1992,Fla,87,F,0.1274651274651275,0.1313868613138686 +1992,Fla,88,M,0.1980235651843406,0.2790697674418605 +1992,Fla,88,F,0.1425813159067281,0.1818181818181818 +1992,Fla,89,M,0.2157920549288867,0.1304347826086957 +1992,Fla,89,F,0.156233086776114,0.1964285714285714 +1992,Fla,90,M,0.2338062924120913,0.1666666666666667 +1992,Fla,90,F,0.173256330519769,0.15 +1992,Fla,91,M,0.2675555555555556,0.38095238095238093 +1992,Fla,91,F,0.1863691194209891,0.1538461538461539 +1992,Fla,92,M,0.24595842956120104,0.1764705882352941 +1992,Fla,92,F,0.235065942591156,0.2857142857142857 +1992,Fla,93,M,0.2403225806451613,0.4444444444444444 +1992,Fla,93,F,0.2306434023991276,0.1724137931034483 +1992,Fla,94,M,0.2522522522522523,0.2666666666666667 +1992,Fla,94,F,0.272108843537415,0.05263157894736842 +1992,Fla,95,M,0.3546325878594249,0.6 +1992,Fla,95,F,0.250551876379691,0.2142857142857143 +1992,Fla,96,M,0.29,0.3333333333333333 +1992,Fla,96,F,0.29186602870813394,0.3 +1992,Fla,97,M,0.3773584905660378,0.0 +1992,Fla,97,F,0.2773722627737226,0.1666666666666667 +1992,Fla,98,M,0.2911392405063291,0.3333333333333333 +1992,Fla,98,F,0.3529411764705883,0.0 +1992,Fla,99,M,0.275,0.0 +1992,Fla,99,F,0.375,1.0 +1992,Fla,100,M,0.5,0.0 +1992,Fla,100,F,0.4333333333333334,0.0 +1992,Fla,101,M,0.25,0.0 +1992,Fla,101,F,0.4042553191489362,0.0 +1992,Fla,102,M,0.6363636363636364,0.0 +1992,Fla,102,F,0.5862068965517241,0.0 +1992,Fla,103,M,0.0,0.0 +1992,Fla,103,F,0.48,0.0 +1992,Fla,104,M,1.0,0.0 +1992,Fla,104,F,0.6666666666666666,0.0 +1992,Fla,105,M,0.0,0.0 +1992,Fla,105,F,0.6666666666666666,0.0 +1992,Fla,106,M,1.0,0.0 +1992,Fla,106,F,0.0,0.0 +1992,Fla,107,M,0.0,0.0 +1992,Fla,107,F,1.0,0.0 +1992,Fla,108,M,0.0,0.0 +1992,Fla,108,F,1.0,0.0 +1992,Fla,109,M,0.0,0.0 +1992,Fla,109,F,0.0,0.0 +1992,Fla,110,M,0.0,0.0 +1992,Fla,110,F,0.0,0.0 +1992,Fla,111,M,0.0,0.0 +1992,Fla,111,F,0.0,0.0 +1992,Fla,112,M,0.0,0.0 +1992,Fla,112,F,0.0,0.0 +1992,Fla,113,M,0.0,0.0 +1992,Fla,113,F,0.0,0.0 +1992,Fla,114,M,0.0,0.0 +1992,Fla,114,F,0.0,0.0 +1992,Fla,115,M,0.0,0.0 +1992,Fla,115,F,0.0,0.0 +1992,Fla,116,M,0.0,0.0 +1992,Fla,116,F,0.0,0.0 +1992,Fla,117,M,0.0,0.0 +1992,Fla,117,F,0.0,0.0 +1992,Fla,118,M,0.0,0.0 +1992,Fla,118,F,0.0,0.0 +1992,Fla,119,M,0.0,0.0 +1992,Fla,119,F,0.0,0.0 +1992,Fla,120,M,0.0,0.0 +1992,Fla,120,F,0.0,0.0 +1992,Wal,0,M,0.002497960848287113,0.001979218208807521 +1992,Wal,0,F,0.00159821000479463,0.0 +1992,Wal,1,M,0.0003607131814902608,0.0 +1992,Wal,1,F,0.0001619170984455959,0.0 +1992,Wal,2,M,0.00035789150774579484,0.0004518752824220515 +1992,Wal,2,F,0.00032244196044711965,0.0004798464491362764 +1992,Wal,3,M,0.0003073770491803279,0.0 +1992,Wal,3,F,0.0001082368221669012,0.0 +1992,Wal,4,M,0.000372518758980363,0.0 +1992,Wal,4,F,5.5819145967066696e-05,0.0 +1992,Wal,5,M,5.3143434128713395e-05,0.0 +1992,Wal,5,F,5.6072670180554004e-05,0.0 +1992,Wal,6,M,0.0002747101807592989,0.0008748906386701663 +1992,Wal,6,F,0.00011553347582462022,0.00046641791044776135 +1992,Wal,7,M,0.00027984552527005095,0.0 +1992,Wal,7,F,0.00017422614553690692,0.00044247787610619474 +1992,Wal,8,M,0.0002794388867154753,0.0004257130693912303 +1992,Wal,8,F,6.041200990756963e-05,0.0 +1992,Wal,9,M,0.0002218647734206001,0.0 +1992,Wal,9,F,0.000289234685023428,0.0004154549231408392 +1992,Wal,10,M,0.00032869508053029467,0.0 +1992,Wal,10,F,5.6385678037778406e-05,0.0 +1992,Wal,11,M,0.0002732837778749453,0.0 +1992,Wal,11,F,0.0001689855235734806,0.0 +1992,Wal,12,M,0.0001656451880072884,0.0 +1992,Wal,12,F,5.839416058394163e-05,0.0 +1992,Wal,13,M,0.00022429068072221602,0.0003793626707132018 +1992,Wal,13,F,0.0003494060097833683,0.0004116920543433512 +1992,Wal,14,M,0.0006040968751716185,0.0003858024691358025 +1992,Wal,14,F,0.0002325446194988664,0.0 +1992,Wal,15,M,0.0004349717268377556,0.0 +1992,Wal,15,F,0.00022600146900954857,0.0 +1992,Wal,16,M,0.001072616110693983,0.001145038167938932 +1992,Wal,16,F,0.0002791892344631191,0.0008071025020177562 +1992,Wal,17,M,0.001178761787617876,0.0007163323782234957 +1992,Wal,17,F,0.0004338394793926247,0.000379794910748196 +1992,Wal,18,M,0.001079542666470386,0.0006697923643670463 +1992,Wal,18,F,0.0005672734773864164,0.0010467550593161196 +1992,Wal,19,M,0.001433623243811526,0.001907790143084261 +1992,Wal,19,F,0.000499226199390944,0.001015916017609211 +1992,Wal,20,M,0.001408781404085466,0.0009342883836810962 +1992,Wal,20,F,0.00024399765762248682,0.001003344481605351 +1992,Wal,21,M,0.001539942252165544,0.00182648401826484 +1992,Wal,21,F,0.0004035716087373254,0.00033003300330033015 +1992,Wal,22,M,0.0016506456937566759,0.0009044317154054867 +1992,Wal,22,F,0.00040312421264802217,0.0003269042170644002 +1992,Wal,23,M,0.0015552879791290392,0.002907822041291073 +1992,Wal,23,F,0.0004625584622500897,0.0006414368184733802 +1992,Wal,24,M,0.0013370308012280881,0.0002927400468384075 +1992,Wal,24,F,0.000616617851086789,0.0 +1992,Wal,25,M,0.001277892460434484,0.0009847365829640572 +1992,Wal,25,F,0.0003030456083640588,0.0005875440658049354 +1992,Wal,26,M,0.0015240998285387698,0.0009610764055742432 +1992,Wal,26,F,0.00029286864841118765,0.0005908419497784343 +1992,Wal,27,M,0.0015224913494809689,0.001694915254237288 +1992,Wal,27,F,0.000186898420708345,0.0 +1992,Wal,28,M,0.001727518909328602,0.001448225923244026 +1992,Wal,28,F,0.0006511930787478487,0.0006251953735542358 +1992,Wal,29,M,0.001926132806857033,0.00146484375 +1992,Wal,29,F,0.0006166982922201137,0.00032362459546925567 +1992,Wal,30,M,0.002046702018792446,0.001006542526421741 +1992,Wal,30,F,0.0007743816334897281,0.0009643201542912248 +1992,Wal,31,M,0.0018260991712319148,0.00205761316872428 +1992,Wal,31,F,0.000743528974394721,0.0016118633139909741 +1992,Wal,32,M,0.0018406884174681328,0.0009678199854827002 +1992,Wal,32,F,0.001017699115044248,0.0 +1992,Wal,33,M,0.0015847121883010948,0.001678657074340528 +1992,Wal,33,F,0.0009947999095636444,0.0006691201070592171 +1992,Wal,34,M,0.0022049164946519053,0.000970873786407767 +1992,Wal,34,F,0.0009149130832570906,0.0 +1992,Wal,35,M,0.002055744131567625,0.001182872013248167 +1992,Wal,35,F,0.0009683666881859263,0.0006896551724137933 +1992,Wal,36,M,0.00211112177334229,0.0009970089730807576 +1992,Wal,36,F,0.001650846058605035,0.001050052502625131 +1992,Wal,37,M,0.002694250661534761,0.0017717033662363962 +1992,Wal,37,F,0.001385169452396343,0.001484230055658627 +1992,Wal,38,M,0.002480916030534351,0.0010825439783491214 +1992,Wal,38,F,0.0014902435616821132,0.0007945967421533573 +1992,Wal,39,M,0.00306044376434583,0.001395478649176668 +1992,Wal,39,F,0.0013170272812793981,0.0008103727714748784 +1992,Wal,40,M,0.0027141729174891428,0.0005989817310572028 +1992,Wal,40,F,0.001614434947768281,0.001266891891891892 +1992,Wal,41,M,0.003021433292418091,0.002289639381797367 +1992,Wal,41,F,0.001505882352941177,0.0016019223067681222 +1992,Wal,42,M,0.004207441024913724,0.001834301436869459 +1992,Wal,42,F,0.0017337519328991153,0.003036876355748373 +1992,Wal,43,M,0.003763539563062236,0.003391921060746223 +1992,Wal,43,F,0.002396888567293778,0.002092050209205021 +1992,Wal,44,M,0.004653284671532846,0.001564455569461827 +1992,Wal,44,F,0.002050674444039373,0.0018231540565177761 +1992,Wal,45,M,0.004637219541898918,0.003654485049833887 +1992,Wal,45,F,0.0028328611898017,0.0009770395701025893 +1992,Wal,46,M,0.004784086617147174,0.002919099249374479 +1992,Wal,46,F,0.0028101644245142,0.001155401502021953 +1992,Wal,47,M,0.005439539827435288,0.0037910699241786015 +1992,Wal,47,F,0.004010938924339107,0.001105583195135434 +1992,Wal,48,M,0.0066017604694585215,0.0056232427366448 +1992,Wal,48,F,0.002827400077110912,0.0006045949214026603 +1992,Wal,49,M,0.006002308580223163,0.004844961240310078 +1992,Wal,49,F,0.002575991756826378,0.00247066090179123 +1992,Wal,50,M,0.006422924901185771,0.004534005037783375 +1992,Wal,50,F,0.003328173374613003,0.001296176279974077 +1992,Wal,51,M,0.0064753495217071385,0.005934718100890208 +1992,Wal,51,F,0.0022157595900844764,0.0038503850385038507 +1992,Wal,52,M,0.008362557323981657,0.008298755186721992 +1992,Wal,52,F,0.003748360092459549,0.002212389380530974 +1992,Wal,53,M,0.008678945276268717,0.006866110838646395 +1992,Wal,53,F,0.00492640797956453,0.003869541182974019 +1992,Wal,54,M,0.009331582221607798,0.006776379477250726 +1992,Wal,54,F,0.0044110015568240785,0.0017857142857142859 +1992,Wal,55,M,0.01033701500991221,0.007936507936507936 +1992,Wal,55,F,0.005222437137330754,0.004079254079254079 +1992,Wal,56,M,0.01191996594295445,0.009438648782911079 +1992,Wal,56,F,0.006040354710191492,0.002888503755054882 +1992,Wal,57,M,0.01072151045178692,0.01439588688946016 +1992,Wal,57,F,0.005972906403940887,0.0051223676721684685 +1992,Wal,58,M,0.01321497697390376,0.014979338842975209 +1992,Wal,58,F,0.0065227993172396964,0.003409090909090909 +1992,Wal,59,M,0.01469753358985681,0.01060752169720347 +1992,Wal,59,F,0.005415666350287533,0.004643064422518862 +1992,Wal,60,M,0.01891252955082742,0.01502145922746781 +1992,Wal,60,F,0.006703427397556493,0.007046388725778039 +1992,Wal,61,M,0.01701762977473066,0.0230958230958231 +1992,Wal,61,F,0.0075437376277352735,0.008013737836290785 +1992,Wal,62,M,0.020724385047453036,0.017875383043922367 +1992,Wal,62,F,0.00790469828545981,0.011196228638774309 +1992,Wal,63,M,0.0216478614536867,0.02682186234817814 +1992,Wal,63,F,0.009688543434232855,0.0111731843575419 +1992,Wal,64,M,0.02586721496318896,0.02660642570281125 +1992,Wal,64,F,0.01146404205346158,0.008912655971479501 +1992,Wal,65,M,0.02626426304773479,0.02659307576517813 +1992,Wal,65,F,0.01099872879013983,0.01082381238725195 +1992,Wal,66,M,0.02958260164798055,0.03123317178244481 +1992,Wal,66,F,0.01201007988847783,0.014634146341463419 +1992,Wal,67,M,0.0320212542823184,0.03833515881708653 +1992,Wal,67,F,0.015054819178530519,0.01351351351351352 +1992,Wal,68,M,0.033433757072525536,0.03646723646723647 +1992,Wal,68,F,0.01597408400357462,0.01231190150478796 +1992,Wal,69,M,0.04055059523809524,0.03911342894393742 +1992,Wal,69,F,0.016290097629009768,0.01232777374909355 +1992,Wal,70,M,0.04118491649663719,0.04825538233110616 +1992,Wal,70,F,0.019737200806935282,0.02503793626707132 +1992,Wal,71,M,0.04464856230031949,0.05153782211138819 +1992,Wal,71,F,0.02120398343963299,0.018410041841004192 +1992,Wal,72,M,0.04823663253697383,0.0458970792767733 +1992,Wal,72,F,0.02523610466016412,0.02542372881355933 +1992,Wal,73,M,0.058232931726907626,0.05776173285198556 +1992,Wal,73,F,0.0248062015503876,0.03057553956834533 +1992,Wal,74,M,0.059263413722191065,0.05510204081632653 +1992,Wal,74,F,0.02933057280883368,0.0280561122244489 +1992,Wal,75,M,0.0650239561943874,0.0613107822410148 +1992,Wal,75,F,0.03316382931682512,0.04244482173174873 +1992,Wal,76,M,0.07038797730409446,0.0825147347740668 +1992,Wal,76,F,0.04264137041812489,0.04236006051437216 +1992,Wal,77,M,0.0807280811449215,0.08745247148288972 +1992,Wal,77,F,0.04053840063341251,0.04971590909090909 +1992,Wal,78,M,0.09252830188679248,0.09251968503937008 +1992,Wal,78,F,0.04748298176317338,0.057663125948406675 +1992,Wal,79,M,0.1008968609865471,0.1055045871559633 +1992,Wal,79,F,0.056318562667357686,0.07340946166394778 +1992,Wal,80,M,0.1150842581175504,0.1091954022988506 +1992,Wal,80,F,0.0649010477299185,0.06545454545454546 +1992,Wal,81,M,0.1204363312555655,0.1201550387596899 +1992,Wal,81,F,0.0709184186701539,0.04158004158004158 +1992,Wal,82,M,0.1218152866242038,0.150259067357513 +1992,Wal,82,F,0.07907742998352553,0.07775377969762419 +1992,Wal,83,M,0.1466420209488602,0.1633663366336634 +1992,Wal,83,F,0.08871062876017459,0.09701492537313433 +1992,Wal,84,M,0.1556031406138473,0.1904761904761905 +1992,Wal,84,F,0.09828788839568804,0.1294117647058824 +1992,Wal,85,M,0.1646160373355961,0.1503759398496241 +1992,Wal,85,F,0.1157973174366617,0.0896551724137931 +1992,Wal,86,M,0.1777541245343268,0.1153846153846154 +1992,Wal,86,F,0.1239579557810801,0.1310861423220974 +1992,Wal,87,M,0.1928571428571429,0.1585365853658537 +1992,Wal,87,F,0.1350863107185869,0.1551020408163265 +1992,Wal,88,M,0.1949790794979079,0.1666666666666667 +1992,Wal,88,F,0.1599803101156781,0.1428571428571429 +1992,Wal,89,M,0.2325830653804931,0.2857142857142857 +1992,Wal,89,F,0.1783154121863799,0.2075471698113208 +1992,Wal,90,M,0.2108843537414966,0.1142857142857143 +1992,Wal,90,F,0.1815671384190542,0.1870503597122302 +1992,Wal,91,M,0.2603550295857988,0.21875 +1992,Wal,91,F,0.2050428163653663,0.17 +1992,Wal,92,M,0.2732095490716181,0.25 +1992,Wal,92,F,0.2321792260692465,0.1636363636363636 +1992,Wal,93,M,0.3267716535433071,0.1578947368421053 +1992,Wal,93,F,0.2260711030082042,0.2307692307692308 +1992,Wal,94,M,0.2875,0.1818181818181818 +1992,Wal,94,F,0.2692793931731985,0.2790697674418605 +1992,Wal,95,M,0.2407407407407408,0.0 +1992,Wal,95,F,0.2719298245614035,0.2173913043478261 +1992,Wal,96,M,0.4339622641509434,0.0 +1992,Wal,96,F,0.3309178743961353,0.2727272727272727 +1992,Wal,97,M,0.3921568627450981,0.5 +1992,Wal,97,F,0.2741935483870968,0.1764705882352941 +1992,Wal,98,M,0.3,0.0 +1992,Wal,98,F,0.3088235294117647,0.0 +1992,Wal,99,M,0.4166666666666667,0.0 +1992,Wal,99,F,0.3163265306122449,0.375 +1992,Wal,100,M,0.1111111111111111,1.0 +1992,Wal,100,F,0.3695652173913043,0.6 +1992,Wal,101,M,0.25,0.0 +1992,Wal,101,F,0.4333333333333334,0.0 +1992,Wal,102,M,0.5,1.0 +1992,Wal,102,F,0.6428571428571429,0.0 +1992,Wal,103,M,0.0,0.0 +1992,Wal,103,F,0.4705882352941176,0.0 +1992,Wal,104,M,0.0,0.0 +1992,Wal,104,F,0.5,0.0 +1992,Wal,105,M,0.0,0.0 +1992,Wal,105,F,1.0,0.0 +1992,Wal,106,M,0.0,0.0 +1992,Wal,106,F,1.0,0.0 +1992,Wal,107,M,0.0,0.0 +1992,Wal,107,F,0.0,0.0 +1992,Wal,108,M,0.0,0.0 +1992,Wal,108,F,0.0,0.0 +1992,Wal,109,M,0.0,0.0 +1992,Wal,109,F,0.0,0.0 +1992,Wal,110,M,0.0,0.0 +1992,Wal,110,F,0.0,0.0 +1992,Wal,111,M,0.0,0.0 +1992,Wal,111,F,0.0,0.0 +1992,Wal,112,M,0.0,0.0 +1992,Wal,112,F,0.0,0.0 +1992,Wal,113,M,0.0,0.0 +1992,Wal,113,F,0.0,0.0 +1992,Wal,114,M,0.0,0.0 +1992,Wal,114,F,0.0,0.0 +1992,Wal,115,M,0.0,0.0 +1992,Wal,115,F,0.0,0.0 +1992,Wal,116,M,0.0,0.0 +1992,Wal,116,F,0.0,0.0 +1992,Wal,117,M,0.0,0.0 +1992,Wal,117,F,0.0,0.0 +1992,Wal,118,M,0.0,0.0 +1992,Wal,118,F,0.0,0.0 +1992,Wal,119,M,0.0,0.0 +1992,Wal,119,F,0.0,0.0 +1992,Wal,120,M,0.0,0.0 +1992,Wal,120,F,0.0,0.0 +1993,BruCap,0,M,0.0022634676324128572,0.001452784503631961 +1993,BruCap,0,F,0.001151012891344383,0.001009591115598183 +1993,BruCap,1,M,0.00047058823529411766,0.0 +1993,BruCap,1,F,0.0007383706620723603,0.0 +1993,BruCap,2,M,0.0,0.0009053870529651426 +1993,BruCap,2,F,0.0005125576627370579,0.0 +1993,BruCap,3,M,0.0,0.0004714757190004715 +1993,BruCap,3,F,0.0,0.0 +1993,BruCap,4,M,0.0,0.0 +1993,BruCap,4,F,0.0,0.0004793863854266539 +1993,BruCap,5,M,0.0,0.0 +1993,BruCap,5,F,0.0,0.0 +1993,BruCap,6,M,0.0,0.0 +1993,BruCap,6,F,0.0,0.0 +1993,BruCap,7,M,0.0006170934896636839,0.0 +1993,BruCap,7,F,0.0,0.0 +1993,BruCap,8,M,0.0003045066991473813,0.0 +1993,BruCap,8,F,0.00032123353678124,0.0 +1993,BruCap,9,M,0.0,0.0004748338081671415 +1993,BruCap,9,F,0.0006504065040650406,0.0 +1993,BruCap,10,M,0.0,0.00045495905368516835 +1993,BruCap,10,F,0.00033101621979477,0.0 +1993,BruCap,11,M,0.0,0.0004363001745200698 +1993,BruCap,11,F,0.0,0.0 +1993,BruCap,12,M,0.0003051571559353067,0.0 +1993,BruCap,12,F,0.00031515915537346363,0.0009203865623561896 +1993,BruCap,13,M,0.0009535918626827717,0.00043290043290043285 +1993,BruCap,13,F,0.0003377237419790612,0.0 +1993,BruCap,14,M,0.0003325573661456601,0.0009174311926605506 +1993,BruCap,14,F,0.0003288391976323578,0.0 +1993,BruCap,15,M,0.000333889816360601,0.0 +1993,BruCap,15,F,0.0,0.0004699248120300752 +1993,BruCap,16,M,0.0,0.00185356811862836 +1993,BruCap,16,F,0.0003418803418803419,0.0004796163069544365 +1993,BruCap,17,M,0.0,0.0004741583688952111 +1993,BruCap,17,F,0.0,0.0 +1993,BruCap,18,M,0.0012734797835084366,0.0004739336492890995 +1993,BruCap,18,F,0.0003152585119798235,0.0 +1993,BruCap,19,M,0.0020461853259280912,0.0009082652134423252 +1993,BruCap,19,F,0.0005614823133071309,0.0 +1993,BruCap,20,M,0.001092299290005461,0.002532714225411566 +1993,BruCap,20,F,0.0007886435331230284,0.0004291845493562232 +1993,BruCap,21,M,0.001250625312656328,0.003316749585406302 +1993,BruCap,21,F,0.0004894762604013706,0.0 +1993,BruCap,22,M,0.0009694619486185168,0.001865671641791045 +1993,BruCap,22,F,0.00022779043280182242,0.0008041817450743867 +1993,BruCap,23,M,0.001891700165523765,0.001081081081081081 +1993,BruCap,23,F,0.00022217285047767158,0.0 +1993,BruCap,24,M,0.001100352112676056,0.002076124567474049 +1993,BruCap,24,F,0.0,0.001112347052280311 +1993,BruCap,25,M,0.002082899395959175,0.0006903693476009665 +1993,BruCap,25,F,0.0003875968992248062,0.0003602305475504323 +1993,BruCap,26,M,0.002053388090349076,0.0018604651162790694 +1993,BruCap,26,F,0.0007747433662599264,0.0003263707571801567 +1993,BruCap,27,M,0.001554303477754032,0.00030021014710297214 +1993,BruCap,27,F,0.001137656427758817,0.0 +1993,BruCap,28,M,0.002102446483180428,0.0005884083553986466 +1993,BruCap,28,F,0.000567000567000567,0.00031486146095717883 +1993,BruCap,29,M,0.0007867820613690008,0.0012236157846436224 +1993,BruCap,29,F,0.0007840062720501764,0.001360081604896294 +1993,BruCap,30,M,0.002090301003344482,0.0009044317154054867 +1993,BruCap,30,F,0.0008174943797261393,0.001348163127738457 +1993,BruCap,31,M,0.003204443494979705,0.0009386733416770963 +1993,BruCap,31,F,0.0004024144869215292,0.0 +1993,BruCap,32,M,0.001501501501501502,0.001252348152786475 +1993,BruCap,32,F,0.000203334688897926,0.0003423485107839781 +1993,BruCap,33,M,0.002542372881355932,0.0017140898183064788 +1993,BruCap,33,F,0.0008392782207301718,0.0003675119441381845 +1993,BruCap,34,M,0.003345973678340397,0.0010312822275696108 +1993,BruCap,34,F,0.0006259127894846651,0.0003878975950349108 +1993,BruCap,35,M,0.002883762200532387,0.0014981273408239699 +1993,BruCap,35,F,0.000426075841499787,0.0004161464835622138 +1993,BruCap,36,M,0.0016374269005847964,0.002576370997423629 +1993,BruCap,36,F,0.0008616975441619991,0.001646090534979424 +1993,BruCap,37,M,0.003725261932479628,0.0007748934521503294 +1993,BruCap,37,F,0.00175054704595186,0.0004284490145672665 +1993,BruCap,38,M,0.002576715858514875,0.001658374792703151 +1993,BruCap,38,F,0.0013461969934933813,0.0009095043201455207 +1993,BruCap,39,M,0.003277920861624912,0.0021195421788893602 +1993,BruCap,39,F,0.003028991778450887,0.0009727626459143972 +1993,BruCap,40,M,0.00332541567695962,0.0016659725114535606 +1993,BruCap,40,F,0.0010921799912625599,0.00048076923076923085 +1993,BruCap,41,M,0.003381642512077295,0.0038350910834132313 +1993,BruCap,41,F,0.001104728236853734,0.001120448179271709 +1993,BruCap,42,M,0.002732919254658385,0.0018340210912425488 +1993,BruCap,42,F,0.002837189000436491,0.001540832049306626 +1993,BruCap,43,M,0.003902439024390244,0.001023017902813299 +1993,BruCap,43,F,0.002819956616052061,0.0012292562999385366 +1993,BruCap,44,M,0.006657156443176415,0.003048780487804878 +1993,BruCap,44,F,0.00214638334406525,0.002425712553062462 +1993,BruCap,45,M,0.003268736866682232,0.002631578947368421 +1993,BruCap,45,F,0.002860645688598284,0.00128122998078155 +1993,BruCap,46,M,0.00676132521974307,0.0017045454545454553 +1993,BruCap,46,F,0.003721314864585487,0.0006706908115358817 +1993,BruCap,47,M,0.006002728512960437,0.001271455816910363 +1993,BruCap,47,F,0.0033670033670033677,0.000731528895391368 +1993,BruCap,48,M,0.008452868852459017,0.0018726591760299628 +1993,BruCap,48,F,0.003145360593125141,0.0007293946024799418 +1993,BruCap,49,M,0.0039904229848363925,0.001346801346801347 +1993,BruCap,49,F,0.0033301617507136053,0.00078125 +1993,BruCap,50,M,0.0043600124571784495,0.003255208333333334 +1993,BruCap,50,F,0.0038377192982456147,0.0008149959250203749 +1993,BruCap,51,M,0.00877808988764045,0.0038109756097560975 +1993,BruCap,51,F,0.0074962518740629685,0.006167400881057269 +1993,BruCap,52,M,0.008995037220843672,0.00373134328358209 +1993,BruCap,52,F,0.0058091286307053935,0.001415428167020524 +1993,BruCap,53,M,0.007903981264636999,0.004884856943475228 +1993,BruCap,53,F,0.002972504334902155,0.004201680672268907 +1993,BruCap,54,M,0.01027296742001761,0.0034036759700476512 +1993,BruCap,54,F,0.005287009063444109,0.003593890386343217 +1993,BruCap,55,M,0.008262024195928003,0.005943536404160475 +1993,BruCap,55,F,0.006557377049180328,0.00546448087431694 +1993,BruCap,56,M,0.01018573996405033,0.006588579795021962 +1993,BruCap,56,F,0.0061146496815286605,0.004520795660036167 +1993,BruCap,57,M,0.01317759808325846,0.006557377049180328 +1993,BruCap,57,F,0.0049838026414154,0.0 +1993,BruCap,58,M,0.009639920612418484,0.01152263374485597 +1993,BruCap,58,F,0.006607929515418502,0.0081799591002045 +1993,BruCap,59,M,0.01333711691259932,0.01228070175438597 +1993,BruCap,59,F,0.005860290670417253,0.005714285714285714 +1993,BruCap,60,M,0.01707317073170732,0.012842465753424659 +1993,BruCap,60,F,0.007800312012480499,0.0067415730337078645 +1993,BruCap,61,M,0.01734721110221511,0.01857585139318886 +1993,BruCap,61,F,0.009253281687109965,0.006119951040391677 +1993,BruCap,62,M,0.01615074024226111,0.01138519924098672 +1993,BruCap,62,F,0.007818765036086608,0.005868544600938967 +1993,BruCap,63,M,0.02191400832177531,0.014084507042253518 +1993,BruCap,63,F,0.00907364422874024,0.005997001499250375 +1993,BruCap,64,M,0.0241640910368081,0.016393442622950817 +1993,BruCap,64,F,0.008758812219611195,0.00430416068866571 +1993,BruCap,65,M,0.02464183381088825,0.014765100671140941 +1993,BruCap,65,F,0.009503695881731784,0.005102040816326529 +1993,BruCap,66,M,0.02949438202247192,0.018154311649016642 +1993,BruCap,66,F,0.00935149420613946,0.006980802792321117 +1993,BruCap,67,M,0.029256060183895236,0.03054662379421222 +1993,BruCap,67,F,0.012367491166077741,0.01484230055658627 +1993,BruCap,68,M,0.03245708154506438,0.01659751037344398 +1993,BruCap,68,F,0.01615384615384616,0.010330578512396693 +1993,BruCap,69,M,0.03298265567244811,0.03238095238095238 +1993,BruCap,69,F,0.01290560471976401,0.01229508196721312 +1993,BruCap,70,M,0.03554301833568406,0.029885057471264367 +1993,BruCap,70,F,0.01691449814126394,0.011876484560570073 +1993,BruCap,71,M,0.03723691311386941,0.04038004750593825 +1993,BruCap,71,F,0.01818512456810329,0.02116402116402116 +1993,BruCap,72,M,0.04405162738496072,0.0425531914893617 +1993,BruCap,72,F,0.02038284296348813,0.01580135440180587 +1993,BruCap,73,M,0.05026861089792786,0.03636363636363636 +1993,BruCap,73,F,0.023970037453183518,0.02090592334494774 +1993,BruCap,74,M,0.06242350061199513,0.051020408163265314 +1993,BruCap,74,F,0.02858103564223269,0.02991452991452992 +1993,BruCap,75,M,0.04882688649334179,0.03260869565217391 +1993,BruCap,75,F,0.03341454925165333,0.01315789473684211 +1993,BruCap,76,M,0.07129909365558912,0.07692307692307693 +1993,BruCap,76,F,0.033192320208265534,0.03431372549019608 +1993,BruCap,77,M,0.07470376094796496,0.0641025641025641 +1993,BruCap,77,F,0.03788285867813004,0.02487562189054727 +1993,BruCap,78,M,0.07774178621008793,0.04848484848484848 +1993,BruCap,78,F,0.04490263459335625,0.0430622009569378 +1993,BruCap,79,M,0.08198380566801619,0.06206896551724138 +1993,BruCap,79,F,0.05314009661835749,0.0273972602739726 +1993,BruCap,80,M,0.09176340519624104,0.08943089430894309 +1993,BruCap,80,F,0.05665086099326179,0.06637168141592921 +1993,BruCap,81,M,0.1045251752708732,0.09565217391304348 +1993,BruCap,81,F,0.060463832136940926,0.027624309392265192 +1993,BruCap,82,M,0.1083991385498923,0.1165048543689321 +1993,BruCap,82,F,0.07260351673284175,0.08333333333333333 +1993,BruCap,83,M,0.1317957166392092,0.0958904109589041 +1993,BruCap,83,F,0.08284409654272668,0.07272727272727272 +1993,BruCap,84,M,0.1410748560460653,0.1058823529411765 +1993,BruCap,84,F,0.07360321177651387,0.07751937984496124 +1993,BruCap,85,M,0.1467268623024831,0.09333333333333334 +1993,BruCap,85,F,0.08740458015267176,0.09230769230769233 +1993,BruCap,86,M,0.1538461538461539,0.1272727272727273 +1993,BruCap,86,F,0.1150862068965517,0.09322033898305083 +1993,BruCap,87,M,0.160392798690671,0.2051282051282051 +1993,BruCap,87,F,0.1226369365002424,0.05172413793103448 +1993,BruCap,88,M,0.1636363636363636,0.06382978723404255 +1993,BruCap,88,F,0.1253713606654783,0.103448275862069 +1993,BruCap,89,M,0.1896551724137931,0.3333333333333333 +1993,BruCap,89,F,0.1492857142857143,0.07042253521126761 +1993,BruCap,90,M,0.2094594594594595,0.12 +1993,BruCap,90,F,0.1455437448896157,0.108695652173913 +1993,BruCap,91,M,0.18987341772151894,0.1666666666666667 +1993,BruCap,91,F,0.1878850102669405,0.07692307692307693 +1993,BruCap,92,M,0.2576687116564418,0.1428571428571429 +1993,BruCap,92,F,0.2291950886766712,0.2033898305084746 +1993,BruCap,93,M,0.3025210084033613,0.08333333333333333 +1993,BruCap,93,F,0.1829268292682927,0.2105263157894737 +1993,BruCap,94,M,0.3176470588235294,0.2222222222222222 +1993,BruCap,94,F,0.2275132275132275,0.15625 +1993,BruCap,95,M,0.3934426229508197,0.5 +1993,BruCap,95,F,0.2595419847328244,0.2105263157894737 +1993,BruCap,96,M,0.2954545454545455,0.0 +1993,BruCap,96,F,0.2459893048128343,0.1 +1993,BruCap,97,M,0.3333333333333333,0.3333333333333333 +1993,BruCap,97,F,0.2517482517482518,0.09090909090909093 +1993,BruCap,98,M,0.3333333333333333,0.0 +1993,BruCap,98,F,0.2358490566037736,0.1428571428571429 +1993,BruCap,99,M,0.3846153846153847,0.3333333333333333 +1993,BruCap,99,F,0.3207547169811321,0.25 +1993,BruCap,100,M,0.0,0.0 +1993,BruCap,100,F,0.3076923076923077,0.25 +1993,BruCap,101,M,0.5,0.0 +1993,BruCap,101,F,0.4,0.0 +1993,BruCap,102,M,0.0,1.0 +1993,BruCap,102,F,0.1818181818181818,0.5 +1993,BruCap,103,M,1.0,0.0 +1993,BruCap,103,F,0.3333333333333333,0.0 +1993,BruCap,104,M,0.0,0.0 +1993,BruCap,104,F,0.3333333333333333,0.0 +1993,BruCap,105,M,0.0,0.0 +1993,BruCap,105,F,0.5,0.0 +1993,BruCap,106,M,0.0,0.0 +1993,BruCap,106,F,0.5,0.0 +1993,BruCap,107,M,0.0,0.0 +1993,BruCap,107,F,0.0,0.0 +1993,BruCap,108,M,0.0,0.0 +1993,BruCap,108,F,0.0,0.0 +1993,BruCap,109,M,0.0,0.0 +1993,BruCap,109,F,0.0,0.0 +1993,BruCap,110,M,0.0,0.0 +1993,BruCap,110,F,0.0,0.0 +1993,BruCap,111,M,0.0,0.0 +1993,BruCap,111,F,0.0,0.0 +1993,BruCap,112,M,0.0,0.0 +1993,BruCap,112,F,0.0,0.0 +1993,BruCap,113,M,0.0,0.0 +1993,BruCap,113,F,0.0,0.0 +1993,BruCap,114,M,0.0,0.0 +1993,BruCap,114,F,0.0,0.0 +1993,BruCap,115,M,0.0,0.0 +1993,BruCap,115,F,0.0,0.0 +1993,BruCap,116,M,0.0,0.0 +1993,BruCap,116,F,0.0,0.0 +1993,BruCap,117,M,0.0,0.0 +1993,BruCap,117,F,0.0,0.0 +1993,BruCap,118,M,0.0,0.0 +1993,BruCap,118,F,0.0,0.0 +1993,BruCap,119,M,0.0,0.0 +1993,BruCap,119,F,0.0,0.0 +1993,BruCap,120,M,0.0,0.0 +1993,BruCap,120,F,0.0,0.0 +1993,Fla,0,M,0.001953818827708703,0.001973359644795264 +1993,Fla,0,F,0.001241272304111715,0.003465346534653466 +1993,Fla,1,M,0.0004954246080317072,0.00048685491723466414 +1993,Fla,1,F,0.00039893208948353637,0.0 +1993,Fla,2,M,0.0004115710253998119,0.00048638132295719856 +1993,Fla,2,F,0.00021669143140168402,0.0 +1993,Fla,3,M,0.0002730913945867217,0.0009881422924901183 +1993,Fla,3,F,0.0001593727090173079,0.0 +1993,Fla,4,M,0.0002767697890399164,0.0009510223490252023 +1993,Fla,4,F,6.439979392065946e-05,0.0 +1993,Fla,5,M,0.0002475170941493147,0.000485201358563804 +1993,Fla,5,F,0.0001965923984272608,0.0005025125628140704 +1993,Fla,6,M,9.25868773532498e-05,0.0 +1993,Fla,6,F,0.000293657008613939,0.0 +1993,Fla,7,M,0.0001587603988061218,0.0004943153732081066 +1993,Fla,7,F,0.0002986461375099549,0.0 +1993,Fla,8,M,0.0002172496198131653,0.0 +1993,Fla,8,F,9.762764814995605e-05,0.0 +1993,Fla,9,M,6.0088931618795825e-05,0.0005128205128205128 +1993,Fla,9,F,0.000156843062831331,0.0 +1993,Fla,10,M,0.0001170925909663066,0.000963855421686747 +1993,Fla,10,F,9.306365554038963e-05,0.0 +1993,Fla,11,M,0.0001695442086524061,0.0 +1993,Fla,11,F,0.0003326579369159585,0.0 +1993,Fla,12,M,0.0001714432665657057,0.0 +1993,Fla,12,F,0.00014900908955446285,0.0 +1993,Fla,13,M,0.0001129177958446251,0.00044543429844097997 +1993,Fla,13,F,0.00021051998436137255,0.0 +1993,Fla,14,M,0.00040394714063131165,0.00047846889952153117 +1993,Fla,14,F,0.0001809736381733728,0.0004828585224529213 +1993,Fla,15,M,0.00047003525264394845,0.0 +1993,Fla,15,F,0.0002443867420192455,0.00048590864917395527 +1993,Fla,16,M,0.0005964096141229798,0.0005073566717402334 +1993,Fla,16,F,0.0005029390500738691,0.0005107252298263534 +1993,Fla,17,M,0.0007007067999025104,0.0005274261603375527 +1993,Fla,17,F,0.0003217917363882096,0.0005246589716684155 +1993,Fla,18,M,0.0012848591035187619,0.001023541453428864 +1993,Fla,18,F,0.0004280429265906382,0.0 +1993,Fla,19,M,0.001511842768352092,0.0004725897920604915 +1993,Fla,19,F,0.0005004268346530863,0.0 +1993,Fla,20,M,0.001125944989544797,0.0004448398576512456 +1993,Fla,20,F,0.0004190061174893154,0.00046772684752104766 +1993,Fla,21,M,0.001469261502770976,0.0004137360364087712 +1993,Fla,21,F,0.0004503430554451772,0.0004374453193350832 +1993,Fla,22,M,0.001225919439579685,0.0008028904054596548 +1993,Fla,22,F,0.0004161356602252334,0.0 +1993,Fla,23,M,0.001149913756468265,0.0011025358324145528 +1993,Fla,23,F,0.00036463081130355516,0.0 +1993,Fla,24,M,0.0011399400292419401,0.0007267441860465116 +1993,Fla,24,F,0.0004380201489268507,0.0 +1993,Fla,25,M,0.001120675266458428,0.0017705382436260628 +1993,Fla,25,F,0.0004032766225582861,0.0004139072847682119 +1993,Fla,26,M,0.0011189072006340482,0.0009348706762231225 +1993,Fla,26,F,0.0004352241404323226,0.0007280669821623589 +1993,Fla,27,M,0.001078046041549691,0.0009047044632086852 +1993,Fla,27,F,0.00021141649048625792,0.0003880481179666279 +1993,Fla,28,M,0.001208902704919802,0.0008769365682548963 +1993,Fla,28,F,0.0003562522265764161,0.0007462686567164179 +1993,Fla,29,M,0.000995951241691385,0.0006201550387596902 +1993,Fla,29,F,0.0002464268112370626,0.0 +1993,Fla,30,M,0.001072914385811255,0.0008931229532598989 +1993,Fla,30,F,0.0004306534599605612,0.0 +1993,Fla,31,M,0.0008986695307191547,0.0006480881399870382 +1993,Fla,31,F,0.0005396168720208654,0.00044984255510571296 +1993,Fla,32,M,0.001167332644906389,0.002083953557606431 +1993,Fla,32,F,0.0005074268843989298,0.0012072434607645881 +1993,Fla,33,M,0.001272515851598324,0.001994017946161515 +1993,Fla,33,F,0.0005189296511890258,0.00135013501350135 +1993,Fla,34,M,0.001207945597709377,0.0009674298613350533 +1993,Fla,34,F,0.0006254777955382584,0.0 +1993,Fla,35,M,0.001556508008120912,0.0003460207612456748 +1993,Fla,35,F,0.0008657400907857175,0.0 +1993,Fla,36,M,0.0016039797294155938,0.001718803712616019 +1993,Fla,36,F,0.0008307816468465902,0.001966568338249754 +1993,Fla,37,M,0.001574322101602519,0.001067235859124867 +1993,Fla,37,F,0.0007653122234711693,0.0005213764337851929 +1993,Fla,38,M,0.001481056805694902,0.001126126126126126 +1993,Fla,38,F,0.001077718176696794,0.0 +1993,Fla,39,M,0.0018949516544385602,0.0025010421008753647 +1993,Fla,39,F,0.0011619389224279473,0.0005899705014749262 +1993,Fla,40,M,0.002330945732669661,0.002451982018798529 +1993,Fla,40,F,0.00131949554670253,0.0030618493570116357 +1993,Fla,41,M,0.002393014434459408,0.0012749681257968554 +1993,Fla,41,F,0.00115792520855812,0.003337783711615488 +1993,Fla,42,M,0.0020949720670391057,0.001974723538704581 +1993,Fla,42,F,0.001397200326892152,0.001905972045743329 +1993,Fla,43,M,0.0022516183506895576,0.0008100445524503848 +1993,Fla,43,F,0.001642688710489362,0.001271455816910363 +1993,Fla,44,M,0.0028430192352022128,0.003800675675675676 +1993,Fla,44,F,0.0014606917418749019,0.0006868131868131869 +1993,Fla,45,M,0.0030874520801708392,0.001360544217687075 +1993,Fla,45,F,0.00182110902900578,0.001360544217687075 +1993,Fla,46,M,0.003176667750569049,0.0028011204481792717 +1993,Fla,46,F,0.001817804092656072,0.0 +1993,Fla,47,M,0.004042332201106028,0.003198294243070363 +1993,Fla,47,F,0.002236174421604885,0.001638001638001638 +1993,Fla,48,M,0.004047666223216054,0.0027533039647577107 +1993,Fla,48,F,0.002278824242074596,0.003154574132492114 +1993,Fla,49,M,0.0041884199038433175,0.003333333333333334 +1993,Fla,49,F,0.00273552576203932,0.002606429192006951 +1993,Fla,50,M,0.004766734279918864,0.003480278422273782 +1993,Fla,50,F,0.002756814500844275,0.002570694087403599 +1993,Fla,51,M,0.005551596083874114,0.004227053140096618 +1993,Fla,51,F,0.003293289921784364,0.001923076923076923 +1993,Fla,52,M,0.006079130582441841,0.004449388209121246 +1993,Fla,52,F,0.003170855118907067,0.0 +1993,Fla,53,M,0.006198475175106924,0.0035502958579881646 +1993,Fla,53,F,0.0034249662009914377,0.0038131553860819827 +1993,Fla,54,M,0.006287048679719777,0.007421150278293135 +1993,Fla,54,F,0.0033233339215340287,0.0009242144177449168 +1993,Fla,55,M,0.007154311089182189,0.007962840079628402 +1993,Fla,55,F,0.0038040170419963476,0.004081632653061225 +1993,Fla,56,M,0.008733485772357724,0.007017543859649123 +1993,Fla,56,F,0.0038327203041449024,0.005530973451327434 +1993,Fla,57,M,0.009411465454198594,0.01104565537555228 +1993,Fla,57,F,0.00419766042161795,0.001132502831257078 +1993,Fla,58,M,0.009894082577535358,0.010486891385767793 +1993,Fla,58,F,0.00522737573651609,0.005452562704471101 +1993,Fla,59,M,0.01110342224458983,0.008487654320987654 +1993,Fla,59,F,0.00535698072092249,0.003472222222222222 +1993,Fla,60,M,0.01271982506390711,0.01567398119122257 +1993,Fla,60,F,0.005702706614560718,0.008760951188986229 +1993,Fla,61,M,0.01376118481950016,0.014272970561998218 +1993,Fla,61,F,0.006208848330830542,0.004457652303120357 +1993,Fla,62,M,0.01546359284454523,0.01466781708369284 +1993,Fla,62,F,0.006662032209477465,0.0077619663648124185 +1993,Fla,63,M,0.0168910897805515,0.02202202202202202 +1993,Fla,63,F,0.008157463770355035,0.00728862973760933 +1993,Fla,64,M,0.0194839205279514,0.01806588735387885 +1993,Fla,64,F,0.00870552611657835,0.001483679525222552 +1993,Fla,65,M,0.02160180075515539,0.024 +1993,Fla,65,F,0.01031971522811143,0.017973856209150332 +1993,Fla,66,M,0.02311688311688312,0.0208078335373317 +1993,Fla,66,F,0.012568533777934527,0.007692307692307694 +1993,Fla,67,M,0.02647551666356359,0.029776674937965264 +1993,Fla,67,F,0.01229641165401337,0.0113452188006483 +1993,Fla,68,M,0.03002666460563435,0.02313624678663239 +1993,Fla,68,F,0.013704058382590893,0.0195729537366548 +1993,Fla,69,M,0.029612483537534418,0.0328515111695138 +1993,Fla,69,F,0.014720542300790859,0.01349072512647555 +1993,Fla,70,M,0.03497437222724728,0.03125 +1993,Fla,70,F,0.01731632080762759,0.030592734225621417 +1993,Fla,71,M,0.041661108887999634,0.03333333333333334 +1993,Fla,71,F,0.018163185978303117,0.02404809619238477 +1993,Fla,72,M,0.045771375464684017,0.04710144927536232 +1993,Fla,72,F,0.02130194605913998,0.008547008547008548 +1993,Fla,73,M,0.04810331919141502,0.0351288056206089 +1993,Fla,73,F,0.026445966514459667,0.01592356687898089 +1993,Fla,74,M,0.05564727590560357,0.056716417910447764 +1993,Fla,74,F,0.027906334185259386,0.02054794520547945 +1993,Fla,75,M,0.06353305785123968,0.04792332268370607 +1993,Fla,75,F,0.030937279774489082,0.03937007874015748 +1993,Fla,76,M,0.0695321203119198,0.044609665427509285 +1993,Fla,76,F,0.03426315119093109,0.02621722846441948 +1993,Fla,77,M,0.07156201770774104,0.07169811320754718 +1993,Fla,77,F,0.04022801302931596,0.03383458646616541 +1993,Fla,78,M,0.08320516764072593,0.1010830324909747 +1993,Fla,78,F,0.04519254056672318,0.04779411764705882 +1993,Fla,79,M,0.09142713483616864,0.06666666666666668 +1993,Fla,79,F,0.05163778423319643,0.04471544715447155 +1993,Fla,80,M,0.09736551215917463,0.07317073170731707 +1993,Fla,80,F,0.05961251862891208,0.048979591836734684 +1993,Fla,81,M,0.1085558583106267,0.1129943502824859 +1993,Fla,81,F,0.06807372175980975,0.06403940886699508 +1993,Fla,82,M,0.1214285714285714,0.1176470588235294 +1993,Fla,82,F,0.079916476841306,0.08379888268156424 +1993,Fla,83,M,0.1324642556770396,0.09090909090909093 +1993,Fla,83,F,0.08684654300168634,0.04854368932038835 +1993,Fla,84,M,0.1444797060297311,0.1272727272727273 +1993,Fla,84,F,0.09712202900751768,0.1020408163265306 +1993,Fla,85,M,0.1561780506523408,0.2580645161290323 +1993,Fla,85,F,0.1091067538126362,0.08270676691729323 +1993,Fla,86,M,0.1690647482014389,0.1506849315068493 +1993,Fla,86,F,0.1267591475673502,0.1031746031746032 +1993,Fla,87,M,0.1875750300120048,0.140625 +1993,Fla,87,F,0.1349021435228332,0.1428571428571429 +1993,Fla,88,M,0.2002176278563656,0.16 +1993,Fla,88,F,0.1488833746898263,0.15 +1993,Fla,89,M,0.2144212523719165,0.2333333333333334 +1993,Fla,89,F,0.1645898234683282,0.1384615384615385 +1993,Fla,90,M,0.2571785268414482,0.2857142857142857 +1993,Fla,90,F,0.1874598758827306,0.2127659574468085 +1993,Fla,91,M,0.2469831053901851,0.2 +1993,Fla,91,F,0.2088471849865952,0.24 +1993,Fla,92,M,0.2785888077858881,0.2307692307692308 +1993,Fla,92,F,0.2330993719985224,0.3235294117647059 +1993,Fla,93,M,0.2622699386503068,0.2142857142857143 +1993,Fla,93,F,0.2553299492385787,0.2307692307692308 +1993,Fla,94,M,0.32340425531914896,0.2 +1993,Fla,94,F,0.2753726046841732,0.39130434782608703 +1993,Fla,95,M,0.3192771084337349,0.3076923076923077 +1993,Fla,95,F,0.2789256198347108,0.3125 +1993,Fla,96,M,0.3134328358208956,0.5 +1993,Fla,96,F,0.2838235294117647,0.1 +1993,Fla,97,M,0.3857142857142858,0.0 +1993,Fla,97,F,0.3235955056179775,0.4 +1993,Fla,98,M,0.2923076923076923,1.0 +1993,Fla,98,F,0.3673469387755102,0.0 +1993,Fla,99,M,0.4464285714285715,0.0 +1993,Fla,99,F,0.402439024390244,0.5 +1993,Fla,100,M,0.3928571428571429,0.0 +1993,Fla,100,F,0.3404255319148936,0.0 +1993,Fla,101,M,0.5,0.0 +1993,Fla,101,F,0.4901960784313725,0.0 +1993,Fla,102,M,0.4166666666666667,0.0 +1993,Fla,102,F,0.5,0.0 +1993,Fla,103,M,0.5,0.0 +1993,Fla,103,F,0.4166666666666667,1.0 +1993,Fla,104,M,0.0,0.0 +1993,Fla,104,F,0.6153846153846154,0.0 +1993,Fla,105,M,0.0,0.0 +1993,Fla,105,F,0.75,0.0 +1993,Fla,106,M,0.3333333333333333,0.0 +1993,Fla,106,F,1.0,0.0 +1993,Fla,107,M,0.0,0.0 +1993,Fla,107,F,1.0,0.0 +1993,Fla,108,M,0.0,0.0 +1993,Fla,108,F,0.0,0.0 +1993,Fla,109,M,0.0,0.0 +1993,Fla,109,F,0.0,0.0 +1993,Fla,110,M,0.0,0.0 +1993,Fla,110,F,1.0,0.0 +1993,Fla,111,M,0.0,0.0 +1993,Fla,111,F,0.0,0.0 +1993,Fla,112,M,0.0,0.0 +1993,Fla,112,F,0.0,0.0 +1993,Fla,113,M,0.0,0.0 +1993,Fla,113,F,0.0,0.0 +1993,Fla,114,M,0.0,0.0 +1993,Fla,114,F,0.0,0.0 +1993,Fla,115,M,0.0,0.0 +1993,Fla,115,F,0.0,0.0 +1993,Fla,116,M,0.0,0.0 +1993,Fla,116,F,0.0,0.0 +1993,Fla,117,M,0.0,0.0 +1993,Fla,117,F,0.0,0.0 +1993,Fla,118,M,0.0,0.0 +1993,Fla,118,F,0.0,0.0 +1993,Fla,119,M,0.0,0.0 +1993,Fla,119,F,0.0,0.0 +1993,Fla,120,M,0.0,0.0 +1993,Fla,120,F,0.0,0.0 +1993,Wal,0,M,0.002766182165669165,0.0022883295194508014 +1993,Wal,0,F,0.0016374392562856538,0.001552795031055901 +1993,Wal,1,M,0.000340931229300604,0.0 +1993,Wal,1,F,0.000304213354966283,0.000724112961622013 +1993,Wal,2,M,0.0006378489769883715,0.0 +1993,Wal,2,F,0.00030747155888080364,0.0 +1993,Wal,3,M,0.0001463486023708474,0.0 +1993,Wal,3,F,0.0001027274128101084,0.0 +1993,Wal,4,M,9.8159509202454e-05,0.0 +1993,Wal,4,F,0.0002591479216336685,0.0 +1993,Wal,5,M,0.0002045303471902644,0.0 +1993,Wal,5,F,0.0002141556911874933,0.0006451612903225806 +1993,Wal,6,M,0.0002548419979612641,0.0 +1993,Wal,6,F,0.0001075905105169724,0.0006377551020408162 +1993,Wal,7,M,0.000422698932685195,0.0 +1993,Wal,7,F,5.5632823365785815e-05,0.0 +1993,Wal,8,M,5.378368203087183e-05,0.0005830903790087462 +1993,Wal,8,F,5.588153115395363e-05,0.0 +1993,Wal,9,M,0.0001613684040664838,0.0 +1993,Wal,9,F,5.813615487471659e-05,0.0005966587112171838 +1993,Wal,10,M,0.0002670369579149755,0.0 +1993,Wal,10,F,5.581291510855612e-05,0.0 +1993,Wal,11,M,0.00021169621593014016,0.0005138746145940392 +1993,Wal,11,F,0.0001087961703748028,0.0 +1993,Wal,12,M,0.0001582528881152081,0.0014698677119059287 +1993,Wal,12,F,0.0001087311079699902,0.0005249343832020997 +1993,Wal,13,M,0.000321285140562249,0.0 +1993,Wal,13,F,0.0002833985149917815,0.0 +1993,Wal,14,M,0.0002723904990193942,0.0009049773755656108 +1993,Wal,14,F,0.000170174144874922,0.0 +1993,Wal,15,M,0.0006958942240779402,0.001382488479262673 +1993,Wal,15,F,0.000169606512890095,0.0 +1993,Wal,16,M,0.000531632110579479,0.0004444444444444445 +1993,Wal,16,F,0.0003865481252415926,0.00046382189239332097 +1993,Wal,17,M,0.0010519118497869884,0.0 +1993,Wal,17,F,0.0001641766540797899,0.0009161704076958314 +1993,Wal,18,M,0.001416645585631166,0.0007656967840735067 +1993,Wal,18,F,0.000266354144470488,0.0008343763037129745 +1993,Wal,19,M,0.001560823334308848,0.0006779661016949152 +1993,Wal,19,F,0.0004085175917887964,0.0 +1993,Wal,20,M,0.001429796968830426,0.0006377551020408162 +1993,Wal,20,F,0.00019846192011907719,0.0003497726477789437 +1993,Wal,21,M,0.001316841461694023,0.0021426385062748693 +1993,Wal,21,F,0.0009681948007939195,0.0 +1993,Wal,22,M,0.001737871107892832,0.00118378218407813 +1993,Wal,22,F,0.000352130388852558,0.0 +1993,Wal,23,M,0.001610620332861536,0.001463700234192038 +1993,Wal,23,F,0.0005550789725992834,0.0006635700066357001 +1993,Wal,24,M,0.00161640652624135,0.0011431837667905118 +1993,Wal,24,F,0.0004631297277826378,0.0 +1993,Wal,25,M,0.001593863625043582,0.001137656427758817 +1993,Wal,25,F,0.0004628201172477631,0.00033112582781456964 +1993,Wal,26,M,0.001478633742422002,0.001725412866650234 +1993,Wal,26,F,0.0007005604483586869,0.001505117399157134 +1993,Wal,27,M,0.0017659411989308898,0.0009394081728511037 +1993,Wal,27,F,0.0007254788160185723,0.0 +1993,Wal,28,M,0.001608751608751609,0.0014312977099236641 +1993,Wal,28,F,0.0009234036659125537,0.0 +1993,Wal,29,M,0.001672940192388122,0.0014426544842510221 +1993,Wal,29,F,0.0004607445632141541,0.0003126954346466542 +1993,Wal,30,M,0.001724716140468548,0.0016936849745947259 +1993,Wal,30,F,0.0005157055789967184,0.0003253090435914118 +1993,Wal,31,M,0.001668829964769145,0.000752823086574655 +1993,Wal,31,F,0.0004074241738343142,0.0009439899307740716 +1993,Wal,32,M,0.0020037278657968308,0.001814470401451577 +1993,Wal,32,F,0.0007831575067950428,0.0003188775510204082 +1993,Wal,33,M,0.001877891265515504,0.001202501202501203 +1993,Wal,33,F,0.0008808244516867787,0.0003301419610432486 +1993,Wal,34,M,0.001808905380333952,0.002155172413793104 +1993,Wal,34,F,0.0004949158643030683,0.0006688963210702341 +1993,Wal,35,M,0.0021013308428671487,0.0009823182711198428 +1993,Wal,35,F,0.001141396155777747,0.0003478260869565218 +1993,Wal,36,M,0.001954148991945093,0.001187366421277607 +1993,Wal,36,F,0.001056354200156157,0.0003421142661648991 +1993,Wal,37,M,0.002198642577191473,0.00125 +1993,Wal,37,F,0.0009141185611773847,0.00034904013961605586 +1993,Wal,38,M,0.002345619913834371,0.001021450459652707 +1993,Wal,38,F,0.0017469657962486214,0.0 +1993,Wal,39,M,0.002904623589352888,0.0019052803483941207 +1993,Wal,39,F,0.0013468951743997027,0.0007955449482895784 +1993,Wal,40,M,0.0027216731127345647,0.002527379949452401 +1993,Wal,40,F,0.002061759055339488,0.001210165389269867 +1993,Wal,41,M,0.003547671840354767,0.003273809523809524 +1993,Wal,41,F,0.00237034227742486,0.001688476150274378 +1993,Wal,42,M,0.0038182332421985475,0.002883506343713957 +1993,Wal,42,F,0.002207194514886823,0.0020024028834601517 +1993,Wal,43,M,0.004070235221733164,0.0018387986515476559 +1993,Wal,43,F,0.002012637491223965,0.0012942191544434859 +1993,Wal,44,M,0.0044109538687741225,0.002493765586034913 +1993,Wal,44,F,0.0021277558966001178,0.001263157894736842 +1993,Wal,45,M,0.005072430653932277,0.002839116719242903 +1993,Wal,45,F,0.0025506718287406057,0.001366742596810934 +1993,Wal,46,M,0.005302425977194876,0.004705882352941176 +1993,Wal,46,F,0.0025619910330313854,0.0009823182711198428 +1993,Wal,47,M,0.0052296641673492536,0.002114164904862579 +1993,Wal,47,F,0.00299043062200957,0.0005770340450086555 +1993,Wal,48,M,0.006961866532865028,0.003389830508474576 +1993,Wal,48,F,0.003107292999451654,0.001664816870144284 +1993,Wal,49,M,0.008169825219312931,0.004728132387706857 +1993,Wal,49,F,0.0033429765348762467,0.0018159806295399519 +1993,Wal,50,M,0.004937509643573522,0.0038535645472061657 +1993,Wal,50,F,0.0033860875966139122,0.001851851851851852 +1993,Wal,51,M,0.007272727272727274,0.006039255158530448 +1993,Wal,51,F,0.003870268596640607,0.002597402597402598 +1993,Wal,52,M,0.009747452370403193,0.005572224603514788 +1993,Wal,52,F,0.003737800235342978,0.00165929203539823 +1993,Wal,53,M,0.00725965126535043,0.009319664492078284 +1993,Wal,53,F,0.004319248826291079,0.003869541182974019 +1993,Wal,54,M,0.00926481370392588,0.007422068283028205 +1993,Wal,54,F,0.005854372484449323,0.002805836139169473 +1993,Wal,55,M,0.010920979410127991,0.00974184120798831 +1993,Wal,55,F,0.004615784683396178,0.004807692307692308 +1993,Wal,56,M,0.01033720681542739,0.007003501750875438 +1993,Wal,56,F,0.0053036672918957365,0.0017657445556209538 +1993,Wal,57,M,0.013769363166953529,0.009022556390977444 +1993,Wal,57,F,0.005547313423208411,0.0034944670937682013 +1993,Wal,58,M,0.0143410589274791,0.01767151767151767 +1993,Wal,58,F,0.006178178672927221,0.004 +1993,Wal,59,M,0.01564924114671164,0.008376963350785341 +1993,Wal,59,F,0.007284524975514201,0.004555808656036446 +1993,Wal,60,M,0.01727434982151963,0.01267056530214425 +1993,Wal,60,F,0.0076194744803630456,0.008787346221441127 +1993,Wal,61,M,0.01823895495717543,0.01790558871405318 +1993,Wal,61,F,0.007061763267966755,0.00297441998810232 +1993,Wal,62,M,0.01938972096202846,0.0176056338028169 +1993,Wal,62,F,0.008398384925975774,0.005737234652897304 +1993,Wal,63,M,0.022613726005784908,0.021886399166232414 +1993,Wal,63,F,0.01086043777640934,0.01009501187648456 +1993,Wal,64,M,0.02540446583767884,0.01460615545122588 +1993,Wal,64,F,0.010435070671378091,0.01125703564727955 +1993,Wal,65,M,0.029645746923233837,0.02933473022524883 +1993,Wal,65,F,0.011982139829311029,0.016206482593037218 +1993,Wal,66,M,0.031183018737468017,0.03227485684539303 +1993,Wal,66,F,0.012285012285012293,0.007255139056831924 +1993,Wal,67,M,0.03277095049642436,0.03135498320268757 +1993,Wal,67,F,0.01270220388665726,0.01486988847583643 +1993,Wal,68,M,0.03487868284228768,0.039338654503990884 +1993,Wal,68,F,0.01460742544126598,0.01956947162426614 +1993,Wal,69,M,0.0363705391040243,0.04026050917702783 +1993,Wal,69,F,0.01683768921140654,0.01868512110726644 +1993,Wal,70,M,0.04314819118444496,0.042090970807875085 +1993,Wal,70,F,0.02088403418416436,0.01321585903083701 +1993,Wal,71,M,0.04684301684774051,0.0453125 +1993,Wal,71,F,0.02113224335446558,0.018633540372670808 +1993,Wal,72,M,0.054250606035275435,0.04458041958041959 +1993,Wal,72,F,0.024632794193290286,0.02299829642248723 +1993,Wal,73,M,0.05871822413175797,0.05286343612334802 +1993,Wal,73,F,0.026889823114142945,0.02729528535980149 +1993,Wal,74,M,0.06422344778509162,0.0745697896749522 +1993,Wal,74,F,0.03235694822888284,0.02573529411764706 +1993,Wal,75,M,0.07157057654075548,0.0737527114967462 +1993,Wal,75,F,0.033862183282027,0.028571428571428567 +1993,Wal,76,M,0.07230235530399852,0.08968609865470853 +1993,Wal,76,F,0.03869421298938478,0.03539823008849558 +1993,Wal,77,M,0.08843425177363473,0.1010752688172043 +1993,Wal,77,F,0.04181084198385236,0.046948356807511735 +1993,Wal,78,M,0.09068923821039904,0.075 +1993,Wal,78,F,0.04748557295960429,0.04985337243401759 +1993,Wal,79,M,0.1,0.1144708423326134 +1993,Wal,79,F,0.05942947702060222,0.05591054313099041 +1993,Wal,80,M,0.1079164270653632,0.0810126582278481 +1993,Wal,80,F,0.06443652316972855,0.04679376083188908 +1993,Wal,81,M,0.1155184411969381,0.1301587301587302 +1993,Wal,81,F,0.06897624727725339,0.05513307984790874 +1993,Wal,82,M,0.1301925025329281,0.1565217391304348 +1993,Wal,82,F,0.08531317494600432,0.1094420600858369 +1993,Wal,83,M,0.1335347432024169,0.1071428571428571 +1993,Wal,83,F,0.09372772630078403,0.1055045871559633 +1993,Wal,84,M,0.1475881929445644,0.1369047619047619 +1993,Wal,84,F,0.1002968891183684,0.08042895442359249 +1993,Wal,85,M,0.1596958174904943,0.2148760330578513 +1993,Wal,85,F,0.1149199213262152,0.1158940397350994 +1993,Wal,86,M,0.1837974683544304,0.2123893805309735 +1993,Wal,86,F,0.1351033439758024,0.1402214022140221 +1993,Wal,87,M,0.1966473243068988,0.2365591397849463 +1993,Wal,87,F,0.1397649969078541,0.12393162393162402 +1993,Wal,88,M,0.2118780096308186,0.2 +1993,Wal,88,F,0.1665508454945564,0.1574074074074074 +1993,Wal,89,M,0.2155440414507772,0.25 +1993,Wal,89,F,0.1668124817731117,0.2164179104477612 +1993,Wal,90,M,0.2506963788300836,0.1944444444444445 +1993,Wal,90,F,0.1866859623733719,0.164179104477612 +1993,Wal,91,M,0.2642487046632125,0.25 +1993,Wal,91,F,0.21600000000000005,0.2017543859649123 +1993,Wal,92,M,0.2695417789757412,0.2916666666666667 +1993,Wal,92,F,0.2443653618030842,0.1279069767441861 +1993,Wal,93,M,0.3102189781021898,0.25 +1993,Wal,93,F,0.25,0.2340425531914894 +1993,Wal,94,M,0.2797619047619048,0.375 +1993,Wal,94,F,0.2684642438452521,0.3157894736842105 +1993,Wal,95,M,0.3859649122807018,0.25 +1993,Wal,95,F,0.3202054794520548,0.2121212121212121 +1993,Wal,96,M,0.2804878048780488,0.09090909090909093 +1993,Wal,96,F,0.2742718446601942,0.2941176470588236 +1993,Wal,97,M,0.4666666666666667,0.0 +1993,Wal,97,F,0.3104693140794224,0.5555555555555556 +1993,Wal,98,M,0.4193548387096775,0.0 +1993,Wal,98,F,0.3463687150837989,0.4166666666666667 +1993,Wal,99,M,0.4285714285714286,0.0 +1993,Wal,99,F,0.4148936170212766,0.5 +1993,Wal,100,M,0.5714285714285714,0.0 +1993,Wal,100,F,0.3030303030303031,0.0 +1993,Wal,101,M,0.875,0.0 +1993,Wal,101,F,0.4137931034482759,0.5 +1993,Wal,102,M,0.3333333333333333,0.0 +1993,Wal,102,F,0.3529411764705883,0.0 +1993,Wal,103,M,1.0,0.0 +1993,Wal,103,F,0.6666666666666666,0.0 +1993,Wal,104,M,0.0,0.0 +1993,Wal,104,F,0.375,0.0 +1993,Wal,105,M,0.0,0.0 +1993,Wal,105,F,1.0,0.0 +1993,Wal,106,M,0.0,0.0 +1993,Wal,106,F,0.0,0.0 +1993,Wal,107,M,0.0,0.0 +1993,Wal,107,F,0.0,0.0 +1993,Wal,108,M,0.0,0.0 +1993,Wal,108,F,0.0,0.0 +1993,Wal,109,M,0.0,0.0 +1993,Wal,109,F,0.0,0.0 +1993,Wal,110,M,0.0,0.0 +1993,Wal,110,F,0.0,0.0 +1993,Wal,111,M,0.0,0.0 +1993,Wal,111,F,0.0,0.0 +1993,Wal,112,M,0.0,0.0 +1993,Wal,112,F,0.0,0.0 +1993,Wal,113,M,0.0,0.0 +1993,Wal,113,F,0.0,0.0 +1993,Wal,114,M,0.0,0.0 +1993,Wal,114,F,0.0,0.0 +1993,Wal,115,M,0.0,0.0 +1993,Wal,115,F,0.0,0.0 +1993,Wal,116,M,0.0,0.0 +1993,Wal,116,F,0.0,0.0 +1993,Wal,117,M,0.0,0.0 +1993,Wal,117,F,0.0,0.0 +1993,Wal,118,M,0.0,0.0 +1993,Wal,118,F,0.0,0.0 +1993,Wal,119,M,0.0,0.0 +1993,Wal,119,F,0.0,0.0 +1993,Wal,120,M,0.0,0.0 +1993,Wal,120,F,0.0,0.0 +1994,BruCap,0,M,0.0018458698661744351,0.0004918839153959665 +1994,BruCap,0,F,0.00220967345936656,0.0005149330587023687 +1994,BruCap,1,M,0.001182872013248167,0.0009541984732824428 +1994,BruCap,1,F,0.0002413709872073377,0.000493339911198816 +1994,BruCap,2,M,0.0002447381302006853,0.0009789525208027412 +1994,BruCap,2,F,0.0005116398055768738,0.0004972650422675287 +1994,BruCap,3,M,0.00025562372188139056,0.0 +1994,BruCap,3,F,0.0,0.0 +1994,BruCap,4,M,0.0008161044613710555,0.00047846889952153117 +1994,BruCap,4,F,0.0,0.0 +1994,BruCap,5,M,0.0,0.0004692632566870014 +1994,BruCap,5,F,0.0002937720329024677,0.0004854368932038835 +1994,BruCap,6,M,0.0,0.000473260766682442 +1994,BruCap,6,F,0.0,0.0 +1994,BruCap,7,M,0.0005891016200294548,0.0 +1994,BruCap,7,F,0.0003144654088050315,0.0 +1994,BruCap,8,M,0.0,0.0 +1994,BruCap,8,F,0.0,0.0 +1994,BruCap,9,M,0.000302571860816944,0.0 +1994,BruCap,9,F,0.0003206155819172812,0.000991571641051066 +1994,BruCap,10,M,0.0003130870381966187,0.0004918839153959665 +1994,BruCap,10,F,0.0003208213025344884,0.0 +1994,BruCap,11,M,0.0003090234857849197,0.0 +1994,BruCap,11,F,0.0006449532408900352,0.0 +1994,BruCap,12,M,0.0005795421616922633,0.0 +1994,BruCap,12,F,0.0,0.0 +1994,BruCap,13,M,0.0,0.0 +1994,BruCap,13,F,0.0,0.0 +1994,BruCap,14,M,0.0,0.0004368719965050242 +1994,BruCap,14,F,0.0,0.0 +1994,BruCap,15,M,0.0003342245989304813,0.0009199632014719412 +1994,BruCap,15,F,0.0,0.0008968609865470852 +1994,BruCap,16,M,0.0,0.0004623208506703652 +1994,BruCap,16,F,0.0,0.0 +1994,BruCap,17,M,0.0006805035726437564,0.00091324200913242 +1994,BruCap,17,F,0.0006849315068493152,0.0 +1994,BruCap,18,M,0.001228878648233487,0.0005017561465127947 +1994,BruCap,18,F,0.0006209251785159888,0.0 +1994,BruCap,19,M,0.001515610791148833,0.0004894762604013706 +1994,BruCap,19,F,0.0008663008951775916,0.0005271481286241433 +1994,BruCap,20,M,0.0008298755186721991,0.0009144947416552351 +1994,BruCap,20,F,0.000523149359142035,0.00046468401486988845 +1994,BruCap,21,M,0.0023523261892315736,0.0004076640847941297 +1994,BruCap,21,F,0.00024636610002463656,0.0 +1994,BruCap,22,M,0.0014489253803429132,0.0 +1994,BruCap,22,F,0.001377410468319559,0.000784313725490196 +1994,BruCap,23,M,0.0018604651162790694,0.0003608805485384338 +1994,BruCap,23,F,0.0002135383301302584,0.0 +1994,BruCap,24,M,0.001114827201783724,0.0006781959986436081 +1994,BruCap,24,F,0.0008387502621094567,0.0 +1994,BruCap,25,M,0.001489995742869306,0.0009649404953361213 +1994,BruCap,25,F,0.0002022244691607685,0.0003516174402250352 +1994,BruCap,26,M,0.0006109979633401223,0.001960143743874551 +1994,BruCap,26,F,0.0005822981366459627,0.0 +1994,BruCap,27,M,0.001861812163839471,0.001469291801351749 +1994,BruCap,27,F,0.0005930025696778018,0.0003177629488401653 +1994,BruCap,28,M,0.000588350656991567,0.0002862049227246709 +1994,BruCap,28,F,0.0005844535359438924,0.0006207324643078832 +1994,BruCap,29,M,0.00197667523225934,0.0008386916410399776 +1994,BruCap,29,F,0.0005902026362384419,0.0 +1994,BruCap,30,M,0.00101276078590237,0.0008818342151675485 +1994,BruCap,30,F,0.0002010050251256282,0.001331114808652246 +1994,BruCap,31,M,0.001513513513513514,0.001175778953556732 +1994,BruCap,31,F,0.001059546514091969,0.0009897723523589574 +1994,BruCap,32,M,0.0017601760176017601,0.0015556938394523962 +1994,BruCap,32,F,0.001041232819658476,0.0 +1994,BruCap,33,M,0.001326846528084918,0.0006251953735542358 +1994,BruCap,33,F,0.001047339757017176,0.00034094783498124785 +1994,BruCap,34,M,0.0015344147303814118,0.0013656538067599868 +1994,BruCap,34,F,0.00042890842805061116,0.001112759643916914 +1994,BruCap,35,M,0.002739100661949327,0.002751977984176127 +1994,BruCap,35,F,0.0019210245464247602,0.0011750881316098714 +1994,BruCap,36,M,0.003410641200545703,0.002254791431792559 +1994,BruCap,36,F,0.00130718954248366,0.0 +1994,BruCap,37,M,0.002627179364700263,0.001490312965722802 +1994,BruCap,37,F,0.0021910604732690627,0.00041220115416323167 +1994,BruCap,38,M,0.00332541567695962,0.001566170712607674 +1994,BruCap,38,F,0.001989829759009507,0.001287001287001287 +1994,BruCap,39,M,0.005004766444232603,0.0004170141784820684 +1994,BruCap,39,F,0.0031731640979147783,0.0004570383912248629 +1994,BruCap,40,M,0.003087885985748219,0.001304347826086957 +1994,BruCap,40,F,0.002428792227864871,0.0014763779527559061 +1994,BruCap,41,M,0.005485332697352731,0.001283697047496791 +1994,BruCap,41,F,0.001107174490699734,0.00048732943469785567 +1994,BruCap,42,M,0.003651411879259981,0.0009601536245799329 +1994,BruCap,42,F,0.002240645305848084,0.001135073779795687 +1994,BruCap,43,M,0.00501127536958156,0.0032422417786012038 +1994,BruCap,43,F,0.001763668430335097,0.0005202913631633715 +1994,BruCap,44,M,0.004677498769079271,0.002084418968212611 +1994,BruCap,44,F,0.0021891418563922947,0.002430133657351154 +1994,BruCap,45,M,0.004322766570605189,0.0031168831168831173 +1994,BruCap,45,F,0.002167316861725184,0.0006153846153846152 +1994,BruCap,46,M,0.006616257088846882,0.002651113467656416 +1994,BruCap,46,F,0.002272727272727273,0.001925545571245187 +1994,BruCap,47,M,0.007334402933761174,0.002268859897901305 +1994,BruCap,47,F,0.0046092604232139105,0.0006693440428380187 +1994,BruCap,48,M,0.0038514442916093533,0.0037974683544303796 +1994,BruCap,48,F,0.003883495145631068,0.000725689404934688 +1994,BruCap,49,M,0.009372559229367352,0.00494132180358246 +1994,BruCap,49,F,0.005211874008610922,0.0007262164124909223 +1994,BruCap,50,M,0.005898123324396783,0.004657351962741184 +1994,BruCap,50,F,0.003365384615384616,0.003909304143862392 +1994,BruCap,51,M,0.01103752759381899,0.003898635477582847 +1994,BruCap,51,F,0.004718290313627533,0.00163265306122449 +1994,BruCap,52,M,0.009533898305084743,0.003103180760279286 +1994,BruCap,52,F,0.0045829514207149395,0.001773049645390071 +1994,BruCap,53,M,0.01074589127686473,0.003768844221105528 +1994,BruCap,53,F,0.004480537664519743,0.0035714285714285718 +1994,BruCap,54,M,0.008579881656804733,0.0076441973592772765 +1994,BruCap,54,F,0.0057803468208092465,0.002527379949452401 +1994,BruCap,55,M,0.01140456182472989,0.005521048999309869 +1994,BruCap,55,F,0.006141248720573183,0.004504504504504504 +1994,BruCap,56,M,0.012242460435951029,0.005983545250560957 +1994,BruCap,56,F,0.006428387760349704,0.0027624309392265192 +1994,BruCap,57,M,0.009491733006736069,0.0066469719350073855 +1994,BruCap,57,F,0.007503234152652005,0.001813236627379873 +1994,BruCap,58,M,0.01297497683039852,0.0057851239669421475 +1994,BruCap,58,F,0.006313131313131313,0.0036968576709796672 +1994,BruCap,59,M,0.01771710717397618,0.01079734219269103 +1994,BruCap,59,F,0.005483549351944167,0.004136504653567736 +1994,BruCap,60,M,0.01555620780745524,0.01361161524500908 +1994,BruCap,60,F,0.009557945041816007,0.005861664712778429 +1994,BruCap,61,M,0.01482102908277405,0.00970873786407767 +1994,BruCap,61,F,0.00839192560671354,0.0045977011494252856 +1994,BruCap,62,M,0.019305019305019308,0.006329113924050633 +1994,BruCap,62,F,0.008828073273008165,0.008816120906801008 +1994,BruCap,63,M,0.02249375173562899,0.01161665053242982 +1994,BruCap,63,F,0.007736156351791531,0.006009615384615385 +1994,BruCap,64,M,0.020594965675057208,0.017758046614872368 +1994,BruCap,64,F,0.008383490971625105,0.007621951219512195 +1994,BruCap,65,M,0.01967592592592593,0.01891551071878941 +1994,BruCap,65,F,0.013864818024263427,0.0058565153733528535 +1994,BruCap,66,M,0.02840236686390533,0.025714285714285717 +1994,BruCap,66,F,0.0119914346895075,0.005190311418685121 +1994,BruCap,67,M,0.030498533724340183,0.01748807631160572 +1994,BruCap,67,F,0.0121524201853759,0.012367491166077741 +1994,BruCap,68,M,0.029539530842745437,0.02245250431778929 +1994,BruCap,68,F,0.01200480192076831,0.007736943907156673 +1994,BruCap,69,M,0.02828339400728088,0.023809523809523808 +1994,BruCap,69,F,0.015294117647058831,0.008281573498964804 +1994,BruCap,70,M,0.03057287028791927,0.03258655804480652 +1994,BruCap,70,F,0.019559902200489,0.02370689655172414 +1994,BruCap,71,M,0.047239444936522,0.024154589371980683 +1994,BruCap,71,F,0.021470644119323583,0.007389162561576354 +1994,BruCap,72,M,0.04149026248941575,0.025445292620865145 +1994,BruCap,72,F,0.02133184937859395,0.030136986301369868 +1994,BruCap,73,M,0.04971885173128145,0.0424929178470255 +1994,BruCap,73,F,0.02677107994900747,0.013986013986013993 +1994,BruCap,74,M,0.04547300040600893,0.056338028169014086 +1994,BruCap,74,F,0.02366863905325444,0.01798561151079137 +1994,BruCap,75,M,0.05774278215223098,0.0449438202247191 +1994,BruCap,75,F,0.02624212736179146,0.02752293577981652 +1994,BruCap,76,M,0.0699394754539341,0.07058823529411765 +1994,BruCap,76,F,0.03548153511947864,0.05429864253393665 +1994,BruCap,77,M,0.08338804990151018,0.05303030303030303 +1994,BruCap,77,F,0.02915254237288136,0.02051282051282051 +1994,BruCap,78,M,0.07166853303471445,0.09027777777777778 +1994,BruCap,78,F,0.03894648360885402,0.015 +1994,BruCap,79,M,0.07540485829959515,0.07051282051282051 +1994,BruCap,79,F,0.04150579150579151,0.0202020202020202 +1994,BruCap,80,M,0.09030470914127424,0.06976744186046513 +1994,BruCap,80,F,0.05613945142271212,0.0660377358490566 +1994,BruCap,81,M,0.10825688073394503,0.1607142857142857 +1994,BruCap,81,F,0.0582756785524215,0.02427184466019418 +1994,BruCap,82,M,0.1205420827389444,0.0980392156862745 +1994,BruCap,82,F,0.06672571597283733,0.1169590643274854 +1994,BruCap,83,M,0.1237785016286645,0.04444444444444445 +1994,BruCap,83,F,0.06771799628942486,0.022598870056497185 +1994,BruCap,84,M,0.1385199240986717,0.1692307692307693 +1994,BruCap,84,F,0.08165467625899281,0.07051282051282051 +1994,BruCap,85,M,0.1316685584562997,0.1621621621621622 +1994,BruCap,85,F,0.09348546190651454,0.1101694915254237 +1994,BruCap,86,M,0.1373333333333333,0.1818181818181818 +1994,BruCap,86,F,0.100762066045724,0.08695652173913042 +1994,BruCap,87,M,0.1746794871794872,0.0851063829787234 +1994,BruCap,87,F,0.1210034431874078,0.1372549019607843 +1994,BruCap,88,M,0.1952191235059761,0.03448275862068966 +1994,BruCap,88,F,0.150363331470095,0.1376146788990826 +1994,BruCap,89,M,0.1915422885572139,0.1363636363636364 +1994,BruCap,89,F,0.1514736120630569,0.1948051948051948 +1994,BruCap,90,M,0.2118380062305296,0.2 +1994,BruCap,90,F,0.1672354948805461,0.161764705882353 +1994,BruCap,91,M,0.1861471861471862,0.3333333333333333 +1994,BruCap,91,F,0.1601941747572816,0.1025641025641026 +1994,BruCap,92,M,0.2901554404145078,0.2222222222222222 +1994,BruCap,92,F,0.2120822622107969,0.1111111111111111 +1994,BruCap,93,M,0.264957264957265,0.2941176470588236 +1994,BruCap,93,F,0.2182468694096601,0.2978723404255319 +1994,BruCap,94,M,0.25,0.3636363636363637 +1994,BruCap,94,F,0.23851203501094095,0.1428571428571429 +1994,BruCap,95,M,0.2631578947368421,0.1428571428571429 +1994,BruCap,95,F,0.2387543252595156,0.3214285714285715 +1994,BruCap,96,M,0.4444444444444444,0.0 +1994,BruCap,96,F,0.2797927461139897,0.1333333333333333 +1994,BruCap,97,M,0.2142857142857143,0.0 +1994,BruCap,97,F,0.2681159420289856,0.125 +1994,BruCap,98,M,0.2727272727272727,0.0 +1994,BruCap,98,F,0.2522522522522523,0.1111111111111111 +1994,BruCap,99,M,0.3333333333333333,0.0 +1994,BruCap,99,F,0.4,0.3333333333333333 +1994,BruCap,100,M,0.2857142857142857,0.0 +1994,BruCap,100,F,0.3235294117647059,0.5 +1994,BruCap,101,M,0.25,0.3333333333333333 +1994,BruCap,101,F,0.2692307692307692,0.5 +1994,BruCap,102,M,1.0,0.0 +1994,BruCap,102,F,0.3333333333333333,0.6666666666666666 +1994,BruCap,103,M,0.0,0.0 +1994,BruCap,103,F,0.4444444444444444,0.0 +1994,BruCap,104,M,0.0,0.0 +1994,BruCap,104,F,0.0,1.0 +1994,BruCap,105,M,0.0,0.0 +1994,BruCap,105,F,0.75,0.0 +1994,BruCap,106,M,0.0,0.0 +1994,BruCap,106,F,0.0,0.0 +1994,BruCap,107,M,0.0,0.0 +1994,BruCap,107,F,0.0,0.0 +1994,BruCap,108,M,0.0,0.0 +1994,BruCap,108,F,0.0,0.0 +1994,BruCap,109,M,0.0,0.0 +1994,BruCap,109,F,0.0,0.0 +1994,BruCap,110,M,0.0,0.0 +1994,BruCap,110,F,0.0,0.0 +1994,BruCap,111,M,0.0,0.0 +1994,BruCap,111,F,0.0,0.0 +1994,BruCap,112,M,0.0,0.0 +1994,BruCap,112,F,0.0,0.0 +1994,BruCap,113,M,0.0,0.0 +1994,BruCap,113,F,0.0,0.0 +1994,BruCap,114,M,0.0,0.0 +1994,BruCap,114,F,0.0,0.0 +1994,BruCap,115,M,0.0,0.0 +1994,BruCap,115,F,0.0,0.0 +1994,BruCap,116,M,0.0,0.0 +1994,BruCap,116,F,0.0,0.0 +1994,BruCap,117,M,0.0,0.0 +1994,BruCap,117,F,0.0,0.0 +1994,BruCap,118,M,0.0,0.0 +1994,BruCap,118,F,0.0,0.0 +1994,BruCap,119,M,0.0,0.0 +1994,BruCap,119,F,0.0,0.0 +1994,BruCap,120,M,0.0,0.0 +1994,BruCap,120,F,0.0,0.0 +1994,Fla,0,M,0.001813654667855277,0.001948368241597662 +1994,Fla,0,F,0.001366467522562604,0.001564945226917058 +1994,Fla,1,M,0.0006182471222068479,0.0009799118079372856 +1994,Fla,1,F,0.0004009746769069431,0.00048402710551790896 +1994,Fla,2,M,0.0003770739064856712,0.0 +1994,Fla,2,F,0.0003058758755696939,0.0 +1994,Fla,3,M,0.0002050741196461007,0.000475963826749167 +1994,Fla,3,F,6.165038069110076e-05,0.0 +1994,Fla,4,M,0.00027225701061802337,0.0 +1994,Fla,4,F,0.0002224906236094336,0.000500751126690035 +1994,Fla,5,M,0.0001226279162451332,0.0 +1994,Fla,5,F,0.0001283449913367131,0.000513347022587269 +1994,Fla,6,M,0.0003085657862256233,0.0 +1994,Fla,6,F,6.531252041016262e-05,0.0 +1994,Fla,7,M,0.0001538366869731093,0.0 +1994,Fla,7,F,0.0001953188580357434,0.0005479452054794519 +1994,Fla,8,M,6.327311841564113e-05,0.0 +1994,Fla,8,F,0.00019860973187686202,0.0 +1994,Fla,9,M,0.0001546072974644403,0.0004914004914004914 +1994,Fla,9,F,6.486556611422826e-05,0.0 +1994,Fla,10,M,0.00011974972307876541,0.0 +1994,Fla,10,F,0.000125203455615375,0.0 +1994,Fla,11,M,0.00014570887367040648,0.0004950495049504952 +1994,Fla,11,F,0.0001234987187007935,0.0 +1994,Fla,12,M,0.0001404454931041263,0.0 +1994,Fla,12,F,0.00015032168841320432,0.0 +1994,Fla,13,M,0.00031395382024716734,0.0 +1994,Fla,13,F,0.00029753049687592984,0.0 +1994,Fla,14,M,0.0002819124943617501,0.0008795074758135447 +1994,Fla,14,F,0.00024017532798943232,0.0 +1994,Fla,15,M,0.0005764020981036371,0.00046816479400749053 +1994,Fla,15,F,0.0003314251280506177,0.000951927653498334 +1994,Fla,16,M,0.0005577899773948271,0.000473709142586452 +1994,Fla,16,F,0.0002135383301302584,0.0 +1994,Fla,17,M,0.001012507444907683,0.0004950495049504952 +1994,Fla,17,F,0.0003455859252277725,0.0 +1994,Fla,18,M,0.001152877643275386,0.001056524035921817 +1994,Fla,18,F,0.0007037973063757638,0.001049868766404199 +1994,Fla,19,M,0.001137225170583776,0.0020212228398180892 +1994,Fla,19,F,0.0002128889024056446,0.0005050505050505049 +1994,Fla,20,M,0.001483430362740708,0.0013818516812528787 +1994,Fla,20,F,0.0003811981350614316,0.0 +1994,Fla,21,M,0.001234269768440259,0.0008726003490401396 +1994,Fla,21,F,0.00022302759966545856,0.0 +1994,Fla,22,M,0.001314432989690722,0.0012028869286287089 +1994,Fla,22,F,0.0002382780440020122,0.0 +1994,Fla,23,M,0.001001928712772086,0.001505457282649605 +1994,Fla,23,F,0.0004166883691858951,0.0007968127490039841 +1994,Fla,24,M,0.0015277499499098382,0.002788428023701638 +1994,Fla,24,F,0.0004700229789011908,0.0 +1994,Fla,25,M,0.0012409719292149608,0.001001001001001001 +1994,Fla,25,F,0.0003097093893563207,0.000774593338497289 +1994,Fla,26,M,0.0008617181702850851,0.0006680026720106881 +1994,Fla,26,F,0.00047889098928796464,0.0 +1994,Fla,27,M,0.001001910620252575,0.0005885815185403178 +1994,Fla,27,F,0.0004343000530811176,0.001050052502625131 +1994,Fla,28,M,0.0008990986535997662,0.0 +1994,Fla,28,F,0.0004223666611915433,0.0 +1994,Fla,29,M,0.001079284218706154,0.001714285714285714 +1994,Fla,29,F,0.00039998222301231067,0.0 +1994,Fla,30,M,0.0009515570934256057,0.0015183723048891589 +1994,Fla,30,F,0.0004479985664045876,0.0007636502481863308 +1994,Fla,31,M,0.0010282213957558519,0.001156737998843262 +1994,Fla,31,F,0.0005889815150416818,0.0008022462896109105 +1994,Fla,32,M,0.001315154969093858,0.0006263701847792045 +1994,Fla,32,F,0.0003817136698401293,0.0008499787505312367 +1994,Fla,33,M,0.001301352958334268,0.0002888503755054882 +1994,Fla,33,F,0.0005528297975260866,0.001171875 +1994,Fla,34,M,0.001623768459394817,0.001313628899835797 +1994,Fla,34,F,0.0007214519219930107,0.0 +1994,Fla,35,M,0.001340183158364977,0.001272264631043257 +1994,Fla,35,F,0.000787037037037037,0.0004508566275924256 +1994,Fla,36,M,0.0012639656923597788,0.0010166045408336161 +1994,Fla,36,F,0.0007721827031074504,0.0 +1994,Fla,37,M,0.001231956486367123,0.0006906077348066298 +1994,Fla,37,F,0.001020795745893078,0.0009560229445506693 +1994,Fla,38,M,0.0015043249341857839,0.001064207165661582 +1994,Fla,38,F,0.0008131636850664881,0.0005151983513652757 +1994,Fla,39,M,0.0017434084829957973,0.001871958068139274 +1994,Fla,39,F,0.001249785576004117,0.0005402485143165856 +1994,Fla,40,M,0.002042056642761639,0.002073828287017835 +1994,Fla,40,F,0.001212335513853459,0.0 +1994,Fla,41,M,0.002212765957446809,0.0008173273395995097 +1994,Fla,41,F,0.001294810602213872,0.0005998800239952009 +1994,Fla,42,M,0.002526670409882089,0.0033941450997030122 +1994,Fla,42,F,0.0012633241215949473,0.001310615989515072 +1994,Fla,43,M,0.002124132214278313,0.00315955766192733 +1994,Fla,43,F,0.0013190175956947269,0.003059975520195839 +1994,Fla,44,M,0.002845424250192259,0.001620745542949757 +1994,Fla,44,F,0.002042115313212752,0.004385964912280702 +1994,Fla,45,M,0.002978406552494416,0.001712328767123288 +1994,Fla,45,F,0.0015932300780943929,0.0026720106880427533 +1994,Fla,46,M,0.00273442538372243,0.0022624434389140282 +1994,Fla,46,F,0.0018758256274768828,0.001336898395721925 +1994,Fla,47,M,0.0037352719979944853,0.004145555043758637 +1994,Fla,47,F,0.0017420696827873119,0.0028985507246376808 +1994,Fla,48,M,0.0038915992216801572,0.004206098843322818 +1994,Fla,48,F,0.0030160280346986854,0.003194888178913738 +1994,Fla,49,M,0.004399409627611263,0.007038440714672442 +1994,Fla,49,F,0.002832206230853708,0.001533742331288344 +1994,Fla,50,M,0.005714285714285714,0.0027397260273972607 +1994,Fla,50,F,0.002651560805110281,0.0025295109612141647 +1994,Fla,51,M,0.0046142362760399,0.004025301897642324 +1994,Fla,51,F,0.003350951739385774,0.002504173622704508 +1994,Fla,52,M,0.006040471156750228,0.006567164179104477 +1994,Fla,52,F,0.0033754641263173692,0.006560449859418931 +1994,Fla,53,M,0.006353978068527312,0.003901895206243033 +1994,Fla,53,F,0.002841101264966516,0.003134796238244514 +1994,Fla,54,M,0.00804214332470933,0.004728132387706857 +1994,Fla,54,F,0.004127998071592142,0.001890359168241966 +1994,Fla,55,M,0.007014480537074389,0.0049291435613062215 +1994,Fla,55,F,0.004306911708309979,0.004616805170821791 +1994,Fla,56,M,0.007386028613102442,0.00728959575878065 +1994,Fla,56,F,0.0045812717610408645,0.0 +1994,Fla,57,M,0.008932001536688437,0.008403361344537815 +1994,Fla,57,F,0.004620441577772265,0.002173913043478261 +1994,Fla,58,M,0.01013307679974347,0.01322556943423953 +1994,Fla,58,F,0.005205589811917082,0.003378378378378379 +1994,Fla,59,M,0.01077917093142272,0.009643916913946587 +1994,Fla,59,F,0.005280087394549979,0.005336179295624333 +1994,Fla,60,M,0.01274796541200407,0.01684532924961715 +1994,Fla,60,F,0.005476951163852123,0.005681818181818182 +1994,Fla,61,M,0.01402830600411497,0.01484375 +1994,Fla,61,F,0.006639680829377675,0.00364963503649635 +1994,Fla,62,M,0.015076634344698159,0.018666666666666668 +1994,Fla,62,F,0.007462036526233269,0.01302460202604921 +1994,Fla,63,M,0.015405759580656509,0.02335640138408305 +1994,Fla,63,F,0.008076037202250794,0.007702182284980746 +1994,Fla,64,M,0.01852746342809826,0.01310483870967742 +1994,Fla,64,F,0.008933852140077822,0.0115606936416185 +1994,Fla,65,M,0.021396276122325468,0.0267379679144385 +1994,Fla,65,F,0.01011933174224344,0.005873715124816446 +1994,Fla,66,M,0.0204437518551499,0.02625570776255708 +1994,Fla,66,F,0.0117782909930716,0.008143322475570033 +1994,Fla,67,M,0.02432914563327894,0.02608695652173913 +1994,Fla,67,F,0.01155881684470275,0.003129890453834116 +1994,Fla,68,M,0.027234823853421568,0.04171934260429836 +1994,Fla,68,F,0.0135605463619648,0.009615384615384616 +1994,Fla,69,M,0.031776370803966066,0.0302233902759527 +1994,Fla,69,F,0.014898389634738359,0.01785714285714286 +1994,Fla,70,M,0.0366550236285186,0.04353741496598639 +1994,Fla,70,F,0.01732564802642667,0.02401372212692968 +1994,Fla,71,M,0.03960572677400651,0.03542673107890499 +1994,Fla,71,F,0.01947635014625098,0.017408123791102518 +1994,Fla,72,M,0.04313143493182451,0.041050903119868636 +1994,Fla,72,F,0.01962266868294088,0.01022494887525562 +1994,Fla,73,M,0.045512071651090336,0.04725897920604915 +1994,Fla,73,F,0.02315634218289086,0.029535864978902964 +1994,Fla,74,M,0.051593024780385466,0.04379562043795621 +1994,Fla,74,F,0.02875836140813437,0.03225806451612903 +1994,Fla,75,M,0.05728684562377868,0.06875000000000002 +1994,Fla,75,F,0.033105996021597035,0.02797202797202797 +1994,Fla,76,M,0.06014124917236813,0.06397306397306397 +1994,Fla,76,F,0.03417684700407213,0.03614457831325301 +1994,Fla,77,M,0.06685292356815006,0.05490196078431372 +1994,Fla,77,F,0.03906198537645742,0.03053435114503817 +1994,Fla,78,M,0.07421669875722038,0.05737704918032788 +1994,Fla,78,F,0.04152288284211122,0.01976284584980237 +1994,Fla,79,M,0.08346615216844225,0.06854838709677419 +1994,Fla,79,F,0.04835354406616266,0.05019305019305019 +1994,Fla,80,M,0.0962655601659751,0.1105769230769231 +1994,Fla,80,F,0.05671247357293869,0.029411764705882363 +1994,Fla,81,M,0.1032686414708887,0.126984126984127 +1994,Fla,81,F,0.06349745331069609,0.0815450643776824 +1994,Fla,82,M,0.1149467499081895,0.08227848101265822 +1994,Fla,82,F,0.07109579424341056,0.07407407407407407 +1994,Fla,83,M,0.1197464517018052,0.09523809523809523 +1994,Fla,83,F,0.08166632295318622,0.04878048780487805 +1994,Fla,84,M,0.1336681788723266,0.1794871794871795 +1994,Fla,84,F,0.09406512200754368,0.06965174129353234 +1994,Fla,85,M,0.1480250293312476,0.1276595744680851 +1994,Fla,85,F,0.1067977480883959,0.09923664122137403 +1994,Fla,86,M,0.1621191450659391,0.2318840579710145 +1994,Fla,86,F,0.1147076080578917,0.075 +1994,Fla,87,M,0.1658465991316932,0.1451612903225807 +1994,Fla,87,F,0.1285450772423334,0.1891891891891892 +1994,Fla,88,M,0.1930729550478998,0.2037037037037037 +1994,Fla,88,F,0.138739224137931,0.1486486486486487 +1994,Fla,89,M,0.2088808337109198,0.2325581395348837 +1994,Fla,89,F,0.149846104001296,0.14 +1994,Fla,90,M,0.21458710066305,0.3181818181818182 +1994,Fla,90,F,0.1797799460244966,0.2586206896551725 +1994,Fla,91,M,0.2409435551811289,0.2 +1994,Fla,91,F,0.1942105263157895,0.1025641025641026 +1994,Fla,92,M,0.2685284640171859,0.1666666666666667 +1994,Fla,92,F,0.2034705682204832,0.1891891891891892 +1994,Fla,93,M,0.2801358234295416,0.1 +1994,Fla,93,F,0.2337035248672139,0.2083333333333334 +1994,Fla,94,M,0.2719665271966527,0.09090909090909093 +1994,Fla,94,F,0.2559402579769179,0.25 +1994,Fla,95,M,0.3322784810126582,0.5 +1994,Fla,95,F,0.2855740922473013,0.2307692307692308 +1994,Fla,96,M,0.3466666666666667,0.2222222222222222 +1994,Fla,96,F,0.2752161383285303,0.2727272727272727 +1994,Fla,97,M,0.3840579710144928,0.0 +1994,Fla,97,F,0.3065843621399177,0.1111111111111111 +1994,Fla,98,M,0.4880952380952381,0.0 +1994,Fla,98,F,0.2857142857142857,0.3333333333333333 +1994,Fla,99,M,0.4130434782608696,0.0 +1994,Fla,99,F,0.3945945945945946,0.2 +1994,Fla,100,M,0.2903225806451613,0.0 +1994,Fla,100,F,0.3229166666666667,1.0 +1994,Fla,101,M,0.5294117647058824,1.0 +1994,Fla,101,F,0.4032258064516129,0.0 +1994,Fla,102,M,0.0,0.0 +1994,Fla,102,F,0.5,0.5 +1994,Fla,103,M,0.6666666666666666,0.0 +1994,Fla,103,F,0.7857142857142857,0.0 +1994,Fla,104,M,1.0,0.0 +1994,Fla,104,F,0.5714285714285714,0.0 +1994,Fla,105,M,1.0,0.0 +1994,Fla,105,F,0.4,0.0 +1994,Fla,106,M,0.0,0.0 +1994,Fla,106,F,0.0,0.0 +1994,Fla,107,M,1.0,0.0 +1994,Fla,107,F,0.0,0.0 +1994,Fla,108,M,0.0,0.0 +1994,Fla,108,F,0.0,0.0 +1994,Fla,109,M,0.0,0.0 +1994,Fla,109,F,0.0,0.0 +1994,Fla,110,M,0.0,0.0 +1994,Fla,110,F,0.0,0.0 +1994,Fla,111,M,0.0,0.0 +1994,Fla,111,F,0.0,0.0 +1994,Fla,112,M,0.0,0.0 +1994,Fla,112,F,0.0,0.0 +1994,Fla,113,M,0.0,0.0 +1994,Fla,113,F,0.0,0.0 +1994,Fla,114,M,0.0,0.0 +1994,Fla,114,F,0.0,0.0 +1994,Fla,115,M,0.0,0.0 +1994,Fla,115,F,0.0,0.0 +1994,Fla,116,M,0.0,0.0 +1994,Fla,116,F,0.0,0.0 +1994,Fla,117,M,0.0,0.0 +1994,Fla,117,F,0.0,0.0 +1994,Fla,118,M,0.0,0.0 +1994,Fla,118,F,0.0,0.0 +1994,Fla,119,M,0.0,0.0 +1994,Fla,119,F,0.0,0.0 +1994,Fla,120,M,0.0,0.0 +1994,Fla,120,F,0.0,0.0 +1994,Wal,0,M,0.002205419029615627,0.0015873015873015884 +1994,Wal,0,F,0.001339509962605347,0.0 +1994,Wal,1,M,0.0004975124378109452,0.0007288629737609329 +1994,Wal,1,F,0.00026085141903171947,0.0 +1994,Wal,2,M,9.645992090286486e-05,0.0 +1994,Wal,2,F,0.0001504513540621866,0.0007107320540156361 +1994,Wal,3,M,9.733781087263349e-05,0.0 +1994,Wal,3,F,5.077946478444118e-05,0.0 +1994,Wal,4,M,0.0001939017887440012,0.0 +1994,Wal,4,F,0.0,0.0 +1994,Wal,5,M,0.0001951695535496463,0.0 +1994,Wal,5,F,5.1442975461700706e-05,0.0012698412698412696 +1994,Wal,6,M,0.0001522997258604935,0.0 +1994,Wal,6,F,0.0001595405232929164,0.0 +1994,Wal,7,M,0.0002028294711221541,0.0 +1994,Wal,7,F,0.000106928999144568,0.0 +1994,Wal,8,M,0.0002106149957877001,0.0 +1994,Wal,8,F,5.526999392030067e-05,0.0 +1994,Wal,9,M,0.00032123353678124,0.0 +1994,Wal,9,F,5.560807429238726e-05,0.0006027727546714887 +1994,Wal,10,M,0.0002679241238881149,0.0 +1994,Wal,10,F,0.000115720650350055,0.0006153846153846152 +1994,Wal,11,M,0.0001592779400053093,0.0 +1994,Wal,11,F,0.00022187708009762592,0.0 +1994,Wal,12,M,0.0001050972149238045,0.0 +1994,Wal,12,F,0.0002701096645237967,0.0 +1994,Wal,13,M,0.0007357964997109371,0.0004970178926441351 +1994,Wal,13,F,0.0001083423618634886,0.0 +1994,Wal,14,M,0.0001600768368817032,0.0009505703422053232 +1994,Wal,14,F,0.0003958380456910201,0.0 +1994,Wal,15,M,0.0005983463881636205,0.0018091361374943469 +1994,Wal,15,F,0.0001697408622835804,0.000499001996007984 +1994,Wal,16,M,0.0005341309689135777,0.0009263547938860583 +1994,Wal,16,F,0.0005638249887235003,0.0 +1994,Wal,17,M,0.0007958404074702888,0.0008745080891998251 +1994,Wal,17,F,0.00044116025146134335,0.0 +1994,Wal,18,M,0.0014144271570014153,0.001313485113835377 +1994,Wal,18,F,0.0003257328990228013,0.0 +1994,Wal,19,M,0.002318431530668817,0.001163692785104733 +1994,Wal,19,F,0.0006362672322375398,0.0004215851602023609 +1994,Wal,20,M,0.001951124335398273,0.0016767270288397052 +1994,Wal,20,F,0.0002545436033192486,0.0 +1994,Wal,21,M,0.0017630801486705422,0.00125984251968504 +1994,Wal,21,F,0.0005446353418824578,0.000353857041755131 +1994,Wal,22,M,0.002070880594907516,0.0006134969325153375 +1994,Wal,22,F,0.0005318634561454406,0.0003418803418803419 +1994,Wal,23,M,0.002033012246478532,0.001163128816516429 +1994,Wal,23,F,0.0005544075399425432,0.0 +1994,Wal,24,M,0.001477541371158393,0.000572737686139748 +1994,Wal,24,F,0.0003540897364560676,0.00033112582781456964 +1994,Wal,25,M,0.001630407092270851,0.001115137998327293 +1994,Wal,25,F,0.0006187480664122925,0.0 +1994,Wal,26,M,0.001898860683589846,0.0005599104143337066 +1994,Wal,26,F,0.0005644788833581362,0.0 +1994,Wal,27,M,0.001434720229555237,0.001216249087813184 +1994,Wal,27,F,0.0005475906013540422,0.00030075187969924816 +1994,Wal,28,M,0.001958817065596484,0.001163873370577281 +1994,Wal,28,F,0.0010063737001006366,0.0006016847172081829 +1994,Wal,29,M,0.00160234400036625,0.001419782300047326 +1994,Wal,29,F,0.0005958656093871753,0.000900900900900901 +1994,Wal,30,M,0.001623075496197366,0.001918005274514505 +1994,Wal,30,F,0.0007313617040727705,0.0 +1994,Wal,31,M,0.001863888357866565,0.001196458482890644 +1994,Wal,31,F,0.0006056088698406782,0.00064 +1994,Wal,32,M,0.001568193349015267,0.000998003992015968 +1994,Wal,32,F,0.0007648355603545237,0.0003121098626716605 +1994,Wal,33,M,0.001855459690138232,0.001352874859075536 +1994,Wal,33,F,0.0009622874948448883,0.0 +1994,Wal,34,M,0.00159511439248929,0.001207729468599034 +1994,Wal,34,F,0.000922266139657444,0.00032905561039815734 +1994,Wal,35,M,0.002594033722438392,0.0009673518742442565 +1994,Wal,35,F,0.0009856630824372759,0.0006680026720106881 +1994,Wal,36,M,0.00241635687732342,0.0009832841691248774 +1994,Wal,36,F,0.0009545020680878142,0.0003495281370150297 +1994,Wal,37,M,0.002138681621595932,0.00214848412508952 +1994,Wal,37,F,0.0011438506588579802,0.0003423485107839781 +1994,Wal,38,M,0.003150959610426812,0.001758352172820899 +1994,Wal,38,F,0.0015971525052477867,0.0003496503496503497 +1994,Wal,39,M,0.002965513942698618,0.002857142857142857 +1994,Wal,39,F,0.001241094001378994,0.0007326007326007326 +1994,Wal,40,M,0.0031392694063926943,0.0035509423654739147 +1994,Wal,40,F,0.001667438628994905,0.0011885895404120446 +1994,Wal,41,M,0.002869303237530487,0.00169635284139101 +1994,Wal,41,F,0.002154768596589845,0.0004033884630899556 +1994,Wal,42,M,0.003494954467142506,0.0017974835230677051 +1994,Wal,42,F,0.001992220851911583,0.001684919966301601 +1994,Wal,43,M,0.004395292783212817,0.0034682080924855487 +1994,Wal,43,F,0.002300361485376274,0.0024213075060532693 +1994,Wal,44,M,0.004175167243915168,0.0030703101013202327 +1994,Wal,44,F,0.002433090024330901,0.0008703220191470844 +1994,Wal,45,M,0.00479373127448721,0.002507051081165779 +1994,Wal,45,F,0.002173814591730447,0.0012626262626262634 +1994,Wal,46,M,0.0051307893169636725,0.0038167938931297713 +1994,Wal,46,F,0.002098635886673662,0.001376146788990826 +1994,Wal,47,M,0.005229189240118717,0.003371544167228591 +1994,Wal,47,F,0.0031139808581764896,0.002946954813359529 +1994,Wal,48,M,0.005310070168784373,0.006388415672913117 +1994,Wal,48,F,0.0026347305389221557,0.0028901734104046237 +1994,Wal,49,M,0.006052200226957508,0.002992731936725096 +1994,Wal,49,F,0.00341796875,0.002787068004459309 +1994,Wal,50,M,0.007751937984496123,0.005253104106972301 +1994,Wal,50,F,0.004188414201946002,0.0006090133982947625 +1994,Wal,51,M,0.00828173374613003,0.006326034063260341 +1994,Wal,51,F,0.004056645522938486,0.0030807147258163892 +1994,Wal,52,M,0.007562536358347875,0.0050994390617032145 +1994,Wal,52,F,0.004497169884469256,0.001976284584980237 +1994,Wal,53,M,0.00900096704604627,0.0078091106290672455 +1994,Wal,53,F,0.004443827246215803,0.0022234574763757642 +1994,Wal,54,M,0.008461853418861744,0.0047169811320754715 +1994,Wal,54,F,0.003827330907265655,0.004986149584487534 +1994,Wal,55,M,0.01026845637583893,0.009040683073832243 +1994,Wal,55,F,0.005082981199093637,0.003357582540570789 +1994,Wal,56,M,0.01004284008708477,0.009364218827008379 +1994,Wal,56,F,0.004756629960252818,0.005447941888619854 +1994,Wal,57,M,0.0138659386450176,0.00904977375565611 +1994,Wal,57,F,0.006097560975609756,0.0035502958579881646 +1994,Wal,58,M,0.014515894904920891,0.007135575942915392 +1994,Wal,58,F,0.00595392182241781,0.004091174751607247 +1994,Wal,59,M,0.01541107671138631,0.01118806606286628 +1994,Wal,59,F,0.007074154514427552,0.002891844997108155 +1994,Wal,60,M,0.0170058735145472,0.01164637374272102 +1994,Wal,60,F,0.007185849404250092,0.008561643835616438 +1994,Wal,61,M,0.01690414507772021,0.01587301587301587 +1994,Wal,61,F,0.007833633904418396,0.005945303210463734 +1994,Wal,62,M,0.01939803516676053,0.01896263245956498 +1994,Wal,62,F,0.007757019556429586,0.01024713682941531 +1994,Wal,63,M,0.020746363061353586,0.01637666325486182 +1994,Wal,63,F,0.008735282947208508,0.005787037037037037 +1994,Wal,64,M,0.02362099047107771,0.02469135802469136 +1994,Wal,64,F,0.01102941176470588,0.007826610475617099 +1994,Wal,65,M,0.02805212620027435,0.028153762858689767 +1994,Wal,65,F,0.01120526257107816,0.01150159744408946 +1994,Wal,66,M,0.030538628563423688,0.02783842794759825 +1994,Wal,66,F,0.01149293841843445,0.01099572388515577 +1994,Wal,67,M,0.03309321731688182,0.0276273022751896 +1994,Wal,67,F,0.01327833653520172,0.01031553398058252 +1994,Wal,68,M,0.03371592539454806,0.03993055555555555 +1994,Wal,68,F,0.01484168865435356,0.01319924575738529 +1994,Wal,69,M,0.03378176382660688,0.04092526690391459 +1994,Wal,69,F,0.01728686086322052,0.018000000000000002 +1994,Wal,70,M,0.04325900244267592,0.04576376004947433 +1994,Wal,70,F,0.01837557603686636,0.01905434015525759 +1994,Wal,71,M,0.04477732793522267,0.04724409448818898 +1994,Wal,71,F,0.02086825828082548,0.021465581051073282 +1994,Wal,72,M,0.04944692091794618,0.05336617405582923 +1994,Wal,72,F,0.02367300596082884,0.02063492063492064 +1994,Wal,73,M,0.05157643733992758,0.05514705882352941 +1994,Wal,73,F,0.02476725803618479,0.03356282271944923 +1994,Wal,74,M,0.0597695327339496,0.08087091757387248 +1994,Wal,74,F,0.02892999755521148,0.030848329048843187 +1994,Wal,75,M,0.06828989918204299,0.05555555555555555 +1994,Wal,75,F,0.03312653634554606,0.03578154425612053 +1994,Wal,76,M,0.0696432386242256,0.07962529274004684 +1994,Wal,76,F,0.03966213734851267,0.014705882352941181 +1994,Wal,77,M,0.07705917043444073,0.1014851485148515 +1994,Wal,77,F,0.03620607787274454,0.03710575139146568 +1994,Wal,78,M,0.08602927887222121,0.08747044917257682 +1994,Wal,78,F,0.04486600421559772,0.05519480519480519 +1994,Wal,79,M,0.08849410592727877,0.078125 +1994,Wal,79,F,0.04887543252595156,0.05384615384615385 +1994,Wal,80,M,0.1033653846153846,0.1012048192771084 +1994,Wal,80,F,0.058207979071288427,0.05980066445182725 +1994,Wal,81,M,0.114168995914857,0.09065934065934066 +1994,Wal,81,F,0.06958386122210311,0.08944543828264759 +1994,Wal,82,M,0.1161205766710354,0.1594202898550725 +1994,Wal,82,F,0.0765033407572383,0.066 +1994,Wal,83,M,0.1268548152458539,0.1282051282051282 +1994,Wal,83,F,0.09067326966159653,0.054117647058823534 +1994,Wal,84,M,0.1487804878048781,0.1776315789473684 +1994,Wal,84,F,0.1012013580569339,0.0967741935483871 +1994,Wal,85,M,0.172501054407423,0.0821917808219178 +1994,Wal,85,F,0.1136201229098185,0.1098265895953757 +1994,Wal,86,M,0.1788944723618091,0.1666666666666667 +1994,Wal,86,F,0.1219512195121951,0.1107142857142857 +1994,Wal,87,M,0.2104283054003725,0.1573033707865169 +1994,Wal,87,F,0.1365749709414956,0.1574468085106383 +1994,Wal,88,M,0.1792604501607717,0.1917808219178082 +1994,Wal,88,F,0.1495327102803738,0.1722488038277512 +1994,Wal,89,M,0.2363083164300203,0.2321428571428572 +1994,Wal,89,F,0.1571349250416435,0.1851851851851852 +1994,Wal,90,M,0.2346666666666667,0.2 +1994,Wal,90,F,0.1843205574912892,0.1739130434782609 +1994,Wal,91,M,0.2364990689013036,0.3125 +1994,Wal,91,F,0.207479964381122,0.1428571428571429 +1994,Wal,92,M,0.29176470588235304,0.16 +1994,Wal,92,F,0.23035809727418505,0.2526315789473685 +1994,Wal,93,M,0.2730627306273063,0.2222222222222222 +1994,Wal,93,F,0.2391817466561763,0.1805555555555556 +1994,Wal,94,M,0.3010752688172043,0.2857142857142857 +1994,Wal,94,F,0.2482352941176471,0.2222222222222222 +1994,Wal,95,M,0.3,0.1818181818181818 +1994,Wal,95,F,0.2882447665056361,0.1666666666666667 +1994,Wal,96,M,0.3188405797101449,0.1666666666666667 +1994,Wal,96,F,0.2987341772151899,0.4074074074074074 +1994,Wal,97,M,0.3666666666666667,0.2222222222222222 +1994,Wal,97,F,0.3076923076923077,0.09090909090909093 +1994,Wal,98,M,0.25,0.0 +1994,Wal,98,F,0.2698412698412699,0.25 +1994,Wal,99,M,0.3888888888888889,0.5 +1994,Wal,99,F,0.3813559322033898,0.2857142857142857 +1994,Wal,100,M,0.5,0.0 +1994,Wal,100,F,0.3508771929824561,0.5 +1994,Wal,101,M,0.5,0.0 +1994,Wal,101,F,0.3478260869565218,0.0 +1994,Wal,102,M,1.0,0.0 +1994,Wal,102,F,0.1764705882352941,1.0 +1994,Wal,103,M,0.0,0.0 +1994,Wal,103,F,0.4,0.5 +1994,Wal,104,M,1.0,0.0 +1994,Wal,104,F,0.0,0.0 +1994,Wal,105,M,0.0,0.0 +1994,Wal,105,F,0.4,0.0 +1994,Wal,106,M,0.0,0.0 +1994,Wal,106,F,0.0,0.0 +1994,Wal,107,M,0.0,0.0 +1994,Wal,107,F,0.0,0.0 +1994,Wal,108,M,0.0,0.0 +1994,Wal,108,F,0.0,0.0 +1994,Wal,109,M,0.0,0.0 +1994,Wal,109,F,0.0,0.0 +1994,Wal,110,M,0.0,0.0 +1994,Wal,110,F,0.0,0.0 +1994,Wal,111,M,0.0,0.0 +1994,Wal,111,F,0.0,0.0 +1994,Wal,112,M,0.0,0.0 +1994,Wal,112,F,0.0,0.0 +1994,Wal,113,M,0.0,0.0 +1994,Wal,113,F,0.0,0.0 +1994,Wal,114,M,0.0,0.0 +1994,Wal,114,F,0.0,0.0 +1994,Wal,115,M,0.0,0.0 +1994,Wal,115,F,0.0,0.0 +1994,Wal,116,M,0.0,0.0 +1994,Wal,116,F,0.0,0.0 +1994,Wal,117,M,0.0,0.0 +1994,Wal,117,F,0.0,0.0 +1994,Wal,118,M,0.0,0.0 +1994,Wal,118,F,0.0,0.0 +1994,Wal,119,M,0.0,0.0 +1994,Wal,119,F,0.0,0.0 +1994,Wal,120,M,0.0,0.0 +1994,Wal,120,F,0.0,0.0 +1995,BruCap,0,M,0.001820250284414107,0.002374169040835708 +1995,BruCap,0,F,0.000501002004008016,0.002029426686960934 +1995,BruCap,1,M,0.0004797313504437514,0.00048100048100048096 +1995,BruCap,1,F,0.000751503006012024,0.0 +1995,BruCap,2,M,0.0009678199854827002,0.0004816955684007707 +1995,BruCap,2,F,0.0,0.0 +1995,BruCap,3,M,0.0002503755633450175,0.00048661800486618007 +1995,BruCap,3,F,0.0,0.001490312965722802 +1995,BruCap,4,M,0.0005142710208279761,0.0 +1995,BruCap,4,F,0.00026845637583892615,0.0 +1995,BruCap,5,M,0.00027196083763937986,0.00048614487117160907 +1995,BruCap,5,F,0.0002810567734682406,0.0 +1995,BruCap,6,M,0.0008234971177600879,0.0004880429477794046 +1995,BruCap,6,F,0.0,0.0004935834155972358 +1995,BruCap,7,M,0.0,0.0004914004914004914 +1995,BruCap,7,F,0.0,0.0 +1995,BruCap,8,M,0.0005873715124816446,0.0 +1995,BruCap,8,F,0.0,0.0 +1995,BruCap,9,M,0.0003070310101320234,0.0 +1995,BruCap,9,F,0.0009891196834817012,0.0005458515283842794 +1995,BruCap,10,M,0.0,0.0 +1995,BruCap,10,F,0.0,0.0 +1995,BruCap,11,M,0.0,0.0 +1995,BruCap,11,F,0.0,0.000552791597567717 +1995,BruCap,12,M,0.0,0.0 +1995,BruCap,12,F,0.0006153846153846152,0.0 +1995,BruCap,13,M,0.0,0.0009460737937559133 +1995,BruCap,13,F,0.0003089280197713933,0.001003009027081244 +1995,BruCap,14,M,0.00030845157310302283,0.0009062075215224287 +1995,BruCap,14,F,0.0006313131313131314,0.0 +1995,BruCap,15,M,0.0003203074951953877,0.0 +1995,BruCap,15,F,0.0,0.0 +1995,BruCap,16,M,0.0,0.001841620626151013 +1995,BruCap,16,F,0.0,0.0004434589800443459 +1995,BruCap,17,M,0.001333777925975325,0.0 +1995,BruCap,17,F,0.0003369272237196766,0.0 +1995,BruCap,18,M,0.0012418503570319778,0.001485148514851485 +1995,BruCap,18,F,0.0006199628022318662,0.0004987531172069825 +1995,BruCap,19,M,0.0,0.001095290251916758 +1995,BruCap,19,F,0.0002849814762040468,0.0 +1995,BruCap,20,M,0.002013808975834293,0.0 +1995,BruCap,20,F,0.000276243093922652,0.0 +1995,BruCap,21,M,0.0005213764337851929,0.0 +1995,BruCap,21,F,0.0007477567298105682,0.00043308791684712 +1995,BruCap,22,M,0.0014869888475836429,0.001188118811881188 +1995,BruCap,22,F,0.0006983240223463687,0.0 +1995,BruCap,23,M,0.0006825938566552901,0.00037565740045078885 +1995,BruCap,23,F,0.0006454388984509468,0.0 +1995,BruCap,24,M,0.000661521499448732,0.0003401360544217687 +1995,BruCap,24,F,0.000812842918106076,0.0003541076487252125 +1995,BruCap,25,M,0.000418848167539267,0.0006283380458686772 +1995,BruCap,25,F,0.0,0.0 +1995,BruCap,26,M,0.001439440674480773,0.0006038647342995169 +1995,BruCap,26,F,0.0002003606491685033,0.0003263707571801567 +1995,BruCap,27,M,0.001598721023181455,0.001234949058351343 +1995,BruCap,27,F,0.00039541320680110717,0.001297858533419857 +1995,BruCap,28,M,0.001441812564366633,0.0014088475626937169 +1995,BruCap,28,F,0.0,0.0006073489219556638 +1995,BruCap,29,M,0.001788908765652952,0.001371365880416895 +1995,BruCap,29,F,0.0,0.00030075187969924816 +1995,BruCap,30,M,0.0010164667615368982,0.0008092797410304827 +1995,BruCap,30,F,0.001227495908346972,0.0008891523414344992 +1995,BruCap,31,M,0.00123253903040263,0.001142857142857143 +1995,BruCap,31,F,0.001040582726326743,0.0009606147934678194 +1995,BruCap,32,M,0.0022237046920169,0.001139925904816187 +1995,BruCap,32,F,0.001310329766324525,0.0006596306068601582 +1995,BruCap,33,M,0.002242152466367713,0.0009287925696594426 +1995,BruCap,33,F,0.001070434596446157,0.00103021978021978 +1995,BruCap,34,M,0.00271125169453231,0.001254705144291092 +1995,BruCap,34,F,0.001495726495726496,0.0003387533875338754 +1995,BruCap,35,M,0.002445531347265451,0.001717622810030917 +1995,BruCap,35,F,0.0006561679790026247,0.001123174840883564 +1995,BruCap,36,M,0.0023408239700374537,0.001740341106856944 +1995,BruCap,36,F,0.0002172024326672459,0.000777000777000777 +1995,BruCap,37,M,0.002088651659317707,0.001534919416730622 +1995,BruCap,37,F,0.001104728236853734,0.0004137360364087712 +1995,BruCap,38,M,0.0031423737007493352,0.00224887556221889 +1995,BruCap,38,F,0.002685164466323563,0.0008210180623973727 +1995,BruCap,39,M,0.0045860487569394145,0.0003924646781789639 +1995,BruCap,39,F,0.0020156774916013447,0.0004275331338178709 +1995,BruCap,40,M,0.0038268356852427647,0.0012552301255230132 +1995,BruCap,40,F,0.001142857142857143,0.0004516711833785004 +1995,BruCap,41,M,0.00262091970455087,0.001751313485113836 +1995,BruCap,41,F,0.00111185234600845,0.0 +1995,BruCap,42,M,0.002385496183206107,0.00175054704595186 +1995,BruCap,42,F,0.0029213483146067424,0.001968503937007874 +1995,BruCap,43,M,0.004189255791030064,0.0034113060428849896 +1995,BruCap,43,F,0.002486437613019892,0.001129943502824859 +1995,BruCap,44,M,0.004021110831867303,0.001403837154890033 +1995,BruCap,44,F,0.0022079929344226107,0.001561686621551276 +1995,BruCap,45,M,0.004720496894409939,0.001566579634464752 +1995,BruCap,45,F,0.003085739475424289,0.001812688821752266 +1995,BruCap,46,M,0.005051719990377675,0.001567398119122257 +1995,BruCap,46,F,0.003924133420536299,0.0012113870381586919 +1995,BruCap,47,M,0.004772130756382725,0.003218884120171674 +1995,BruCap,47,F,0.001880484747179273,0.001287001287001287 +1995,BruCap,48,M,0.007374971191518783,0.002878526194588371 +1995,BruCap,48,F,0.003603985584057664,0.001321003963011889 +1995,BruCap,49,M,0.01133536079623998,0.005031446540880503 +1995,BruCap,49,F,0.003445729756337682,0.00361794500723589 +1995,BruCap,50,M,0.007886435331230283,0.006273525721455458 +1995,BruCap,50,F,0.005266773528738264,0.002892263195950832 +1995,BruCap,51,M,0.008149959250203748,0.004078857919782461 +1995,BruCap,51,F,0.004102316602316602,0.001567398119122257 +1995,BruCap,52,M,0.009557183816502071,0.004626569729015202 +1995,BruCap,52,F,0.00308641975308642,0.0040650406504065045 +1995,BruCap,53,M,0.008614501076812634,0.0007739938080495358 +1995,BruCap,53,F,0.004649721016738996,0.004492362982929021 +1995,BruCap,54,M,0.008985879332477536,0.004383218534752661 +1995,BruCap,54,F,0.0068201193520886615,0.0007168458781362008 +1995,BruCap,55,M,0.01295180722891567,0.003498950314905529 +1995,BruCap,55,F,0.0043312101910828035,0.0008453085376162299 +1995,BruCap,56,M,0.009770992366412214,0.009715475364330326 +1995,BruCap,56,F,0.007045929018789144,0.003587443946188341 +1995,BruCap,57,M,0.016799022602321318,0.006792452830188679 +1995,BruCap,57,F,0.006267955079655264,0.003700277520814061 +1995,BruCap,58,M,0.01694383432695325,0.005970149253731343 +1995,BruCap,58,F,0.008181578252837161,0.002734731084776664 +1995,BruCap,59,M,0.01196850393700788,0.009251471825063078 +1995,BruCap,59,F,0.007432086109687341,0.003745318352059925 +1995,BruCap,60,M,0.01346499102333932,0.01109215017064846 +1995,BruCap,60,F,0.010469867211440241,0.006376195536663124 +1995,BruCap,61,M,0.02119285498032092,0.016885553470919332 +1995,BruCap,61,F,0.009570552147239264,0.013189448441247 +1995,BruCap,62,M,0.02509374098644361,0.01367365542388332 +1995,BruCap,62,F,0.009473197781885398,0.004728132387706857 +1995,BruCap,63,M,0.020827469743878408,0.0130718954248366 +1995,BruCap,63,F,0.00899078444594291,0.0026075619295958287 +1995,BruCap,64,M,0.0241240666283745,0.0175609756097561 +1995,BruCap,64,F,0.01305158483530143,0.0073081607795371486 +1995,BruCap,65,M,0.033963378617838165,0.01680672268907563 +1995,BruCap,65,F,0.01311762133799738,0.007898894154818325 +1995,BruCap,66,M,0.02272047832585949,0.01462765957446809 +1995,BruCap,66,F,0.014390081912773968,0.007541478129713423 +1995,BruCap,67,M,0.03255528255528256,0.01355421686746988 +1995,BruCap,67,F,0.01132897603485839,0.008928571428571428 +1995,BruCap,68,M,0.030404378230465188,0.021381578947368415 +1995,BruCap,68,F,0.01490657148855763,0.01444043321299639 +1995,BruCap,69,M,0.028854824165915238,0.01996370235934664 +1995,BruCap,69,F,0.01689395481375941,0.004008016032064128 +1995,BruCap,70,M,0.0389948006932409,0.029816513761467888 +1995,BruCap,70,F,0.017750299162345433,0.0189873417721519 +1995,BruCap,71,M,0.04059040590405904,0.0367170626349892 +1995,BruCap,71,F,0.02095750817150548,0.03333333333333334 +1995,BruCap,72,M,0.04307116104868914,0.03307888040712468 +1995,BruCap,72,F,0.02322857700566075,0.02506265664160401 +1995,BruCap,73,M,0.04338781575037147,0.05026455026455026 +1995,BruCap,73,F,0.02383676582761251,0.0254957507082153 +1995,BruCap,74,M,0.04966991512103112,0.04166666666666667 +1995,BruCap,74,F,0.02589118198874297,0.011820330969267141 +1995,BruCap,75,M,0.060735671514114624,0.03571428571428571 +1995,BruCap,75,F,0.03518518518518519,0.03308823529411765 +1995,BruCap,76,M,0.06661991584852735,0.05389221556886229 +1995,BruCap,76,F,0.030785947120608483,0.02884615384615385 +1995,BruCap,77,M,0.06299782766111513,0.0641025641025641 +1995,BruCap,77,F,0.03092006033182504,0.024154589371980683 +1995,BruCap,78,M,0.06752873563218391,0.08130081300813008 +1995,BruCap,78,F,0.03723217421847559,0.026178010471204192 +1995,BruCap,79,M,0.08353510895883777,0.07692307692307693 +1995,BruCap,79,F,0.04616289326668627,0.05076142131979695 +1995,BruCap,80,M,0.08204845814977972,0.05517241379310345 +1995,BruCap,80,F,0.04947717419025759,0.02577319587628866 +1995,BruCap,81,M,0.09614206981016532,0.06666666666666668 +1995,BruCap,81,F,0.04910836762688615,0.02631578947368421 +1995,BruCap,82,M,0.1088011088011088,0.1075268817204301 +1995,BruCap,82,F,0.06620808254514188,0.04975124378109453 +1995,BruCap,83,M,0.1110197368421053,0.1195652173913044 +1995,BruCap,83,F,0.07188498402555911,0.060810810810810814 +1995,BruCap,84,M,0.1321462043111528,0.05882352941176471 +1995,BruCap,84,F,0.07998661311914324,0.08235294117647059 +1995,BruCap,85,M,0.1479820627802691,0.1296296296296296 +1995,BruCap,85,F,0.0886426592797784,0.06944444444444445 +1995,BruCap,86,M,0.1295060080106809,0.078125 +1995,BruCap,86,F,0.1019397441188609,0.1132075471698113 +1995,BruCap,87,M,0.1943127962085308,0.09259259259259256 +1995,BruCap,87,F,0.1195238095238095,0.1401869158878505 +1995,BruCap,88,M,0.1904761904761905,0.1666666666666667 +1995,BruCap,88,F,0.1287749287749288,0.0989010989010989 +1995,BruCap,89,M,0.2338308457711443,0.1111111111111111 +1995,BruCap,89,F,0.1339584728734093,0.1075268817204301 +1995,BruCap,90,M,0.1766561514195584,0.25 +1995,BruCap,90,F,0.1569105691056911,0.1147540983606558 +1995,BruCap,91,M,0.2289156626506024,0.4285714285714286 +1995,BruCap,91,F,0.1600418410041841,0.1132075471698113 +1995,BruCap,92,M,0.1989247311827957,0.07692307692307693 +1995,BruCap,92,F,0.1809635722679201,0.1351351351351352 +1995,BruCap,93,M,0.2627737226277373,0.3333333333333333 +1995,BruCap,93,F,0.197346600331675,0.1842105263157895 +1995,BruCap,94,M,0.2911392405063291,0.0 +1995,BruCap,94,F,0.2284382284382285,0.15625 +1995,BruCap,95,M,0.3389830508474576,0.2857142857142857 +1995,BruCap,95,F,0.2708933717579251,0.3333333333333333 +1995,BruCap,96,M,0.2051282051282051,0.2 +1995,BruCap,96,F,0.271889400921659,0.1052631578947368 +1995,BruCap,97,M,0.3157894736842105,0.0 +1995,BruCap,97,F,0.3284671532846715,0.3333333333333333 +1995,BruCap,98,M,0.4090909090909091,0.0 +1995,BruCap,98,F,0.2424242424242425,0.0 +1995,BruCap,99,M,0.25,0.0 +1995,BruCap,99,F,0.2125,0.0 +1995,BruCap,100,M,0.5,0.0 +1995,BruCap,100,F,0.38095238095238093,0.3333333333333333 +1995,BruCap,101,M,0.2,0.0 +1995,BruCap,101,F,0.1739130434782609,0.0 +1995,BruCap,102,M,0.3333333333333333,1.0 +1995,BruCap,102,F,0.4705882352941176,0.0 +1995,BruCap,103,M,0.0,0.0 +1995,BruCap,103,F,0.2857142857142857,1.0 +1995,BruCap,104,M,0.0,0.0 +1995,BruCap,104,F,1.0,0.0 +1995,BruCap,105,M,0.0,0.0 +1995,BruCap,105,F,0.0,0.0 +1995,BruCap,106,M,0.0,0.0 +1995,BruCap,106,F,1.0,0.0 +1995,BruCap,107,M,0.0,0.0 +1995,BruCap,107,F,1.0,0.0 +1995,BruCap,108,M,0.0,0.0 +1995,BruCap,108,F,0.0,0.0 +1995,BruCap,109,M,0.0,0.0 +1995,BruCap,109,F,0.0,0.0 +1995,BruCap,110,M,0.0,0.0 +1995,BruCap,110,F,0.0,0.0 +1995,BruCap,111,M,0.0,0.0 +1995,BruCap,111,F,0.0,0.0 +1995,BruCap,112,M,0.0,0.0 +1995,BruCap,112,F,0.0,0.0 +1995,BruCap,113,M,0.0,0.0 +1995,BruCap,113,F,0.0,0.0 +1995,BruCap,114,M,0.0,0.0 +1995,BruCap,114,F,0.0,0.0 +1995,BruCap,115,M,0.0,0.0 +1995,BruCap,115,F,0.0,0.0 +1995,BruCap,116,M,0.0,0.0 +1995,BruCap,116,F,0.0,0.0 +1995,BruCap,117,M,0.0,0.0 +1995,BruCap,117,F,0.0,0.0 +1995,BruCap,118,M,0.0,0.0 +1995,BruCap,118,F,0.0,0.0 +1995,BruCap,119,M,0.0,0.0 +1995,BruCap,119,F,0.0,0.0 +1995,BruCap,120,M,0.0,0.0 +1995,BruCap,120,F,0.0,0.0 +1995,Fla,0,M,0.0017892517093744012,0.001952171791117619 +1995,Fla,0,F,0.0008719272946778897,0.001658374792703151 +1995,Fla,1,M,0.00045698269558859365,0.0004926108374384236 +1995,Fla,1,F,0.00047217325610677413,0.0 +1995,Fla,2,M,0.00017587571449509008,0.000493339911198816 +1995,Fla,2,F,0.0002146317532348072,0.0 +1995,Fla,3,M,0.0002311604253351826,0.0004725897920604915 +1995,Fla,3,F,0.0001520773769694021,0.001009081735620585 +1995,Fla,4,M,0.00032095235316429837,0.0 +1995,Fla,4,F,0.0001227860146729288,0.0004878048780487805 +1995,Fla,5,M,0.000150665943470138,0.0 +1995,Fla,5,F,0.00012669855246903798,0.000512295081967213 +1995,Fla,6,M,0.0001220926683352665,0.00048146364949446316 +1995,Fla,6,F,3.194173826939663e-05,0.0005154639175257731 +1995,Fla,7,M,0.00012290674450760494,0.0 +1995,Fla,7,F,0.0001298954341754887,0.0005192107995846313 +1995,Fla,8,M,6.122948812147929e-05,0.0004995004995004995 +1995,Fla,8,F,0.0001945462209396583,0.0 +1995,Fla,9,M,0.0001259723490693793,0.0005138746145940392 +1995,Fla,9,F,0.00019784350578692255,0.0 +1995,Fla,10,M,0.00018455292054996768,0.0005186721991701245 +1995,Fla,10,F,0.0001612903225806452,0.0 +1995,Fla,11,M,0.00023819448579765387,0.000544069640914037 +1995,Fla,11,F,9.33968431867003e-05,0.0 +1995,Fla,12,M,0.0002023823291314907,0.0 +1995,Fla,12,F,0.0001531299767242435,0.0 +1995,Fla,13,M,0.0001961553550411926,0.0 +1995,Fla,13,F,0.0001198537783903638,0.0 +1995,Fla,14,M,0.0005413259637026696,0.0 +1995,Fla,14,F,0.0002079866888519135,0.0004803073967339097 +1995,Fla,15,M,0.0004778099440681301,0.000445632798573975 +1995,Fla,15,F,0.0003294300859513043,0.0 +1995,Fla,16,M,0.0004316049951084767,0.0004675081813931744 +1995,Fla,16,F,0.0002704326923076923,0.0 +1995,Fla,17,M,0.0005273488998916004,0.0 +1995,Fla,17,F,0.00024364987512943907,0.0 +1995,Fla,18,M,0.0010339428672712769,0.0 +1995,Fla,18,F,0.000558850010866528,0.0 +1995,Fla,19,M,0.001325580694724792,0.0011634671320535199 +1995,Fla,19,F,0.0005086631696073756,0.0 +1995,Fla,20,M,0.001219087425983978,0.0 +1995,Fla,20,F,0.0003031589159037168,0.0 +1995,Fla,21,M,0.001312959186524011,0.001885014137606032 +1995,Fla,21,F,0.0002928343436118188,0.0 +1995,Fla,22,M,0.0010427807486631019,0.0013495276653171392 +1995,Fla,22,F,0.0005010577886649594,0.0 +1995,Fla,23,M,0.001158808230113563,0.0007902015013828526 +1995,Fla,23,F,0.0004501880197023463,0.0 +1995,Fla,24,M,0.0008751750350070014,0.0011009174311926607 +1995,Fla,24,F,0.0004174929548063877,0.0003780718336483932 +1995,Fla,25,M,0.001328953637070284,0.001709986320109439 +1995,Fla,25,F,0.00033962066983645963,0.0 +1995,Fla,26,M,0.0009936160170901953,0.001671122994652407 +1995,Fla,26,F,0.000490702479338843,0.0 +1995,Fla,27,M,0.0009575563162808512,0.0 +1995,Fla,27,F,0.0004785773658094254,0.0 +1995,Fla,28,M,0.0012330456226880401,0.0005842827928717499 +1995,Fla,28,F,0.0003857373610742786,0.0 +1995,Fla,29,M,0.001099048986183384,0.001479289940828403 +1995,Fla,29,F,0.000491538515553683,0.000362844702467344 +1995,Fla,30,M,0.0009916357678710012,0.0005753739930955121 +1995,Fla,30,F,0.0004215009871996806,0.0006968641114982577 +1995,Fla,31,M,0.001037434079709519,0.0015239256324291381 +1995,Fla,31,F,0.00044720719109163284,0.0007352941176470588 +1995,Fla,32,M,0.00113666171198741,0.0002928257686676428 +1995,Fla,32,F,0.0006335558321077045,0.0011820330969267141 +1995,Fla,33,M,0.0007670056100981768,0.0009538950715421305 +1995,Fla,33,F,0.0005601989826786475,0.00041788549937317183 +1995,Fla,34,M,0.0014574317809816358,0.002068557919621749 +1995,Fla,34,F,0.0009898482999930944,0.0007701193685021178 +1995,Fla,35,M,0.001316078087299847,0.002010050251256282 +1995,Fla,35,F,0.0006979781150087813,0.0004184100418410042 +1995,Fla,36,M,0.001249525849566013,0.0003254149040026033 +1995,Fla,36,F,0.0008098290103889492,0.0004462293618920125 +1995,Fla,37,M,0.001262939491666855,0.002083333333333333 +1995,Fla,37,F,0.0008185028413741492,0.0014873574615765991 +1995,Fla,38,M,0.001767236367864202,0.001065340909090909 +1995,Fla,38,F,0.0008064707417158851,0.001869158878504673 +1995,Fla,39,M,0.0016685859321755071,0.0007280669821623589 +1995,Fla,39,F,0.0007650011953143677,0.001544799176107106 +1995,Fla,40,M,0.002030287106482588,0.0011472275334608027 +1995,Fla,40,F,0.0011522714457329179,0.0005268703898840885 +1995,Fla,41,M,0.002167348529125268,0.0025466893039049238 +1995,Fla,41,F,0.0013400080906148866,0.0005627462014631404 +1995,Fla,42,M,0.002654263867919934,0.0008257638315441782 +1995,Fla,42,F,0.001498108320849097,0.002372479240806643 +1995,Fla,43,M,0.00260609622116048,0.0025929127052722557 +1995,Fla,43,F,0.001711787632992732,0.003846153846153847 +1995,Fla,44,M,0.002385149849631857,0.001629327902240326 +1995,Fla,44,F,0.001716534185438509,0.002430133657351154 +1995,Fla,45,M,0.0028503928919932212,0.003323639385126714 +1995,Fla,45,F,0.0020185922974767607,0.0006176652254478072 +1995,Fla,46,M,0.00378047525974694,0.002606429192006951 +1995,Fla,46,F,0.002223210315695865,0.003340013360053441 +1995,Fla,47,M,0.003668018495079173,0.00365296803652968 +1995,Fla,47,F,0.00214240372407956,0.002677376171352075 +1995,Fla,48,M,0.0043789007449164495,0.0036815462494247603 +1995,Fla,48,F,0.002448299213418764,0.002869440459110474 +1995,Fla,49,M,0.004920675320268092,0.003755364806866953 +1995,Fla,49,F,0.002592539248163618,0.005477308294209703 +1995,Fla,50,M,0.004359222747734914,0.003234501347708895 +1995,Fla,50,F,0.002782366750717329,0.001502629601803156 +1995,Fla,51,M,0.005801154280954364,0.005446623093681918 +1995,Fla,51,F,0.002687441495304526,0.002465078060805259 +1995,Fla,52,M,0.006611682911866948,0.004681100058513751 +1995,Fla,52,F,0.002842484747642818,0.002454991816693945 +1995,Fla,53,M,0.006453817243081128,0.005360333531864205 +1995,Fla,53,F,0.003497292418772563,0.001845018450184502 +1995,Fla,54,M,0.007421660252886202,0.00605060506050605 +1995,Fla,54,F,0.003930204980518381,0.003891050583657589 +1995,Fla,55,M,0.00771885786005648,0.00823529411764706 +1995,Fla,55,F,0.003388292240205718,0.0027855153203342627 +1995,Fla,56,M,0.008544677756567585,0.006146281499692686 +1995,Fla,56,F,0.004710134194389311,0.0036463081130355523 +1995,Fla,57,M,0.008342446492735509,0.008575197889182058 +1995,Fla,57,F,0.0043560954659795075,0.004921259842519685 +1995,Fla,58,M,0.01075199380065222,0.004187020237264481 +1995,Fla,58,F,0.004639287604695333,0.00211864406779661 +1995,Fla,59,M,0.01042881202228268,0.012454212454212459 +1995,Fla,59,F,0.005541546029077551,0.006666666666666667 +1995,Fla,60,M,0.01144076013185961,0.01196709050112192 +1995,Fla,60,F,0.005453991468616697,0.002141327623126339 +1995,Fla,61,M,0.01406184638156837,0.008520526723470178 +1995,Fla,61,F,0.007122550667930181,0.005688282138794084 +1995,Fla,62,M,0.01585146357636806,0.01675977653631285 +1995,Fla,62,F,0.007032348804500703,0.006090133982947625 +1995,Fla,63,M,0.01712143832788031,0.0145322434150772 +1995,Fla,63,F,0.007779597566682265,0.008746355685131196 +1995,Fla,64,M,0.018421223324901082,0.01420959147424512 +1995,Fla,64,F,0.008609038020802727,0.006459948320413436 +1995,Fla,65,M,0.02037518443054873,0.0196078431372549 +1995,Fla,65,F,0.008601205424409845,0.008683068017366137 +1995,Fla,66,M,0.02386409109098185,0.01958650707290533 +1995,Fla,66,F,0.01105540557912328,0.01167883211678832 +1995,Fla,67,M,0.024611889435819767,0.02807017543859649 +1995,Fla,67,F,0.011011745862253073,0.02291325695581015 +1995,Fla,68,M,0.02792253247258303,0.029299363057324838 +1995,Fla,68,F,0.01283734979315779,0.014173228346456691 +1995,Fla,69,M,0.02862535388486946,0.0302233902759527 +1995,Fla,69,F,0.015206468572189132,0.019386106623586436 +1995,Fla,70,M,0.033711560598585766,0.04155495978552279 +1995,Fla,70,F,0.0155697579548545,0.01449275362318841 +1995,Fla,71,M,0.03757410329679703,0.03846153846153847 +1995,Fla,71,F,0.01840932464861159,0.033509700176366834 +1995,Fla,72,M,0.04341372912801484,0.043478260869565216 +1995,Fla,72,F,0.02025601861953597,0.029821073558648117 +1995,Fla,73,M,0.04478480031019775,0.040816326530612235 +1995,Fla,73,F,0.022713095805966317,0.0309278350515464 +1995,Fla,74,M,0.05134474327628362,0.05731225296442687 +1995,Fla,74,F,0.02794245364951101,0.02620087336244542 +1995,Fla,75,M,0.05692573402417962,0.07304785894206549 +1995,Fla,75,F,0.030601477312697863,0.0302013422818792 +1995,Fla,76,M,0.06452316076294277,0.07142857142857142 +1995,Fla,76,F,0.0332647965927449,0.04411764705882353 +1995,Fla,77,M,0.07046547074686364,0.07806691449814128 +1995,Fla,77,F,0.041873776171110114,0.04979253112033195 +1995,Fla,78,M,0.07463644140290847,0.0653061224489796 +1995,Fla,78,F,0.04618336302590106,0.05882352941176471 +1995,Fla,79,M,0.08429408429408429,0.0851063829787234 +1995,Fla,79,F,0.04892298613160224,0.06349206349206349 +1995,Fla,80,M,0.09660287519457923,0.09691629955947137 +1995,Fla,80,F,0.05251105075358151,0.06048387096774194 +1995,Fla,81,M,0.1028180518684909,0.08648648648648649 +1995,Fla,81,F,0.061764376191009975,0.037815126050420166 +1995,Fla,82,M,0.1146794214781916,0.1049382716049383 +1995,Fla,82,F,0.07308970099667775,0.06280193236714976 +1995,Fla,83,M,0.1266943291839557,0.1388888888888889 +1995,Fla,83,F,0.07856063727509957,0.09714285714285714 +1995,Fla,84,M,0.1322469445314948,0.1276595744680851 +1995,Fla,84,F,0.09005839197484654,0.10897435897435903 +1995,Fla,85,M,0.1486815036469048,0.15 +1995,Fla,85,F,0.0981991165477404,0.07027027027027027 +1995,Fla,86,M,0.1606241395135383,0.125 +1995,Fla,86,F,0.1101288441643939,0.1166666666666667 +1995,Fla,87,M,0.1712347354138399,0.1509433962264151 +1995,Fla,87,F,0.1259529333775273,0.1981981981981982 +1995,Fla,88,M,0.2086081221797987,0.1132075471698113 +1995,Fla,88,F,0.1521048451151708,0.1555555555555556 +1995,Fla,89,M,0.1873568483737975,0.1627906976744186 +1995,Fla,89,F,0.1555207517619421,0.1290322580645161 +1995,Fla,90,M,0.2176403207331043,0.1875 +1995,Fla,90,F,0.1760549933167844,0.1149425287356322 +1995,Fla,91,M,0.2244427363566488,0.06666666666666668 +1995,Fla,91,F,0.1985833544143688,0.2222222222222222 +1995,Fla,92,M,0.2680756395995551,0.1666666666666667 +1995,Fla,92,F,0.2008505070330389,0.1212121212121212 +1995,Fla,93,M,0.2754050073637703,0.2666666666666667 +1995,Fla,93,F,0.2264957264957265,0.03225806451612903 +1995,Fla,94,M,0.2894117647058824,0.1 +1995,Fla,94,F,0.2591656131479141,0.1111111111111111 +1995,Fla,95,M,0.2906976744186047,0.2222222222222222 +1995,Fla,95,F,0.2727272727272727,0.25 +1995,Fla,96,M,0.4123222748815166,0.5 +1995,Fla,96,F,0.2831491712707183,0.2727272727272727 +1995,Fla,97,M,0.4421768707482993,0.25 +1995,Fla,97,F,0.2994011976047904,0.25 +1995,Fla,98,M,0.3411764705882353,1.0 +1995,Fla,98,F,0.2985074626865672,0.25 +1995,Fla,99,M,0.3488372093023256,0.0 +1995,Fla,99,F,0.2441314553990611,0.5 +1995,Fla,100,M,0.3461538461538462,0.0 +1995,Fla,100,F,0.3035714285714286,0.6666666666666666 +1995,Fla,101,M,0.5454545454545454,0.0 +1995,Fla,101,F,0.3538461538461539,0.0 +1995,Fla,102,M,0.625,0.0 +1995,Fla,102,F,0.4864864864864865,0.0 +1995,Fla,103,M,0.8,0.5 +1995,Fla,103,F,0.6153846153846154,0.0 +1995,Fla,104,M,0.5,0.0 +1995,Fla,104,F,0.6666666666666666,0.0 +1995,Fla,105,M,0.0,0.0 +1995,Fla,105,F,0.6666666666666666,0.0 +1995,Fla,106,M,0.0,0.0 +1995,Fla,106,F,0.3333333333333333,0.0 +1995,Fla,107,M,0.0,0.0 +1995,Fla,107,F,0.0,0.0 +1995,Fla,108,M,0.0,0.0 +1995,Fla,108,F,0.0,0.0 +1995,Fla,109,M,0.0,0.0 +1995,Fla,109,F,0.0,0.0 +1995,Fla,110,M,0.0,0.0 +1995,Fla,110,F,0.0,1.0 +1995,Fla,111,M,0.0,0.0 +1995,Fla,111,F,0.0,0.0 +1995,Fla,112,M,0.0,0.0 +1995,Fla,112,F,0.0,0.0 +1995,Fla,113,M,0.0,0.0 +1995,Fla,113,F,0.0,0.0 +1995,Fla,114,M,0.0,0.0 +1995,Fla,114,F,0.0,0.0 +1995,Fla,115,M,0.0,0.0 +1995,Fla,115,F,0.0,0.0 +1995,Fla,116,M,0.0,0.0 +1995,Fla,116,F,0.0,0.0 +1995,Fla,117,M,0.0,0.0 +1995,Fla,117,F,0.0,0.0 +1995,Fla,118,M,0.0,0.0 +1995,Fla,118,F,0.0,0.0 +1995,Fla,119,M,0.0,0.0 +1995,Fla,119,F,0.0,0.0 +1995,Fla,120,M,0.0,0.0 +1995,Fla,120,F,0.0,0.0 +1995,Wal,0,M,0.0018587360594795536,0.000835421888053467 +1995,Wal,0,F,0.001377410468319559,0.001814882032667877 +1995,Wal,1,M,0.0006228912535686477,0.001557632398753894 +1995,Wal,1,F,0.0002760448296803401,0.0 +1995,Wal,2,M,0.0003447426742181729,0.001454545454545455 +1995,Wal,2,F,0.0005675954592363262,0.0 +1995,Wal,3,M,0.000286902883373978,0.0 +1995,Wal,3,F,0.0002486943546381498,0.0 +1995,Wal,4,M,0.0001451589490492089,0.0 +1995,Wal,4,F,0.00010076074361428792,0.0 +1995,Wal,5,M,0.0001928547321729907,0.0 +1995,Wal,5,F,0.00015187566445603204,0.0006720430107526883 +1995,Wal,6,M,9.69555943377933e-05,0.0 +1995,Wal,6,F,5.118231139318252e-05,0.0 +1995,Wal,7,M,0.000100872547536188,0.0 +1995,Wal,7,F,0.0003171247357293869,0.0 +1995,Wal,8,M,0.0001007201490658206,0.0 +1995,Wal,8,F,0.000106258633513973,0.0 +1995,Wal,9,M,0.0001569940865560731,0.0 +1995,Wal,9,F,0.0001647989452867502,0.0006455777921239509 +1995,Wal,10,M,0.0001063264221158958,0.0006067961165048543 +1995,Wal,10,F,0.00011052777010223821,0.0 +1995,Wal,11,M,0.0002661131513119378,0.0 +1995,Wal,11,F,0.00023003047903847264,0.0012626262626262634 +1995,Wal,12,M,0.0004204993429697766,0.0005627462014631404 +1995,Wal,12,F,0.0002753000770840216,0.001165501165501166 +1995,Wal,13,M,0.00041862899005756153,0.0005449591280653951 +1995,Wal,13,F,0.0001615421894351408,0.0 +1995,Wal,14,M,0.00026188979677351784,0.0010152284263959394 +1995,Wal,14,F,0.0002696580735627225,0.0005327650506126798 +1995,Wal,15,M,0.0005845467105962378,0.0 +1995,Wal,15,F,0.0002815632391035027,0.0005219206680584551 +1995,Wal,16,M,0.0008136696501220504,0.0004595588235294118 +1995,Wal,16,F,0.0002255808707421611,0.0 +1995,Wal,17,M,0.00096,0.001385681293302541 +1995,Wal,17,F,0.0004496655612388286,0.001352569882777277 +1995,Wal,18,M,0.001468890987304585,0.001407129455909944 +1995,Wal,18,F,0.0003282096165417647,0.000474608448030375 +1995,Wal,19,M,0.0015600624024961,0.0009416195856873825 +1995,Wal,19,F,0.0005381841666218177,0.0004782400765184123 +1995,Wal,20,M,0.001104584023698348,0.000400320256204964 +1995,Wal,20,F,0.0004215629446171682,0.0004308487720809996 +1995,Wal,21,M,0.001699524133242692,0.001414927484966396 +1995,Wal,21,F,0.0005572441742654507,0.0 +1995,Wal,22,M,0.0016155856497980518,0.0006533812479581836 +1995,Wal,22,F,0.0004453461329110793,0.001065719360568384 +1995,Wal,23,M,0.001364449044885669,0.0009493670886075947 +1995,Wal,23,F,0.0005356186395286557,0.0006903693476009665 +1995,Wal,24,M,0.001119275877171639,0.002086438152011923 +1995,Wal,24,F,0.0004548211036992117,0.0006889424733034793 +1995,Wal,25,M,0.0012367665974077368,0.0008795074758135447 +1995,Wal,25,F,0.00040747720674374783,0.0 +1995,Wal,26,M,0.001737530662305806,0.001412429378531074 +1995,Wal,26,F,0.0003095815489396832,0.0 +1995,Wal,27,M,0.0020997900209979,0.0014471780028943561 +1995,Wal,27,F,0.0005627749923257956,0.0003371544167228591 +1995,Wal,28,M,0.001382033563672261,0.0024925224327018948 +1995,Wal,28,F,0.0002969708968521085,0.0003044140030441401 +1995,Wal,29,M,0.0012349197302175359,0.0007239382239382237 +1995,Wal,29,F,0.0007151029748283753,0.0003021148036253777 +1995,Wal,30,M,0.00127301659468061,0.001480750246791708 +1995,Wal,30,F,0.0005909090909090909,0.0 +1995,Wal,31,M,0.002077754178594515,0.0007309941520467836 +1995,Wal,31,F,0.0005449838775602886,0.0003138731952291275 +1995,Wal,32,M,0.001472404293720908,0.0012288031457360527 +1995,Wal,32,F,0.0007864180968682056,0.001904761904761905 +1995,Wal,33,M,0.002021687189854806,0.0017825311942959 +1995,Wal,33,F,0.0008958566629339306,0.0 +1995,Wal,34,M,0.002209843009069564,0.0023180343069077428 +1995,Wal,34,F,0.001139834951898965,0.00032041012495994867 +1995,Wal,35,M,0.001860760642643188,0.001727968402863491 +1995,Wal,35,F,0.0009207295685724307,0.000652954619653934 +1995,Wal,36,M,0.0026757704373500646,0.00198609731876862 +1995,Wal,36,F,0.001025549560797253,0.001004688546550569 +1995,Wal,37,M,0.003385585752713106,0.001763668430335097 +1995,Wal,37,F,0.0007255906761598112,0.0003497726477789437 +1995,Wal,38,M,0.002888804697859443,0.001225189904435188 +1995,Wal,38,F,0.001641811465316733,0.0 +1995,Wal,39,M,0.002527540655252993,0.0017930327868852462 +1995,Wal,39,F,0.0018224064877670968,0.0007022471910112357 +1995,Wal,40,M,0.00377574917554844,0.001849894291754757 +1995,Wal,40,F,0.0014686309605764381,0.0007358351729212656 +1995,Wal,41,M,0.003226877995539316,0.001670843776106934 +1995,Wal,41,F,0.001619096081787482,0.001203369434416366 +1995,Wal,42,M,0.003104996656157447,0.002025462962962963 +1995,Wal,42,F,0.0025284450063211127,0.001205787781350483 +1995,Wal,43,M,0.003497020144806186,0.001820388349514563 +1995,Wal,43,F,0.0023716914903709327,0.0 +1995,Wal,44,M,0.0040227165168007575,0.0008936550491510277 +1995,Wal,44,F,0.002348961758902565,0.001620745542949757 +1995,Wal,45,M,0.004606762917933131,0.002801992528019925 +1995,Wal,45,F,0.003280378649421248,0.001771479185119575 +1995,Wal,46,M,0.004671168254555545,0.0034887408816999693 +1995,Wal,46,F,0.0026730699528814787,0.001267427122940431 +1995,Wal,47,M,0.005704034224205346,0.006426735218508998 +1995,Wal,47,F,0.001962395034684191,0.003199268738574041 +1995,Wal,48,M,0.006425702811244979,0.0037722908093278467 +1995,Wal,48,F,0.002478656017625999,0.002946954813359529 +1995,Wal,49,M,0.005782550676749063,0.006858122588941277 +1995,Wal,49,F,0.003114331915913039,0.004694835680751174 +1995,Wal,50,M,0.007275718081741111,0.005190311418685121 +1995,Wal,50,F,0.0030553009471432947,0.0039347948285553686 +1995,Wal,51,M,0.008332768782602805,0.008196721311475409 +1995,Wal,51,F,0.003103582050950472,0.002442002442002442 +1995,Wal,52,M,0.008628060629615235,0.004985044865403789 +1995,Wal,52,F,0.003766895634832706,0.003719776813391197 +1995,Wal,53,M,0.0087580281925098,0.007205352547606794 +1995,Wal,53,F,0.003582554517133957,0.00199203187250996 +1995,Wal,54,M,0.009881718820182664,0.005714285714285714 +1995,Wal,54,F,0.004802338530066815,0.0022471910112359553 +1995,Wal,55,M,0.01023843880986738,0.006730769230769231 +1995,Wal,55,F,0.005534243129362933,0.00334075723830735 +1995,Wal,56,M,0.01041384906681093,0.005151983513652756 +1995,Wal,56,F,0.005154322881511935,0.003952569169960474 +1995,Wal,57,M,0.01193671422517305,0.009018036072144287 +1995,Wal,57,F,0.006009144350097975,0.005494505494505495 +1995,Wal,58,M,0.012918208868568109,0.01170483460559797 +1995,Wal,58,F,0.005987634233647901,0.004778972520908004 +1995,Wal,59,M,0.014626975376699741,0.015487867836861131 +1995,Wal,59,F,0.007408851627997659,0.008849557522123894 +1995,Wal,60,M,0.0157469342251951,0.011982570806100221 +1995,Wal,60,F,0.006110106615125632,0.0052417006406523 +1995,Wal,61,M,0.01677410411034865,0.01241900647948164 +1995,Wal,61,F,0.009134110967104857,0.005205320994794679 +1995,Wal,62,M,0.017753813782219883,0.01773948302078054 +1995,Wal,62,F,0.008342792281498297,0.007242003621001809 +1995,Wal,63,M,0.02102580439630456,0.01756373937677054 +1995,Wal,63,F,0.010331941085952959,0.008552229688454491 +1995,Wal,64,M,0.0256741065668946,0.02924281984334204 +1995,Wal,64,F,0.01164061646081539,0.008777062609713282 +1995,Wal,65,M,0.02645502645502646,0.02459474566797094 +1995,Wal,65,F,0.01165780901765815,0.010365853658536593 +1995,Wal,66,M,0.03039706608364483,0.02878103837471783 +1995,Wal,66,F,0.01221846846846847,0.01490602721970188 +1995,Wal,67,M,0.03106263093260132,0.03557312252964427 +1995,Wal,67,F,0.01184834123222749,0.01361386138613862 +1995,Wal,68,M,0.03592726201869985,0.03409726103968698 +1995,Wal,68,F,0.015625,0.01839362354383814 +1995,Wal,69,M,0.03751204685299133,0.0358662613981763 +1995,Wal,69,F,0.01583760874414455,0.0126984126984127 +1995,Wal,70,M,0.04219572623103128,0.04528535980148883 +1995,Wal,70,F,0.01844133599771624,0.01919122686771762 +1995,Wal,71,M,0.04114210483008311,0.05736636245110821 +1995,Wal,71,F,0.022005750836218533,0.0280373831775701 +1995,Wal,72,M,0.05186440677966102,0.05501130369253957 +1995,Wal,72,F,0.02313776413646559,0.028787878787878782 +1995,Wal,73,M,0.05517002081887578,0.06788511749347259 +1995,Wal,73,F,0.02506251090306449,0.028432168968318437 +1995,Wal,74,M,0.05859375,0.0696078431372549 +1995,Wal,74,F,0.028717026378896882,0.03052064631956912 +1995,Wal,75,M,0.0672053872053872,0.06655290102389079 +1995,Wal,75,F,0.034068977091549886,0.02533333333333334 +1995,Wal,76,M,0.07653061224489796,0.1096491228070175 +1995,Wal,76,F,0.03711763994680208,0.03501945525291829 +1995,Wal,77,M,0.07195402298850574,0.08629441624365483 +1995,Wal,77,F,0.04300254452926209,0.03433476394849786 +1995,Wal,78,M,0.08301404853128991,0.08264462809917356 +1995,Wal,78,F,0.04217904574520414,0.05202312138728324 +1995,Wal,79,M,0.0967550455085081,0.1191709844559586 +1995,Wal,79,F,0.0508439039731628,0.05263157894736842 +1995,Wal,80,M,0.1013833272661085,0.1138014527845036 +1995,Wal,80,F,0.057498410391497876,0.06359300476947535 +1995,Wal,81,M,0.1127835051546392,0.1072386058981233 +1995,Wal,81,F,0.07154165842074016,0.06920415224913495 +1995,Wal,82,M,0.1148058252427185,0.1197604790419162 +1995,Wal,82,F,0.07607105538140023,0.07129094412331406 +1995,Wal,83,M,0.1395555555555556,0.1802575107296138 +1995,Wal,83,F,0.08841243073958083,0.1085106382978723 +1995,Wal,84,M,0.1436170212765958,0.1597633136094675 +1995,Wal,84,F,0.09869357133617902,0.0948905109489051 +1995,Wal,85,M,0.173273395995096,0.203125 +1995,Wal,85,F,0.1087082728592163,0.1135135135135135 +1995,Wal,86,M,0.1780612244897959,0.164179104477612 +1995,Wal,86,F,0.1146670955291091,0.0981012658227848 +1995,Wal,87,M,0.1932721712538226,0.2151898734177215 +1995,Wal,87,F,0.1369714492229852,0.1877551020408163 +1995,Wal,88,M,0.1821036106750393,0.1538461538461539 +1995,Wal,88,F,0.1565295169946333,0.0975609756097561 +1995,Wal,89,M,0.2087804878048781,0.2372881355932204 +1995,Wal,89,F,0.1740470852017937,0.1491712707182321 +1995,Wal,90,M,0.20185922974767606,0.1951219512195122 +1995,Wal,90,F,0.1827461310503787,0.1886792452830189 +1995,Wal,91,M,0.2439446366782007,0.1621621621621622 +1995,Wal,91,F,0.1973572037510656,0.2142857142857143 +1995,Wal,92,M,0.2895377128953771,0.1304347826086957 +1995,Wal,92,F,0.2286995515695067,0.1442307692307692 +1995,Wal,93,M,0.2633333333333333,0.2608695652173913 +1995,Wal,93,F,0.2393876130828114,0.2837837837837838 +1995,Wal,94,M,0.3267326732673268,0.1666666666666667 +1995,Wal,94,F,0.2685185185185186,0.2982456140350877 +1995,Wal,95,M,0.3030303030303031,0.3333333333333333 +1995,Wal,95,F,0.2846034214618974,0.3214285714285715 +1995,Wal,96,M,0.3333333333333333,0.2222222222222222 +1995,Wal,96,F,0.3076923076923077,0.2941176470588236 +1995,Wal,97,M,0.3478260869565218,0.0 +1995,Wal,97,F,0.2717391304347826,0.2352941176470588 +1995,Wal,98,M,0.3421052631578948,0.3333333333333333 +1995,Wal,98,F,0.2980769230769231,0.1 +1995,Wal,99,M,0.3333333333333333,0.0 +1995,Wal,99,F,0.3260869565217392,0.6666666666666666 +1995,Wal,100,M,0.4444444444444444,0.0 +1995,Wal,100,F,0.4931506849315068,0.2 +1995,Wal,101,M,0.3333333333333333,1.0 +1995,Wal,101,F,0.3513513513513514,0.0 +1995,Wal,102,M,0.0,0.0 +1995,Wal,102,F,0.4137931034482759,0.0 +1995,Wal,103,M,0.0,0.0 +1995,Wal,103,F,0.5714285714285714,0.0 +1995,Wal,104,M,0.5,0.0 +1995,Wal,104,F,0.1666666666666667,0.0 +1995,Wal,105,M,0.0,0.0 +1995,Wal,105,F,0.0,1.0 +1995,Wal,106,M,0.0,0.0 +1995,Wal,106,F,0.0,0.0 +1995,Wal,107,M,0.0,0.0 +1995,Wal,107,F,0.0,0.0 +1995,Wal,108,M,0.0,0.0 +1995,Wal,108,F,0.0,0.0 +1995,Wal,109,M,0.0,0.0 +1995,Wal,109,F,0.0,0.0 +1995,Wal,110,M,0.0,0.0 +1995,Wal,110,F,0.0,0.0 +1995,Wal,111,M,0.0,0.0 +1995,Wal,111,F,0.0,0.0 +1995,Wal,112,M,0.0,0.0 +1995,Wal,112,F,0.0,0.0 +1995,Wal,113,M,0.0,0.0 +1995,Wal,113,F,0.0,0.0 +1995,Wal,114,M,0.0,0.0 +1995,Wal,114,F,0.0,0.0 +1995,Wal,115,M,0.0,0.0 +1995,Wal,115,F,0.0,0.0 +1995,Wal,116,M,0.0,0.0 +1995,Wal,116,F,0.0,0.0 +1995,Wal,117,M,0.0,0.0 +1995,Wal,117,F,0.0,0.0 +1995,Wal,118,M,0.0,0.0 +1995,Wal,118,F,0.0,0.0 +1995,Wal,119,M,0.0,0.0 +1995,Wal,119,F,0.0,0.0 +1995,Wal,120,M,0.0,0.0 +1995,Wal,120,F,0.0,0.0 +1996,BruCap,0,M,0.0006978367062107465,0.000963855421686747 +1996,BruCap,0,F,0.00023775558725630053,0.001644736842105263 +1996,BruCap,1,M,0.0,0.0 +1996,BruCap,1,F,0.0005157297576070137,0.0005224660397074192 +1996,BruCap,2,M,0.0002432498175626369,0.0 +1996,BruCap,2,F,0.0005134788189987163,0.0 +1996,BruCap,3,M,0.00024813895781637717,0.0004940711462450593 +1996,BruCap,3,F,0.0,0.0005165289256198346 +1996,BruCap,4,M,0.0,0.0 +1996,BruCap,4,F,0.00026364355391510685,0.0 +1996,BruCap,5,M,0.0005167958656330749,0.0 +1996,BruCap,5,F,0.0005389382915656157,0.0005241090146750523 +1996,BruCap,6,M,0.0002724053391446473,0.0 +1996,BruCap,6,F,0.0002777006387114691,0.0005227391531625719 +1996,BruCap,7,M,0.0005425935973955506,0.0005149330587023687 +1996,BruCap,7,F,0.0,0.0 +1996,BruCap,8,M,0.0002790957298353336,0.0 +1996,BruCap,8,F,0.0,0.0 +1996,BruCap,9,M,0.0005787037037037037,0.0 +1996,BruCap,9,F,0.0,0.0005672149744753263 +1996,BruCap,10,M,0.0,0.0 +1996,BruCap,10,F,0.0009705596894208996,0.0 +1996,BruCap,11,M,0.0,0.0005672149744753263 +1996,BruCap,11,F,0.00030562347188264064,0.0 +1996,BruCap,12,M,0.0,0.0 +1996,BruCap,12,F,0.0,0.0 +1996,BruCap,13,M,0.0002891844997108155,0.0016181229773462786 +1996,BruCap,13,F,0.0,0.0 +1996,BruCap,14,M,0.00029078220412910734,0.0 +1996,BruCap,14,F,0.0003066544004906471,0.001029336078229542 +1996,BruCap,15,M,0.0006161429451632777,0.00046511627906976747 +1996,BruCap,15,F,0.0009413241292751805,0.0 +1996,BruCap,16,M,0.0003166561114629513,0.00135623869801085 +1996,BruCap,16,F,0.0,0.0009385265133740028 +1996,BruCap,17,M,0.0003279763857002296,0.001403180542563143 +1996,BruCap,17,F,0.0006482982171799027,0.0004444444444444445 +1996,BruCap,18,M,0.0011820330969267141,0.0005390835579514825 +1996,BruCap,18,F,0.0005973715651135006,0.0 +1996,BruCap,19,M,0.001130901894260673,0.001095290251916758 +1996,BruCap,19,F,0.00027894002789400284,0.0 +1996,BruCap,20,M,0.0016103059581320447,0.0005534034311012729 +1996,BruCap,20,F,0.0002671653753673524,0.001025641025641026 +1996,BruCap,21,M,0.000812787862367922,0.00236630383341221 +1996,BruCap,21,F,0.0002621919244887258,0.00045787545787545793 +1996,BruCap,22,M,0.001479289940828403,0.0009074410163339383 +1996,BruCap,22,F,0.0002358490566037736,0.0008396305625524769 +1996,BruCap,23,M,0.0006976744186046513,0.0003927729772191674 +1996,BruCap,23,F,0.00021767522855898998,0.0007476635514018691 +1996,BruCap,24,M,0.0008552490912978406,0.0003631082062454612 +1996,BruCap,24,F,0.000407000407000407,0.0 +1996,BruCap,25,M,0.0004194630872483222,0.0003302509907529723 +1996,BruCap,25,F,0.0001956947162426615,0.0 +1996,BruCap,26,M,0.001431200163565733,0.0009319664492078283 +1996,BruCap,26,F,0.0005950019833399446,0.0003174603174603174 +1996,BruCap,27,M,0.001214574898785425,0.0006053268765133173 +1996,BruCap,27,F,0.0008075913587724611,0.0006383657835939994 +1996,BruCap,28,M,0.0008,0.000906344410876133 +1996,BruCap,28,F,0.0010191602119853241,0.0006426735218508997 +1996,BruCap,29,M,0.0006207324643078832,0.0002782415136338342 +1996,BruCap,29,F,0.00041160732661041366,0.0012303906490310679 +1996,BruCap,30,M,0.0022226712467165077,0.0008368200836820082 +1996,BruCap,30,F,0.0004133939644481192,0.0006075334143377885 +1996,BruCap,31,M,0.002065688907250568,0.001094990418833835 +1996,BruCap,31,F,0.001047998323202683,0.000299043062200957 +1996,BruCap,32,M,0.0012774111134766868,0.0005896226415094339 +1996,BruCap,32,F,0.001280956447480786,0.0009813542688910696 +1996,BruCap,33,M,0.002279462046956919,0.0 +1996,BruCap,33,F,0.0008930564858227283,0.001352722353736896 +1996,BruCap,34,M,0.002066115702479339,0.0012828736369467607 +1996,BruCap,34,F,0.0006554511688879179,0.0003498950314905528 +1996,BruCap,35,M,0.001591270743350762,0.0009640102827763496 +1996,BruCap,35,F,0.002617801047120419,0.00034578146611341634 +1996,BruCap,36,M,0.0011125945705384964,0.0021390374331550803 +1996,BruCap,36,F,0.001332445036642239,0.0003819709702062643 +1996,BruCap,37,M,0.0019011406844106468,0.001818181818181818 +1996,BruCap,37,F,0.00044130626654898496,0.001198561725928885 +1996,BruCap,38,M,0.001648222274546739,0.0008019246190858058 +1996,BruCap,38,F,0.001114827201783724,0.001267962806424345 +1996,BruCap,39,M,0.00535410075444147,0.0023264831329972853 +1996,BruCap,39,F,0.002936525864016264,0.0008413967185527978 +1996,BruCap,40,M,0.00341796875,0.002842062525375559 +1996,BruCap,40,F,0.0018034265103697032,0.0008658008658008657 +1996,BruCap,41,M,0.002915451895043732,0.001751313485113836 +1996,BruCap,41,F,0.002540415704387991,0.0013818516812528787 +1996,BruCap,42,M,0.003122748018256066,0.002299908003679853 +1996,BruCap,42,F,0.001570915619389587,0.0009910802775024775 +1996,BruCap,43,M,0.002844950213371266,0.001357466063348416 +1996,BruCap,43,F,0.002264492753623189,0.001497005988023952 +1996,BruCap,44,M,0.005200594353640416,0.0015274949083503061 +1996,BruCap,44,F,0.001359927470534905,0.001138952164009112 +1996,BruCap,45,M,0.004285354171918326,0.00238208670795617 +1996,BruCap,45,F,0.002229157378510923,0.0010520778537611779 +1996,BruCap,46,M,0.003746253746253747,0.003224073078989791 +1996,BruCap,46,F,0.0026578073089701,0.0006142506142506142 +1996,BruCap,47,M,0.0048285852245292145,0.002173913043478261 +1996,BruCap,47,F,0.003303237172428981,0.001225490196078432 +1996,BruCap,48,M,0.006949436855978912,0.002207505518763797 +1996,BruCap,48,F,0.0025167785234899327,0.0013080444735121 +1996,BruCap,49,M,0.006060606060606061,0.00655933214072749 +1996,BruCap,49,F,0.004502572898799315,0.002659574468085107 +1996,BruCap,50,M,0.006186726659167604,0.0025957170668397147 +1996,BruCap,50,F,0.0034756703078450838,0.0007347538574577517 +1996,BruCap,51,M,0.00936830835117773,0.0050536955148452285 +1996,BruCap,51,F,0.003464203233256351,0.00364963503649635 +1996,BruCap,52,M,0.01122058018609743,0.0014194464158978 +1996,BruCap,52,F,0.003166869671132765,0.002390438247011952 +1996,BruCap,53,M,0.005812076202776882,0.0047393364928909965 +1996,BruCap,53,F,0.00480090369951991,0.002454991816693945 +1996,BruCap,54,M,0.0108499095840868,0.006344171292624901 +1996,BruCap,54,F,0.0059430716296528,0.00185356811862836 +1996,BruCap,55,M,0.01298279779292438,0.007051282051282051 +1996,BruCap,55,F,0.004890678941311853,0.003652300949598247 +1996,BruCap,56,M,0.01134621281815394,0.005767844268204758 +1996,BruCap,56,F,0.005964730290456431,0.001715265866209263 +1996,BruCap,57,M,0.01305970149253731,0.007241129616220129 +1996,BruCap,57,F,0.0071485305798252565,0.002737226277372263 +1996,BruCap,58,M,0.015649452269170583,0.006928406466512702 +1996,BruCap,58,F,0.005857294994675187,0.004725897920604915 +1996,BruCap,59,M,0.01356589147286822,0.004615384615384616 +1996,BruCap,59,F,0.006974248927038627,0.003690036900369004 +1996,BruCap,60,M,0.016763378465506133,0.006071118820468344 +1996,BruCap,60,F,0.008923884514435695,0.0057971014492753615 +1996,BruCap,61,M,0.01685565430585351,0.01234567901234568 +1996,BruCap,61,F,0.01045751633986928,0.004419889502762432 +1996,BruCap,62,M,0.01762114537444934,0.011787819253438121 +1996,BruCap,62,F,0.0060105184072126215,0.005025125628140704 +1996,BruCap,63,M,0.01818181818181818,0.017061611374407582 +1996,BruCap,63,F,0.010613207547169807,0.0036764705882352936 +1996,BruCap,64,M,0.020378457059679767,0.01598173515981735 +1996,BruCap,64,F,0.01076993583868011,0.004059539918809202 +1996,BruCap,65,M,0.02812687013764213,0.01800847457627119 +1996,BruCap,65,F,0.01162544916508138,0.005 +1996,BruCap,66,M,0.02962048750385684,0.01395939086294416 +1996,BruCap,66,F,0.01161751563896336,0.0132890365448505 +1996,BruCap,67,M,0.03293321021852878,0.035561877667140834 +1996,BruCap,67,F,0.015346422929361319,0.012678288431061807 +1996,BruCap,68,M,0.03098051740657937,0.02283849918433932 +1996,BruCap,68,F,0.01217083425536623,0.01111111111111111 +1996,BruCap,69,M,0.0283375314861461,0.01909722222222223 +1996,BruCap,69,F,0.01325636091511653,0.01734104046242775 +1996,BruCap,70,M,0.034568670196200565,0.03047619047619048 +1996,BruCap,70,F,0.0180986061992927,0.02494802494802495 +1996,BruCap,71,M,0.04131227217496963,0.04400977995110025 +1996,BruCap,71,F,0.01776597917092097,0.024229074889867842 +1996,BruCap,72,M,0.04234001292824823,0.02758620689655173 +1996,BruCap,72,F,0.02133122654552637,0.01190476190476191 +1996,BruCap,73,M,0.04484451718494272,0.03571428571428571 +1996,BruCap,73,F,0.02085004009623096,0.028571428571428567 +1996,BruCap,74,M,0.05010893246187364,0.05747126436781608 +1996,BruCap,74,F,0.02822422579380635,0.02719033232628399 +1996,BruCap,75,M,0.07028647568287807,0.06168831168831169 +1996,BruCap,75,F,0.02708454246469337,0.02205882352941177 +1996,BruCap,76,M,0.0497716894977169,0.05027932960893855 +1996,BruCap,76,F,0.03193832599118943,0.03501945525291829 +1996,BruCap,77,M,0.0690172543135784,0.046357615894039736 +1996,BruCap,77,F,0.03494926719278467,0.04188481675392671 +1996,BruCap,78,M,0.07292474786656322,0.0364963503649635 +1996,BruCap,78,F,0.03442879499217527,0.05641025641025641 +1996,BruCap,79,M,0.08762490392006149,0.047619047619047616 +1996,BruCap,79,F,0.04064445258147199,0.07142857142857142 +1996,BruCap,80,M,0.07463672391017173,0.036036036036036036 +1996,BruCap,80,F,0.05431409062693979,0.0446927374301676 +1996,BruCap,81,M,0.08860759493670886,0.1007751937984496 +1996,BruCap,81,F,0.054746494066882416,0.036842105263157884 +1996,BruCap,82,M,0.09727891156462586,0.1415094339622642 +1996,BruCap,82,F,0.06087969705796679,0.03846153846153847 +1996,BruCap,83,M,0.107728337236534,0.08536585365853659 +1996,BruCap,83,F,0.07105181507911883,0.054054054054054064 +1996,BruCap,84,M,0.1300738007380074,0.07317073170731707 +1996,BruCap,84,F,0.0804037591367908,0.1076923076923077 +1996,BruCap,85,M,0.1326086956521739,0.1447368421052632 +1996,BruCap,85,F,0.08217168011738811,0.06578947368421052 +1996,BruCap,86,M,0.1474103585657371,0.2127659574468085 +1996,BruCap,86,F,0.09442248572683357,0.08333333333333333 +1996,BruCap,87,M,0.1524390243902439,0.1666666666666667 +1996,BruCap,87,F,0.123300515705579,0.1063829787234043 +1996,BruCap,88,M,0.1524752475247525,0.1521739130434783 +1996,BruCap,88,F,0.131434830230011,0.1505376344086022 +1996,BruCap,89,M,0.2034739454094293,0.3 +1996,BruCap,89,F,0.1374249499666444,0.1139240506329114 +1996,BruCap,90,M,0.1633986928104575,0.2173913043478261 +1996,BruCap,90,F,0.1513002364066194,0.16 +1996,BruCap,91,M,0.2239382239382239,0.2173913043478261 +1996,BruCap,91,F,0.1771037181996086,0.1454545454545455 +1996,BruCap,92,M,0.2736842105263158,0.0 +1996,BruCap,92,F,0.1937106918238994,0.1111111111111111 +1996,BruCap,93,M,0.3172413793103449,0.1 +1996,BruCap,93,F,0.2138643067846608,0.1212121212121212 +1996,BruCap,94,M,0.31,0.3333333333333333 +1996,BruCap,94,F,0.1822033898305085,0.1 +1996,BruCap,95,M,0.3392857142857143,0.1666666666666667 +1996,BruCap,95,F,0.2283950617283951,0.3043478260869566 +1996,BruCap,96,M,0.2631578947368421,0.25 +1996,BruCap,96,F,0.2800000000000001,0.1428571428571429 +1996,BruCap,97,M,0.2666666666666667,0.0 +1996,BruCap,97,F,0.2236842105263158,0.05882352941176471 +1996,BruCap,98,M,0.3846153846153847,0.0 +1996,BruCap,98,F,0.3152173913043479,0.0 +1996,BruCap,99,M,0.3076923076923077,0.0 +1996,BruCap,99,F,0.2972972972972973,0.1666666666666667 +1996,BruCap,100,M,0.3333333333333333,0.0 +1996,BruCap,100,F,0.4576271186440678,0.0 +1996,BruCap,101,M,0.25,0.0 +1996,BruCap,101,F,0.44,0.0 +1996,BruCap,102,M,0.3333333333333333,0.0 +1996,BruCap,102,F,0.2941176470588236,0.5 +1996,BruCap,103,M,1.0,0.0 +1996,BruCap,103,F,0.4545454545454545,0.0 +1996,BruCap,104,M,0.0,0.0 +1996,BruCap,104,F,0.6,0.0 +1996,BruCap,105,M,0.0,0.0 +1996,BruCap,105,F,0.0,0.0 +1996,BruCap,106,M,0.0,0.0 +1996,BruCap,106,F,0.5,0.0 +1996,BruCap,107,M,0.0,0.0 +1996,BruCap,107,F,0.0,0.0 +1996,BruCap,108,M,0.0,0.0 +1996,BruCap,108,F,0.0,0.0 +1996,BruCap,109,M,0.0,0.0 +1996,BruCap,109,F,0.0,0.0 +1996,BruCap,110,M,0.0,0.0 +1996,BruCap,110,F,0.0,0.0 +1996,BruCap,111,M,0.0,0.0 +1996,BruCap,111,F,0.0,0.5 +1996,BruCap,112,M,0.0,0.0 +1996,BruCap,112,F,0.0,0.0 +1996,BruCap,113,M,0.0,0.0 +1996,BruCap,113,F,0.0,0.0 +1996,BruCap,114,M,0.0,0.0 +1996,BruCap,114,F,0.0,0.0 +1996,BruCap,115,M,0.0,0.0 +1996,BruCap,115,F,0.0,0.0 +1996,BruCap,116,M,0.0,0.0 +1996,BruCap,116,F,0.0,0.0 +1996,BruCap,117,M,0.0,0.0 +1996,BruCap,117,F,0.0,0.0 +1996,BruCap,118,M,0.0,0.0 +1996,BruCap,118,F,0.0,0.0 +1996,BruCap,119,M,0.0,0.0 +1996,BruCap,119,F,0.0,0.0 +1996,BruCap,120,M,0.0,0.0 +1996,BruCap,120,F,0.0,0.0 +1996,Fla,0,M,0.001513102826604855,0.0005414185165132649 +1996,Fla,0,F,0.0007420899952776093,0.002791736460078169 +1996,Fla,1,M,0.000476069569633109,0.0009940357852882703 +1996,Fla,1,F,0.0003657887736100027,0.0 +1996,Fla,2,M,0.0002123271050715846,0.0005055611729019212 +1996,Fla,2,F,0.0001253172091857514,0.0 +1996,Fla,3,M,0.0002915706913141092,0.001003009027081244 +1996,Fla,3,F,6.104447089704848e-05,0.0 +1996,Fla,4,M,5.7573838447809316e-05,0.0 +1996,Fla,4,F,0.0001819505094614265,0.0005102040816326531 +1996,Fla,5,M,0.00017444903180787352,0.0005030181086519115 +1996,Fla,5,F,9.170105456212746e-05,0.0 +1996,Fla,6,M,0.00015005552054260082,0.001008064516129032 +1996,Fla,6,F,0.0,0.0005293806246691371 +1996,Fla,7,M,0.0002126754572522331,0.0 +1996,Fla,7,F,9.541681244235236e-05,0.0005249343832020997 +1996,Fla,8,M,0.0001836715951878042,0.0005189413596263622 +1996,Fla,8,F,0.0,0.0 +1996,Fla,9,M,9.142439202779301e-05,0.0 +1996,Fla,9,F,0.0001614622016985824,0.0 +1996,Fla,10,M,9.409108016560028e-05,0.0 +1996,Fla,10,F,9.853187506158242e-05,0.001121704991587213 +1996,Fla,11,M,0.0002139364303178484,0.0005506607929515419 +1996,Fla,11,F,0.0001285181853232232,0.0005675368898978432 +1996,Fla,12,M,0.0001182627206338882,0.0 +1996,Fla,12,F,0.00012360175514492306,0.0005910165484633572 +1996,Fla,13,M,0.00020216022641945358,0.0 +1996,Fla,13,F,0.00024464831804281347,0.0 +1996,Fla,14,M,0.0003079076277116865,0.0005081300813008131 +1996,Fla,14,F,0.00014960205852432531,0.0 +1996,Fla,15,M,0.000370085689071085,0.0 +1996,Fla,15,F,0.0002666824700723006,0.0 +1996,Fla,16,M,0.0006458859870822803,0.0004462293618920125 +1996,Fla,16,F,0.00035916314986082434,0.0009372071227741332 +1996,Fla,17,M,0.001006122976974157,0.000473260766682442 +1996,Fla,17,F,0.0002102291497732528,0.0 +1996,Fla,18,M,0.0008106308445036334,0.001147446930579461 +1996,Fla,18,F,0.0004208627686757853,0.0 +1996,Fla,19,M,0.0009967459177391458,0.0006297229219143577 +1996,Fla,19,F,0.0004319521150226775,0.0 +1996,Fla,20,M,0.0014125142754102301,0.001828153564899452 +1996,Fla,20,F,0.0003168467412312665,0.0 +1996,Fla,21,M,0.001448435689455388,0.0 +1996,Fla,21,F,0.0003937604119339694,0.0009195402298850574 +1996,Fla,22,M,0.001283768698370172,0.0004844961240310077 +1996,Fla,22,F,0.0002047142773586009,0.0 +1996,Fla,23,M,0.001097342290501298,0.002214348981399469 +1996,Fla,23,F,0.0002509340322310824,0.0003968253968253969 +1996,Fla,24,M,0.001161110537723191,0.0003865481252415926 +1996,Fla,24,F,0.0003715794781962471,0.0003711952487008166 +1996,Fla,25,M,0.0008770830722967048,0.0018268176835951767 +1996,Fla,25,F,0.0003401627547949865,0.0 +1996,Fla,26,M,0.000929881879869314,0.000671591672263264 +1996,Fla,26,F,0.0005226162167812069,0.001404494382022472 +1996,Fla,27,M,0.001317555809675335,0.001366586949094636 +1996,Fla,27,F,0.00041338328381346077,0.0 +1996,Fla,28,M,0.001196802144669443,0.0006896551724137933 +1996,Fla,28,F,0.0004027588984544127,0.0007513148009015777 +1996,Fla,29,M,0.001023874901102992,0.001226241569589209 +1996,Fla,29,F,0.0004333694474539545,0.0 +1996,Fla,30,M,0.0013899787019392446,0.002143294549908145 +1996,Fla,30,F,0.00032704167445337317,0.000353356890459364 +1996,Fla,31,M,0.0009914861515249488,0.001455604075691412 +1996,Fla,31,F,0.0003104419362707054,0.001024940211820977 +1996,Fla,32,M,0.001231181286044452,0.001234949058351343 +1996,Fla,32,F,0.0006255864873318738,0.0007275372862859223 +1996,Fla,33,M,0.001201319266976826,0.001190830604346532 +1996,Fla,33,F,0.0004291651608239971,0.00038431975403535736 +1996,Fla,34,M,0.001117196056955093,0.0009596928982725527 +1996,Fla,34,F,0.0007389162561576355,0.0004078303425774878 +1996,Fla,35,M,0.0009639526542324248,0.002761583307763118 +1996,Fla,35,F,0.0008056719303899452,0.0003849114703618168 +1996,Fla,36,M,0.001512925647378692,0.0006903693476009665 +1996,Fla,36,F,0.0005849795257165999,0.0 +1996,Fla,37,M,0.001137225170583776,0.0009986684420772304 +1996,Fla,37,F,0.0007632351920808568,0.0004334633723450369 +1996,Fla,38,M,0.001714298603748901,0.001432664756446992 +1996,Fla,38,F,0.0009582797709477619,0.0004914004914004914 +1996,Fla,39,M,0.001605584642233857,0.00215594681997844 +1996,Fla,39,F,0.0010435442557632099,0.0009345794392523364 +1996,Fla,40,M,0.0017166776408616313,0.001470588235294118 +1996,Fla,40,F,0.0009323229184097918,0.0020639834881320948 +1996,Fla,41,M,0.002152080344332855,0.001160092807424594 +1996,Fla,41,F,0.0014713094654242279,0.001569858712715856 +1996,Fla,42,M,0.00234140630716324,0.001735357917570499 +1996,Fla,42,F,0.001264734152881065,0.0005668934240362813 +1996,Fla,43,M,0.002564227801113608,0.0008431703204047218 +1996,Fla,43,F,0.001829640170766416,0.002958579881656805 +1996,Fla,44,M,0.002660935421144202,0.002232142857142857 +1996,Fla,44,F,0.0017150848307343196,0.0 +1996,Fla,45,M,0.002674838341080843,0.0020973154362416107 +1996,Fla,45,F,0.00219414190546685,0.001233806292412092 +1996,Fla,46,M,0.003037010346425079,0.00211595429538722 +1996,Fla,46,F,0.001968294499414831,0.00121580547112462 +1996,Fla,47,M,0.00297004132231405,0.003963011889035667 +1996,Fla,47,F,0.002410964647920543,0.0 +1996,Fla,48,M,0.004276605671038309,0.002726033621081327 +1996,Fla,48,F,0.0025971960883046674,0.003255208333333334 +1996,Fla,49,M,0.004193401707674432,0.003215434083601286 +1996,Fla,49,F,0.0026881018868909357,0.0028653295128939827 +1996,Fla,50,M,0.004802910165686191,0.004257583821181479 +1996,Fla,50,F,0.003059251349245289,0.0015455950540958269 +1996,Fla,51,M,0.00545979475745362,0.009279475982532752 +1996,Fla,51,F,0.003051881993896236,0.002207505518763797 +1996,Fla,52,M,0.0061312995364139365,0.003865267807840972 +1996,Fla,52,F,0.003240067829457365,0.0008090614886731393 +1996,Fla,53,M,0.006206494530741007,0.005913660555884093 +1996,Fla,53,F,0.002918896379178539,0.002425222312045271 +1996,Fla,54,M,0.006150672371638142,0.004730928444707274 +1996,Fla,54,F,0.003697136605424982,0.005439709882139618 +1996,Fla,55,M,0.007059800664451828,0.0078125 +1996,Fla,55,F,0.003942359978249048,0.003048780487804878 +1996,Fla,56,M,0.007901640380543001,0.008244994110718492 +1996,Fla,56,F,0.004181818181818182,0.005494505494505495 +1996,Fla,57,M,0.007787448465414567,0.005504587155963303 +1996,Fla,57,F,0.004136043086261791,0.0036231884057971024 +1996,Fla,58,M,0.008693461005417664,0.009986684420772305 +1996,Fla,58,F,0.0042802155504234034,0.001958863858961802 +1996,Fla,59,M,0.009815750856024784,0.008990318118948824 +1996,Fla,59,F,0.005502923428071163,0.003167898627243929 +1996,Fla,60,M,0.01220469864537661,0.008088235294117648 +1996,Fla,60,F,0.00588308924771561,0.007838745800671894 +1996,Fla,61,M,0.012646645534459659,0.01131221719457014 +1996,Fla,61,F,0.005607476635514018,0.0021598272138228947 +1996,Fla,62,M,0.01562754885648103,0.008513931888544891 +1996,Fla,62,F,0.006644518272425249,0.005656108597285068 +1996,Fla,63,M,0.015269134535189582,0.018668831168831168 +1996,Fla,63,F,0.006690639000235793,0.007334963325183373 +1996,Fla,64,M,0.0179816632231405,0.0136986301369863 +1996,Fla,64,F,0.007513922857058667,0.002976190476190476 +1996,Fla,65,M,0.019095444183818432,0.022522522522522518 +1996,Fla,65,F,0.009302325581395349,0.0038119440914866592 +1996,Fla,66,M,0.0218661504821307,0.0148619957537155 +1996,Fla,66,F,0.0098116790631429,0.00583941605839416 +1996,Fla,67,M,0.02344041141834986,0.01779755283648498 +1996,Fla,67,F,0.01118008385062888,0.01017441860465116 +1996,Fla,68,M,0.027465280471720067,0.02521008403361345 +1996,Fla,68,F,0.01156868697089278,0.008237232289950576 +1996,Fla,69,M,0.0301696542893726,0.03137254901960785 +1996,Fla,69,F,0.01376238282029121,0.009478672985781993 +1996,Fla,70,M,0.03399846197433926,0.043478260869565216 +1996,Fla,70,F,0.014791800344466581,0.011608623548922059 +1996,Fla,71,M,0.03589656345695815,0.03389830508474577 +1996,Fla,71,F,0.01718485800062114,0.029520295202952032 +1996,Fla,72,M,0.04,0.03851851851851852 +1996,Fla,72,F,0.02102102102102102,0.02367941712204008 +1996,Fla,73,M,0.04740439144976007,0.0297723292469352 +1996,Fla,73,F,0.02267245537867825,0.030060120240480964 +1996,Fla,74,M,0.04995182311476242,0.05087719298245614 +1996,Fla,74,F,0.02510790016888722,0.0211864406779661 +1996,Fla,75,M,0.054721030042918464,0.04592901878914405 +1996,Fla,75,F,0.02868788819875777,0.024774774774774785 +1996,Fla,76,M,0.060408581679724675,0.061281337047353765 +1996,Fla,76,F,0.03282684229632319,0.04844290657439446 +1996,Fla,77,M,0.07386694628917627,0.09558823529411764 +1996,Fla,77,F,0.03613451757382525,0.05078125 +1996,Fla,78,M,0.07754381540789307,0.056224899598393566 +1996,Fla,78,F,0.03912633563796355,0.04444444444444445 +1996,Fla,79,M,0.08565483759102993,0.1008771929824561 +1996,Fla,79,F,0.049069617070191834,0.07659574468085106 +1996,Fla,80,M,0.09071207430340557,0.1126760563380282 +1996,Fla,80,F,0.05640007445554384,0.04680851063829787 +1996,Fla,81,M,0.09987844408427876,0.1225490196078432 +1996,Fla,81,F,0.0641061688129112,0.034934497816593885 +1996,Fla,82,M,0.1117941712204007,0.1052631578947368 +1996,Fla,82,F,0.06528491219687015,0.047619047619047616 +1996,Fla,83,M,0.1241476907243021,0.1180555555555556 +1996,Fla,83,F,0.08139459107201043,0.060606060606060615 +1996,Fla,84,M,0.1351522842639594,0.1181102362204725 +1996,Fla,84,F,0.09016393442622953,0.09433962264150944 +1996,Fla,85,M,0.14553651938683498,0.1518987341772152 +1996,Fla,85,F,0.100041135335253,0.09420289855072464 +1996,Fla,86,M,0.1684973637961336,0.1529411764705883 +1996,Fla,86,F,0.1164719185827365,0.1169590643274854 +1996,Fla,87,M,0.1716479298053194,0.1714285714285714 +1996,Fla,87,F,0.1363828438622438,0.1467889908256881 +1996,Fla,88,M,0.1946176567115196,0.2173913043478261 +1996,Fla,88,F,0.1407613507019097,0.1505376344086022 +1996,Fla,89,M,0.2133450395083407,0.2083333333333334 +1996,Fla,89,F,0.1542544886807182,0.1923076923076923 +1996,Fla,90,M,0.2178329571106095,0.2777777777777778 +1996,Fla,90,F,0.1741228884351216,0.1481481481481482 +1996,Fla,91,M,0.2450765864332604,0.1153846153846154 +1996,Fla,91,F,0.194793119479312,0.1842105263157895 +1996,Fla,92,M,0.282025819265144,0.0 +1996,Fla,92,F,0.2130627774254914,0.09090909090909093 +1996,Fla,93,M,0.2782874617737003,0.0 +1996,Fla,93,F,0.2362076011442583,0.07692307692307693 +1996,Fla,94,M,0.3292433537832311,0.2 +1996,Fla,94,F,0.2628382109331861,0.06896551724137931 +1996,Fla,95,M,0.3278145695364239,0.2222222222222222 +1996,Fla,95,F,0.262617621899059,0.1875 +1996,Fla,96,M,0.3278688524590164,0.7142857142857143 +1996,Fla,96,F,0.2884130982367758,0.2857142857142857 +1996,Fla,97,M,0.4274193548387097,0.3333333333333333 +1996,Fla,97,F,0.275,0.3333333333333333 +1996,Fla,98,M,0.3170731707317073,0.0 +1996,Fla,98,F,0.3228571428571429,0.6666666666666666 +1996,Fla,99,M,0.4107142857142857,0.0 +1996,Fla,99,F,0.3106382978723405,0.3333333333333333 +1996,Fla,100,M,0.3928571428571429,1.0 +1996,Fla,100,F,0.3227848101265823,1.0 +1996,Fla,101,M,0.4705882352941176,0.0 +1996,Fla,101,F,0.4415584415584416,1.0 +1996,Fla,102,M,0.5555555555555556,0.5 +1996,Fla,102,F,0.38095238095238093,0.0 +1996,Fla,103,M,0.6666666666666666,0.0 +1996,Fla,103,F,0.5263157894736842,0.0 +1996,Fla,104,M,0.0,1.0 +1996,Fla,104,F,0.4,1.0 +1996,Fla,105,M,0.0,0.0 +1996,Fla,105,F,0.0,0.0 +1996,Fla,106,M,0.0,0.0 +1996,Fla,106,F,0.0,0.0 +1996,Fla,107,M,0.0,0.0 +1996,Fla,107,F,0.0,0.0 +1996,Fla,108,M,0.0,0.0 +1996,Fla,108,F,0.0,0.0 +1996,Fla,109,M,0.0,0.0 +1996,Fla,109,F,0.0,0.0 +1996,Fla,110,M,0.0,0.0 +1996,Fla,110,F,0.0,0.0 +1996,Fla,111,M,0.0,0.0 +1996,Fla,111,F,0.0,0.0 +1996,Fla,112,M,0.0,0.0 +1996,Fla,112,F,0.0,0.0 +1996,Fla,113,M,0.0,0.0 +1996,Fla,113,F,0.0,0.0 +1996,Fla,114,M,0.0,0.0 +1996,Fla,114,F,0.0,0.0 +1996,Fla,115,M,0.0,0.0 +1996,Fla,115,F,0.0,0.0 +1996,Fla,116,M,0.0,0.0 +1996,Fla,116,F,0.0,0.0 +1996,Fla,117,M,0.0,0.0 +1996,Fla,117,F,0.0,0.0 +1996,Fla,118,M,0.0,0.0 +1996,Fla,118,F,0.0,0.0 +1996,Fla,119,M,0.0,0.0 +1996,Fla,119,F,0.0,0.0 +1996,Fla,120,M,0.0,0.0 +1996,Fla,120,F,0.0,0.0 +1996,Wal,0,M,0.0009874375994294807,0.0 +1996,Wal,0,F,0.001146066128015587,0.0 +1996,Wal,1,M,0.0001083775875149019,0.0016863406408094439 +1996,Wal,1,F,0.00033977008890650665,0.0 +1996,Wal,2,M,0.0002569373072970196,0.000819672131147541 +1996,Wal,2,F,0.000327725584443959,0.0 +1996,Wal,3,M,0.00019556077050943583,0.0 +1996,Wal,3,F,5.1211143544835355e-05,0.0007727975270479134 +1996,Wal,4,M,0.00018987041344282533,0.0 +1996,Wal,4,F,0.0001481627815092849,0.0 +1996,Wal,5,M,0.000336829948994322,0.0 +1996,Wal,5,F,0.0,0.0 +1996,Wal,6,M,9.585430146177807e-05,0.0 +1996,Wal,6,F,0.0001510117789187557,0.0007002801120448178 +1996,Wal,7,M,0.0,0.000655307994757536 +1996,Wal,7,F,0.00020361415118350733,0.0 +1996,Wal,8,M,0.000250752256770311,0.0 +1996,Wal,8,F,0.00010526869835254492,0.0006775067750677508 +1996,Wal,9,M,0.0003004055474891103,0.0012730744748567788 +1996,Wal,9,F,0.00037023324694557584,0.0 +1996,Wal,10,M,0.0002083224832039998,0.0 +1996,Wal,10,F,0.0001639433848844199,0.0 +1996,Wal,11,M,0.0001584451251716489,0.0 +1996,Wal,11,F,0.0001097273275909365,0.0 +1996,Wal,12,M,0.00047505938242280285,0.001989389920424403 +1996,Wal,12,F,0.00022747952684258417,0.0 +1996,Wal,13,M,0.000262412091949197,0.0 +1996,Wal,13,F,0.0001097092704333516,0.0 +1996,Wal,14,M,0.0004697286012526096,0.0 +1996,Wal,14,F,0.00010726736390453208,0.0 +1996,Wal,15,M,0.0007303839732888147,0.0 +1996,Wal,15,F,0.0002691065662002153,0.0 +1996,Wal,16,M,0.0005830285683998518,0.0004914004914004914 +1996,Wal,16,F,0.0004489589763735339,0.0 +1996,Wal,17,M,0.001246747614917606,0.0004604051565377533 +1996,Wal,17,F,0.0002813572674582184,0.0009905894006934127 +1996,Wal,18,M,0.001001951168064125,0.0005120327700972862 +1996,Wal,18,F,0.0003334630133940977,0.0009770395701025893 +1996,Wal,19,M,0.001196794671661984,0.001038961038961039 +1996,Wal,19,F,0.0005953347404881746,0.0005091649694501019 +1996,Wal,20,M,0.001189860320744956,0.0 +1996,Wal,20,F,0.0006446760502847322,0.0 +1996,Wal,21,M,0.0017034921589257981,0.0004248088360237893 +1996,Wal,21,F,0.00031568978217405027,0.000864304235090752 +1996,Wal,22,M,0.001696558410082405,0.0 +1996,Wal,22,F,0.00040506329113924064,0.0 +1996,Wal,23,M,0.001520623455616803,0.001020408163265306 +1996,Wal,23,F,0.0003981089823339138,0.0 +1996,Wal,24,M,0.001936337017096439,0.001645278051990787 +1996,Wal,24,F,0.0006870154087741683,0.0003528581510232886 +1996,Wal,25,M,0.001173823730803091,0.001269035532994924 +1996,Wal,25,F,0.0005591988205988511,0.0006949270326615705 +1996,Wal,26,M,0.0010423905489923562,0.0015403573629081948 +1996,Wal,26,F,0.0003575259206292456,0.0 +1996,Wal,27,M,0.0015849481057313769,0.0002986857825567503 +1996,Wal,27,F,0.0007204981730224899,0.0 +1996,Wal,28,M,0.001400840504302582,0.0 +1996,Wal,28,F,0.0006606698175534889,0.0 +1996,Wal,29,M,0.001373356876594075,0.002130492676431425 +1996,Wal,29,F,0.0004918839153959665,0.0003087372645878358 +1996,Wal,30,M,0.001412628902387343,0.002825584382224506 +1996,Wal,30,F,0.0002841985600606291,0.0 +1996,Wal,31,M,0.001676332004349402,0.000777000777000777 +1996,Wal,31,F,0.0008598841419261402,0.00030497102775236347 +1996,Wal,32,M,0.001057811709515706,0.001789823574533368 +1996,Wal,32,F,0.0006333695258776693,0.000949667616334283 +1996,Wal,33,M,0.001511001983190103,0.0007684426229508198 +1996,Wal,33,F,0.0008304115150396753,0.0006482982171799027 +1996,Wal,34,M,0.001508502468458585,0.002387267904509284 +1996,Wal,34,F,0.0009822744117515738,0.0006279434850863422 +1996,Wal,35,M,0.001791127032240287,0.001229105211406096 +1996,Wal,35,F,0.001045929968167349,0.0006622516556291393 +1996,Wal,36,M,0.0021286231884057967,0.001553599171413775 +1996,Wal,36,F,0.0007436245133633701,0.0006615944426066821 +1996,Wal,37,M,0.003038254384753487,0.002059202059202059 +1996,Wal,37,F,0.001023268229745963,0.0010152284263959394 +1996,Wal,38,M,0.002914103335029372,0.00129769011160135 +1996,Wal,38,F,0.00167466280438128,0.000708215297450425 +1996,Wal,39,M,0.00278841155064039,0.002009040683073833 +1996,Wal,39,F,0.0014594545288698349,0.001399090591115775 +1996,Wal,40,M,0.003427428952254011,0.001845018450184502 +1996,Wal,40,F,0.0016846514592724132,0.0007130124777183603 +1996,Wal,41,M,0.0034874832791897572,0.0024363833243096922 +1996,Wal,41,F,0.001605357306669113,0.001106194690265487 +1996,Wal,42,M,0.0038895740442083295,0.003414911781445646 +1996,Wal,42,F,0.001803551609322975,0.00161485668146952 +1996,Wal,43,M,0.004398967199005451,0.004101963082332259 +1996,Wal,43,F,0.002109803553846875,0.0008077544426494346 +1996,Wal,44,M,0.005726698262243286,0.0018489984591679512 +1996,Wal,44,F,0.001614588279988603,0.002976190476190476 +1996,Wal,45,M,0.004074477661439333,0.002727272727272728 +1996,Wal,45,F,0.0026794528275278532,0.001222992254382389 +1996,Wal,46,M,0.004668889947594093,0.0037902716361339225 +1996,Wal,46,F,0.002962475312705728,0.0017706949977866308 +1996,Wal,47,M,0.004733398301545314,0.004488618146841937 +1996,Wal,47,F,0.002769705775517617,0.001699957501062474 +1996,Wal,48,M,0.006337311499676195,0.0052407468064199145 +1996,Wal,48,F,0.002923575898771185,0.0032422417786012038 +1996,Wal,49,M,0.0063167893611968656,0.003139169863969306 +1996,Wal,49,F,0.003401673255493243,0.002941176470588236 +1996,Wal,50,M,0.006623360081518278,0.006129597197898424 +1996,Wal,50,F,0.00402354071582993,0.0035314891112419072 +1996,Wal,51,M,0.008343949044585987,0.005701754385964914 +1996,Wal,51,F,0.004159784669970026,0.002818489289740699 +1996,Wal,52,M,0.008659484522023728,0.008849557522123894 +1996,Wal,52,F,0.003366785367432826,0.003722084367245658 +1996,Wal,53,M,0.00970190125968234,0.009576612903225808 +1996,Wal,53,F,0.003480965782846986,0.0037759597230962866 +1996,Wal,54,M,0.010646324084164641,0.00625 +1996,Wal,54,F,0.005778541308761518,0.001348617666891436 +1996,Wal,55,M,0.009645090799487605,0.005376344086021507 +1996,Wal,55,F,0.005033205173016428,0.003376477208778841 +1996,Wal,56,M,0.01033215449691422,0.01075268817204301 +1996,Wal,56,F,0.004674963674268747,0.0022560631697687533 +1996,Wal,57,M,0.012873782439888293,0.009947643979057593 +1996,Wal,57,F,0.005851915732413453,0.003975014196479273 +1996,Wal,58,M,0.012555286060779,0.009193054136874362 +1996,Wal,58,F,0.005900091779205454,0.0037014188772362734 +1996,Wal,59,M,0.01533157276995305,0.008268733850129198 +1996,Wal,59,F,0.005883121976728984,0.00726832222895215 +1996,Wal,60,M,0.01488870691580436,0.02022352315061203 +1996,Wal,60,F,0.0062740997320436575,0.0059594755661501785 +1996,Wal,61,M,0.01633201357466064,0.022075055187637967 +1996,Wal,61,F,0.007256349305642437,0.01178550383028875 +1996,Wal,62,M,0.01858500527983105,0.0131651124520022 +1996,Wal,62,F,0.007471514849635764,0.007589025102159953 +1996,Wal,63,M,0.021447183804369614,0.01857585139318886 +1996,Wal,63,F,0.009552682759409679,0.006112469437652812 +1996,Wal,64,M,0.022175977108668792,0.019551466359977 +1996,Wal,64,F,0.009541772994563408,0.007317073170731708 +1996,Wal,65,M,0.02643404705260376,0.01638448935008193 +1996,Wal,65,F,0.01254490190660404,0.009506833036244802 +1996,Wal,66,M,0.02636959740534443,0.02199074074074074 +1996,Wal,66,F,0.01241984865114667,0.01486988847583643 +1996,Wal,67,M,0.031113695841814483,0.0375366568914956 +1996,Wal,67,F,0.01253775574172223,0.01246719160104987 +1996,Wal,68,M,0.0344441959293223,0.03539823008849558 +1996,Wal,68,F,0.01403590853266273,0.01128526645768025 +1996,Wal,69,M,0.03586691086691087,0.04020979020979022 +1996,Wal,69,F,0.01767647400860565,0.01943573667711599 +1996,Wal,70,M,0.04158964879852126,0.04507936507936508 +1996,Wal,70,F,0.018008834522595992,0.02322580645161291 +1996,Wal,71,M,0.04342211460855529,0.05059132720105125 +1996,Wal,71,F,0.02156725962097431,0.02025139664804469 +1996,Wal,72,M,0.04897084048027444,0.05833333333333333 +1996,Wal,72,F,0.02193981536985973,0.01937406855439642 +1996,Wal,73,M,0.05317247542448615,0.04545454545454546 +1996,Wal,73,F,0.02398646607455743,0.01866251944012442 +1996,Wal,74,M,0.05944505696435134,0.05425631431244153 +1996,Wal,74,F,0.030344580899010383,0.029535864978902964 +1996,Wal,75,M,0.06003159557661927,0.06914893617021277 +1996,Wal,75,F,0.03303284761669549,0.04403669724770643 +1996,Wal,76,M,0.07075812274368233,0.07889908256880734 +1996,Wal,76,F,0.03442296020116188,0.03945578231292517 +1996,Wal,77,M,0.0830939226519337,0.07766990291262135 +1996,Wal,77,F,0.03902622662818422,0.052000000000000005 +1996,Wal,78,M,0.08223928659895963,0.0980392156862745 +1996,Wal,78,F,0.047827819848545235,0.0457516339869281 +1996,Wal,79,M,0.08981202135066141,0.0668693009118541 +1996,Wal,79,F,0.05184139612472732,0.0625 +1996,Wal,80,M,0.09791894852135816,0.08823529411764706 +1996,Wal,80,F,0.05944634388441601,0.04293381037567084 +1996,Wal,81,M,0.1144248326232502,0.1159029649595687 +1996,Wal,81,F,0.06646758501107793,0.07575757575757576 +1996,Wal,82,M,0.1189867534278411,0.1111111111111111 +1996,Wal,82,F,0.07798701989573359,0.06273062730627306 +1996,Wal,83,M,0.1367614879649891,0.1254237288135593 +1996,Wal,83,F,0.08891897991424058,0.08080808080808081 +1996,Wal,84,M,0.1463498622589532,0.1875 +1996,Wal,84,F,0.09943294210734538,0.1244131455399061 +1996,Wal,85,M,0.1566874027993779,0.2013888888888889 +1996,Wal,85,F,0.1077165806081469,0.1352785145888594 +1996,Wal,86,M,0.1641127039050915,0.180952380952381 +1996,Wal,86,F,0.1161279844079909,0.1441441441441442 +1996,Wal,87,M,0.1828358208955224,0.1308411214953271 +1996,Wal,87,F,0.1360593450334721,0.1354166666666667 +1996,Wal,88,M,0.2110022607385079,0.296875 +1996,Wal,88,F,0.152092050209205,0.1666666666666667 +1996,Wal,89,M,0.2067307692307692,0.2923076923076923 +1996,Wal,89,F,0.1593130779392338,0.2072538860103627 +1996,Wal,90,M,0.2333333333333334,0.1666666666666667 +1996,Wal,90,F,0.1845841784989858,0.14375 +1996,Wal,91,M,0.2800000000000001,0.3030303030303031 +1996,Wal,91,F,0.2107371794871795,0.1846153846153846 +1996,Wal,92,M,0.2362385321100918,0.4137931034482759 +1996,Wal,92,F,0.2108879492600423,0.3012048192771085 +1996,Wal,93,M,0.2871621621621622,0.2105263157894737 +1996,Wal,93,F,0.2545322697606962,0.2111111111111111 +1996,Wal,94,M,0.3619909502262444,0.25 +1996,Wal,94,F,0.2515952597994531,0.1454545454545455 +1996,Wal,95,M,0.3880597014925373,0.1 +1996,Wal,95,F,0.2867132867132867,0.2682926829268293 +1996,Wal,96,M,0.3888888888888889,0.5 +1996,Wal,96,F,0.3253275109170306,0.3888888888888889 +1996,Wal,97,M,0.3518518518518519,0.2857142857142857 +1996,Wal,97,F,0.33993399339934005,0.25 +1996,Wal,98,M,0.3,0.2 +1996,Wal,98,F,0.26,0.06666666666666668 +1996,Wal,99,M,0.4166666666666667,1.0 +1996,Wal,99,F,0.3611111111111111,0.4444444444444444 +1996,Wal,100,M,0.125,0.0 +1996,Wal,100,F,0.3440860215053764,1.0 +1996,Wal,101,M,0.2,1.0 +1996,Wal,101,F,0.3421052631578948,0.3333333333333333 +1996,Wal,102,M,0.25,0.0 +1996,Wal,102,F,0.3043478260869566,1.0 +1996,Wal,103,M,1.0,0.0 +1996,Wal,103,F,0.4666666666666667,0.5 +1996,Wal,104,M,0.0,0.0 +1996,Wal,104,F,0.5,0.0 +1996,Wal,105,M,0.0,0.0 +1996,Wal,105,F,0.0,0.0 +1996,Wal,106,M,0.0,0.0 +1996,Wal,106,F,0.0,0.0 +1996,Wal,107,M,0.0,0.0 +1996,Wal,107,F,0.6666666666666666,0.0 +1996,Wal,108,M,0.0,0.0 +1996,Wal,108,F,0.0,0.0 +1996,Wal,109,M,0.0,0.0 +1996,Wal,109,F,0.0,0.0 +1996,Wal,110,M,0.0,0.0 +1996,Wal,110,F,0.0,0.0 +1996,Wal,111,M,0.0,0.0 +1996,Wal,111,F,0.0,0.0 +1996,Wal,112,M,0.0,0.0 +1996,Wal,112,F,0.0,0.0 +1996,Wal,113,M,0.0,0.0 +1996,Wal,113,F,0.0,0.0 +1996,Wal,114,M,0.0,0.0 +1996,Wal,114,F,0.0,0.0 +1996,Wal,115,M,0.0,0.0 +1996,Wal,115,F,0.0,0.0 +1996,Wal,116,M,0.0,0.0 +1996,Wal,116,F,0.0,0.0 +1996,Wal,117,M,0.0,0.0 +1996,Wal,117,F,0.0,0.0 +1996,Wal,118,M,0.0,0.0 +1996,Wal,118,F,0.0,0.0 +1996,Wal,119,M,0.0,0.0 +1996,Wal,119,F,0.0,0.0 +1996,Wal,120,M,0.0,0.0 +1996,Wal,120,F,0.0,0.0 +1997,BruCap,0,M,0.0008988764044943821,0.0005238344683080147 +1997,BruCap,0,F,0.0020637468470534287,0.001605995717344754 +1997,BruCap,1,M,0.00023540489642184562,0.0004899559039686428 +1997,BruCap,1,F,0.0002426595486532395,0.0 +1997,BruCap,2,M,0.0002374169040835708,0.0 +1997,BruCap,2,F,0.0002646202699126753,0.0 +1997,BruCap,3,M,0.0,0.0 +1997,BruCap,3,F,0.0002618486514794449,0.0 +1997,BruCap,4,M,0.0002495632642874969,0.0 +1997,BruCap,4,F,0.0,0.0 +1997,BruCap,5,M,0.0002518891687657431,0.0 +1997,BruCap,5,F,0.0,0.0 +1997,BruCap,6,M,0.0005185377236193934,0.0 +1997,BruCap,6,F,0.000273000273000273,0.0 +1997,BruCap,7,M,0.0,0.0 +1997,BruCap,7,F,0.0,0.0 +1997,BruCap,8,M,0.0002698327037236913,0.001063829787234043 +1997,BruCap,8,F,0.0002888503755054882,0.0 +1997,BruCap,9,M,0.0,0.0005428881650380022 +1997,BruCap,9,F,0.0,0.0 +1997,BruCap,10,M,0.0005649717514124294,0.0 +1997,BruCap,10,F,0.0,0.0 +1997,BruCap,11,M,0.0,0.0 +1997,BruCap,11,F,0.0,0.0 +1997,BruCap,12,M,0.0,0.0 +1997,BruCap,12,F,0.0,0.0 +1997,BruCap,13,M,0.0,0.0 +1997,BruCap,13,F,0.000587026709715292,0.001278772378516624 +1997,BruCap,14,M,0.0,0.0005414185165132649 +1997,BruCap,14,F,0.0,0.0 +1997,BruCap,15,M,0.00029342723004694836,0.0 +1997,BruCap,15,F,0.0,0.0 +1997,BruCap,16,M,0.0,0.0 +1997,BruCap,16,F,0.0003104625892579944,0.0 +1997,BruCap,17,M,0.001261034047919294,0.0 +1997,BruCap,17,F,0.0,0.000925925925925926 +1997,BruCap,18,M,0.001463700234192038,0.0 +1997,BruCap,18,F,0.0002855511136493433,0.0009930486593843098 +1997,BruCap,19,M,0.0002677376171352075,0.0 +1997,BruCap,19,F,0.0,0.0005455537370430987 +1997,BruCap,20,M,0.001076136669357008,0.001637554585152839 +1997,BruCap,20,F,0.000782472613458529,0.0 +1997,BruCap,21,M,0.001031725561000774,0.001070090957731407 +1997,BruCap,21,F,0.0007672634271099745,0.0 +1997,BruCap,22,M,0.0023183925811437398,0.0009233610341643582 +1997,BruCap,22,F,0.0004965243296921549,0.0004372540445999127 +1997,BruCap,23,M,0.0011614401858304302,0.0017189514396218312 +1997,BruCap,23,F,0.0006657789613848202,0.0003872966692486445 +1997,BruCap,24,M,0.0006580390436499232,0.001103752759381898 +1997,BruCap,24,F,0.001230516817063167,0.0 +1997,BruCap,25,M,0.002240325865580448,0.001011463250168577 +1997,BruCap,25,F,0.00019421246844047391,0.0009810333551340746 +1997,BruCap,26,M,0.001807228915662651,0.0006182380216383308 +1997,BruCap,26,F,0.00038842493688094783,0.000327653997378768 +1997,BruCap,27,M,0.0022267206477732788,0.00029797377830750887 +1997,BruCap,27,F,0.0001992428770671449,0.0006066120715802245 +1997,BruCap,28,M,0.001644398766700925,0.0008751458576429405 +1997,BruCap,28,F,0.0008250825082508251,0.0 +1997,BruCap,29,M,0.001018952516812717,0.0002947244326554671 +1997,BruCap,29,F,0.0008303923603902845,0.0003161555485298767 +1997,BruCap,30,M,0.001463822668339607,0.0008250825082508251 +1997,BruCap,30,F,0.00021195421788893602,0.0003019323671497585 +1997,BruCap,31,M,0.002861230329041488,0.0005486968449931413 +1997,BruCap,31,F,0.00021235931195582927,0.0005954153021732659 +1997,BruCap,32,M,0.0025461489497135576,0.001353912808015164 +1997,BruCap,32,F,0.0008639308855291578,0.0 +1997,BruCap,33,M,0.002161227577263886,0.001482799525504152 +1997,BruCap,33,F,0.001534078457155381,0.0006495615459564793 +1997,BruCap,34,M,0.0018648018648018648,0.0014841199168892849 +1997,BruCap,34,F,0.0009138679460817912,0.001335559265442404 +1997,BruCap,35,M,0.002329916123019571,0.001286587327114828 +1997,BruCap,35,F,0.0008964589870013447,0.0003513703443429375 +1997,BruCap,36,M,0.002538071065989848,0.002556727388942154 +1997,BruCap,36,F,0.001111605157847932,0.0003466204506065858 +1997,BruCap,37,M,0.00227894257064722,0.000715307582260372 +1997,BruCap,37,F,0.0008966599417171037,0.0007595898214963919 +1997,BruCap,38,M,0.0038131553860819827,0.001118985453189108 +1997,BruCap,38,F,0.0017873100983020558,0.001196172248803828 +1997,BruCap,39,M,0.0023668639053254447,0.0016359918200409 +1997,BruCap,39,F,0.0018026137899954946,0.000429000429000429 +1997,BruCap,40,M,0.001725838264299803,0.003944773175542407 +1997,BruCap,40,F,0.0009082652134423252,0.0 +1997,BruCap,41,M,0.002938295788442703,0.002065262288310616 +1997,BruCap,41,F,0.00136394635144351,0.0008729812309035355 +1997,BruCap,42,M,0.0031645569620253173,0.002706359945872802 +1997,BruCap,42,F,0.001627906976744186,0.00138121546961326 +1997,BruCap,43,M,0.003856350927934442,0.002791996277338297 +1997,BruCap,43,F,0.001810364335822585,0.0009935419771485343 +1997,BruCap,44,M,0.005017921146953405,0.0018552875695732839 +1997,BruCap,44,F,0.002267573696145125,0.0009970089730807576 +1997,BruCap,45,M,0.004747626186906547,0.001525165226232842 +1997,BruCap,45,F,0.003186888231277032,0.0011467889908256881 +1997,BruCap,46,M,0.004580152671755725,0.003887269193391642 +1997,BruCap,46,F,0.002696629213483146,0.002126528442317916 +1997,BruCap,47,M,0.005030181086519115,0.002166847237269772 +1997,BruCap,47,F,0.002247696111485727,0.0018348623853211008 +1997,BruCap,48,M,0.00535410075444147,0.0005470459518599561 +1997,BruCap,48,F,0.002865961199294533,0.0018371096142069808 +1997,BruCap,49,M,0.005110732538330494,0.004491858506457047 +1997,BruCap,49,F,0.003581209184748261,0.0006635700066357001 +1997,BruCap,50,M,0.006375442739079103,0.0018050541516245488 +1997,BruCap,50,F,0.003254502061184639,0.0006675567423230972 +1997,BruCap,51,M,0.007092198581560284,0.007213114754098361 +1997,BruCap,51,F,0.005260521042084168,0.0021945866861741038 +1997,BruCap,52,M,0.008740781207320403,0.00193298969072165 +1997,BruCap,52,F,0.005602240896358543,0.0014992503748125939 +1997,BruCap,53,M,0.008087005019520357,0.0035893754486719313 +1997,BruCap,53,F,0.0064039408866995075,0.004858299595141701 +1997,BruCap,54,M,0.01301236174365648,0.003460207612456748 +1997,BruCap,54,F,0.006556442417331813,0.0008216926869350862 +1997,BruCap,55,M,0.01062271062271062,0.007293354943273906 +1997,BruCap,55,F,0.0034976152623211448,0.0009389671361502347 +1997,BruCap,56,M,0.01365756162558295,0.009138381201044385 +1997,BruCap,56,F,0.00580720092915215,0.002199413489736071 +1997,BruCap,57,M,0.0113314447592068,0.009587020648967551 +1997,BruCap,57,F,0.006594566077552097,0.003451251078515962 +1997,BruCap,58,M,0.01644528779253637,0.0029563932002956398 +1997,BruCap,58,F,0.006718624025799516,0.002795899347623486 +1997,BruCap,59,M,0.01060411311053985,0.008580343213728548 +1997,BruCap,59,F,0.007301243915630071,0.0038572806171648993 +1997,BruCap,60,M,0.01697171381031614,0.0047393364928909965 +1997,BruCap,60,F,0.008525852585258526,0.005644402634054563 +1997,BruCap,61,M,0.01633333333333333,0.009918845807033365 +1997,BruCap,61,F,0.007575757575757577,0.002958579881656805 +1997,BruCap,62,M,0.014561570117125682,0.01367365542388332 +1997,BruCap,62,F,0.007464676086376965,0.005688282138794084 +1997,BruCap,63,M,0.020732102364755436,0.01107754279959718 +1997,BruCap,63,F,0.006835443037974682,0.006385696040868455 +1997,BruCap,64,M,0.0226576852418861,0.02171767028627838 +1997,BruCap,64,F,0.009093084469968891,0.007425742574257425 +1997,BruCap,65,M,0.024390243902439032,0.016969696969696968 +1997,BruCap,65,F,0.0109864422627396,0.005471956224350204 +1997,BruCap,66,M,0.02642213242151073,0.01657458563535912 +1997,BruCap,66,F,0.01309856130556152,0.01794871794871795 +1997,BruCap,67,M,0.02712188895979579,0.02516556291390729 +1997,BruCap,67,F,0.014253393665158369,0.005050505050505051 +1997,BruCap,68,M,0.03133994243684042,0.01987767584097859 +1997,BruCap,68,F,0.01260889500229253,0.01948051948051948 +1997,BruCap,69,M,0.030142431268632006,0.028862478777589125 +1997,BruCap,69,F,0.017295597484276733,0.016885553470919332 +1997,BruCap,70,M,0.03241491085899514,0.04488330341113106 +1997,BruCap,70,F,0.0169528363399261,0.013944223107569721 +1997,BruCap,71,M,0.03509912252193695,0.03187250996015936 +1997,BruCap,71,F,0.01532893336172025,0.01731601731601732 +1997,BruCap,72,M,0.03517110266159696,0.0391644908616188 +1997,BruCap,72,F,0.015233722871452419,0.0273972602739726 +1997,BruCap,73,M,0.03921568627450981,0.06082725060827252 +1997,BruCap,73,F,0.022060311677798015,0.0215311004784689 +1997,BruCap,74,M,0.05545986910093007,0.037900874635568516 +1997,BruCap,74,F,0.02508739461237919,0.024324324324324333 +1997,BruCap,75,M,0.05650459921156373,0.02461538461538462 +1997,BruCap,75,F,0.02666666666666667,0.031055900621118005 +1997,BruCap,76,M,0.056998556998557,0.04482758620689655 +1997,BruCap,76,F,0.03003003003003003,0.030848329048843187 +1997,BruCap,77,M,0.06901544401544403,0.04093567251461988 +1997,BruCap,77,F,0.03339041095890411,0.024 +1997,BruCap,78,M,0.07033144704931285,0.08571428571428573 +1997,BruCap,78,F,0.043325526932084316,0.04444444444444445 +1997,BruCap,79,M,0.09322033898305083,0.04 +1997,BruCap,79,F,0.04597233523189585,0.04945054945054945 +1997,BruCap,80,M,0.09252971137521222,0.08823529411764706 +1997,BruCap,80,F,0.05026861089792786,0.04624277456647399 +1997,BruCap,81,M,0.1056034482758621,0.06666666666666668 +1997,BruCap,81,F,0.06264424662050774,0.08 +1997,BruCap,82,M,0.1065246338215712,0.08620689655172414 +1997,BruCap,82,F,0.06392168154333429,0.043478260869565216 +1997,BruCap,83,M,0.1182714177407127,0.07692307692307693 +1997,BruCap,83,F,0.0704666457876605,0.0898876404494382 +1997,BruCap,84,M,0.12042818911686,0.08333333333333333 +1997,BruCap,84,F,0.07894736842105263,0.09090909090909093 +1997,BruCap,85,M,0.13995726495726502,0.1690140845070423 +1997,BruCap,85,F,0.08457142857142858,0.050420168067226885 +1997,BruCap,86,M,0.1639135959339263,0.09375 +1997,BruCap,86,F,0.09521880064829824,0.0915492957746479 +1997,BruCap,87,M,0.1653543307086614,0.1111111111111111 +1997,BruCap,87,F,0.1100782778864971,0.1186440677966102 +1997,BruCap,88,M,0.1785063752276867,0.3 +1997,BruCap,88,F,0.1319632233639805,0.09090909090909093 +1997,BruCap,89,M,0.161592505854801,0.225 +1997,BruCap,89,F,0.1450577663671374,0.1447368421052632 +1997,BruCap,90,M,0.1704180064308682,0.3636363636363637 +1997,BruCap,90,F,0.1574864235841738,0.1764705882352941 +1997,BruCap,91,M,0.24,0.2666666666666667 +1997,BruCap,91,F,0.1815616180620884,0.1451612903225807 +1997,BruCap,92,M,0.2256410256410257,0.1578947368421053 +1997,BruCap,92,F,0.196642685851319,0.2444444444444445 +1997,BruCap,93,M,0.2769230769230769,0.0 +1997,BruCap,93,F,0.1943573667711599,0.04878048780487805 +1997,BruCap,94,M,0.2323232323232323,0.2222222222222222 +1997,BruCap,94,F,0.2380952380952381,0.1666666666666667 +1997,BruCap,95,M,0.2463768115942029,0.1666666666666667 +1997,BruCap,95,F,0.2637075718015666,0.1923076923076923 +1997,BruCap,96,M,0.3783783783783784,0.4 +1997,BruCap,96,F,0.2834008097165992,0.2666666666666667 +1997,BruCap,97,M,0.3928571428571429,0.3333333333333333 +1997,BruCap,97,F,0.2613636363636364,0.3333333333333333 +1997,BruCap,98,M,0.5,0.0 +1997,BruCap,98,F,0.2820512820512821,0.2 +1997,BruCap,99,M,0.125,0.0 +1997,BruCap,99,F,0.25,0.0 +1997,BruCap,100,M,0.4444444444444444,0.0 +1997,BruCap,100,F,0.4,0.0 +1997,BruCap,101,M,0.25,0.0 +1997,BruCap,101,F,0.28125,0.0 +1997,BruCap,102,M,0.0,0.0 +1997,BruCap,102,F,0.2857142857142857,0.0 +1997,BruCap,103,M,0.0,0.0 +1997,BruCap,103,F,0.1666666666666667,0.0 +1997,BruCap,104,M,0.0,0.0 +1997,BruCap,104,F,0.1666666666666667,0.0 +1997,BruCap,105,M,0.0,0.0 +1997,BruCap,105,F,0.0,0.0 +1997,BruCap,106,M,0.0,0.0 +1997,BruCap,106,F,0.0,0.0 +1997,BruCap,107,M,0.0,0.0 +1997,BruCap,107,F,0.5,0.0 +1997,BruCap,108,M,0.0,0.0 +1997,BruCap,108,F,0.0,0.0 +1997,BruCap,109,M,0.0,0.0 +1997,BruCap,109,F,0.0,0.0 +1997,BruCap,110,M,0.0,0.0 +1997,BruCap,110,F,0.0,0.0 +1997,BruCap,111,M,0.0,0.0 +1997,BruCap,111,F,0.0,0.0 +1997,BruCap,112,M,0.0,0.0 +1997,BruCap,112,F,0.0,0.0 +1997,BruCap,113,M,0.0,0.0 +1997,BruCap,113,F,0.0,0.0 +1997,BruCap,114,M,0.0,0.0 +1997,BruCap,114,F,0.0,0.0 +1997,BruCap,115,M,0.0,0.0 +1997,BruCap,115,F,0.0,0.0 +1997,BruCap,116,M,0.0,0.0 +1997,BruCap,116,F,0.0,0.0 +1997,BruCap,117,M,0.0,0.0 +1997,BruCap,117,F,0.0,0.0 +1997,BruCap,118,M,0.0,0.0 +1997,BruCap,118,F,0.0,0.0 +1997,BruCap,119,M,0.0,0.0 +1997,BruCap,119,F,0.0,0.0 +1997,BruCap,120,M,0.0,0.0 +1997,BruCap,120,F,0.0,0.0 +1997,Fla,0,M,0.0009678668215253582,0.0005688282138794084 +1997,Fla,0,F,0.001108945493648767,0.001120448179271709 +1997,Fla,1,M,0.0003841967087148621,0.0005324813631522896 +1997,Fla,1,F,0.0003015075376884424,0.0005543237250554324 +1997,Fla,2,M,0.0002842613941442153,0.0 +1997,Fla,2,F,0.00016553002714692452,0.0 +1997,Fla,3,M,0.0002115250959417399,0.001025115325474116 +1997,Fla,3,F,9.3455032553503e-05,0.0005350454788657035 +1997,Fla,4,M,0.0002618715083798883,0.001009081735620585 +1997,Fla,4,F,9.116601331023794e-05,0.0 +1997,Fla,5,M,0.00020053858935426585,0.0 +1997,Fla,5,F,0.000151153299676532,0.000508646998982706 +1997,Fla,6,M,0.00017371666811430558,0.0 +1997,Fla,6,F,0.0001523136442562525,0.0 +1997,Fla,7,M,0.0001495260025718473,0.0 +1997,Fla,7,F,9.437226713643084e-05,0.0 +1997,Fla,8,M,9.088981125215865e-05,0.0 +1997,Fla,8,F,6.337135614702154e-05,0.0 +1997,Fla,9,M,0.00012202562538133012,0.0 +1997,Fla,9,F,9.665571235260003e-05,0.0 +1997,Fla,10,M,0.0002125527586311603,0.0005353319057815847 +1997,Fla,10,F,0.0,0.0 +1997,Fla,11,M,6.24512099921936e-05,0.0005605381165919282 +1997,Fla,11,F,0.000163484174731886,0.0 +1997,Fla,12,M,9.10028514226779e-05,0.0 +1997,Fla,12,F,0.0001592458118351488,0.0012853470437018 +1997,Fla,13,M,0.00017703292812463114,0.001202645820805773 +1997,Fla,13,F,0.0001852423587527015,0.0 +1997,Fla,14,M,0.00023071377072819043,0.0005359056806002144 +1997,Fla,14,F,9.168704156479218e-05,0.001126760563380282 +1997,Fla,15,M,0.0003353641495724107,0.0005042864346949069 +1997,Fla,15,F,0.0003583266147093076,0.0005112474437627811 +1997,Fla,16,M,0.0003410156583023104,0.0 +1997,Fla,16,F,0.0004145077720207254,0.0004748338081671415 +1997,Fla,17,M,0.00061735323829835,0.0 +1997,Fla,17,F,0.0001493428912783752,0.0 +1997,Fla,18,M,0.0009655799159377489,0.001140901312036509 +1997,Fla,18,F,0.0005335862927610127,0.0 +1997,Fla,19,M,0.001150450113606949,0.0 +1997,Fla,19,F,0.00023894148920283148,0.0 +1997,Fla,20,M,0.001025520818072607,0.001877346683354193 +1997,Fla,20,F,0.0003386178236108973,0.0 +1997,Fla,21,M,0.0009913184535432122,0.0006082725060827251 +1997,Fla,21,F,0.0001898253606681853,0.00048309178743961346 +1997,Fla,22,M,0.001273516642547034,0.001066098081023454 +1997,Fla,22,F,0.0004236006051437217,0.0004302925989672978 +1997,Fla,23,M,0.001172791243158718,0.001377410468319559 +1997,Fla,23,F,0.0003221555132523064,0.0008220304151253597 +1997,Fla,24,M,0.001207826717126983,0.0008200082000820008 +1997,Fla,24,F,0.0003356455582904453,0.0003735524841240195 +1997,Fla,25,M,0.001164746991070273,0.0003636363636363636 +1997,Fla,25,F,0.0003460207612456748,0.00035026269702276714 +1997,Fla,26,M,0.0009032517061421117,0.0014204545454545461 +1997,Fla,26,F,0.00015700641109511968,0.0006784260515603799 +1997,Fla,27,M,0.001107782169742441,0.0013153567905294311 +1997,Fla,27,F,0.0004968489317747967,0.0006868131868131869 +1997,Fla,28,M,0.0007954856191115419,0.00033189512114171934 +1997,Fla,28,F,0.0003868372188982877,0.0 +1997,Fla,29,M,0.0009567089213106912,0.000333667000333667 +1997,Fla,29,F,0.0005285944422070076,0.001418439716312057 +1997,Fla,30,M,0.0009537767231953846,0.0008984725965858043 +1997,Fla,30,F,0.0005528181708929215,0.0006435006435006435 +1997,Fla,31,M,0.001008245205233913,0.0008971291866028707 +1997,Fla,31,F,0.0005365432617164716,0.000682360968952576 +1997,Fla,32,M,0.0009470308430726843,0.0008668015024559376 +1997,Fla,32,F,0.0003322259136212625,0.0003326679973386561 +1997,Fla,33,M,0.001122068057743348,0.0015119443604475358 +1997,Fla,33,F,0.00040195618677564153,0.00035523978685612787 +1997,Fla,34,M,0.001092299290005461,0.001466705778820769 +1997,Fla,34,F,0.0006771703309105683,0.0 +1997,Fla,35,M,0.001051409545922502,0.001270244522070499 +1997,Fla,35,F,0.0006708107866374492,0.0008022462896109105 +1997,Fla,36,M,0.0014790247400501973,0.0006148170919151553 +1997,Fla,36,F,0.0005063174610480772,0.00038431975403535736 +1997,Fla,37,M,0.001556096171126745,0.0006968641114982577 +1997,Fla,37,F,0.0007419898819561551,0.002031694433157253 +1997,Fla,38,M,0.001629209721695271,0.001688048615800135 +1997,Fla,38,F,0.0008322160062878543,0.0004273504273504274 +1997,Fla,39,M,0.0012422921419375241,0.002501786990707649 +1997,Fla,39,F,0.0009817671809256663,0.0009587727708533078 +1997,Fla,40,M,0.0018625875998230551,0.0003580379520229145 +1997,Fla,40,F,0.0009491493249175426,0.0018239854081167355 +1997,Fla,41,M,0.002166643116198012,0.0029444239970555764 +1997,Fla,41,F,0.001124025446022863,0.001998001998001998 +1997,Fla,42,M,0.002515693133355695,0.001935733643050717 +1997,Fla,42,F,0.001349660131039729,0.001036806635562468 +1997,Fla,43,M,0.002053036783575706,0.0030594405594405604 +1997,Fla,43,F,0.001494086960925828,0.002765486725663717 +1997,Fla,44,M,0.002691790040376851,0.002095557418273261 +1997,Fla,44,F,0.001552162849872774,0.001740139211136891 +1997,Fla,45,M,0.002846445789311725,0.002659574468085107 +1997,Fla,45,F,0.002007183604479189,0.0018856065367693282 +1997,Fla,46,M,0.0035380733109602225,0.002504173622704508 +1997,Fla,46,F,0.001986439241445068,0.004206730769230769 +1997,Fla,47,M,0.003122983610788489,0.001667361400583577 +1997,Fla,47,F,0.002103637428769239,0.0005959475566150177 +1997,Fla,48,M,0.0036240325127488288,0.0030594405594405604 +1997,Fla,48,F,0.002339089069357934,0.0006447453255963892 +1997,Fla,49,M,0.0039806431470496405,0.001337494427106554 +1997,Fla,49,F,0.002417962003454232,0.0006361323155216285 +1997,Fla,50,M,0.00436039142118339,0.0031717263253285013 +1997,Fla,50,F,0.002641144321539709,0.0034916201117318442 +1997,Fla,51,M,0.005223646276367996,0.004186289900575615 +1997,Fla,51,F,0.003242898919998842,0.00228310502283105 +1997,Fla,52,M,0.005198908516444061,0.004291845493562232 +1997,Fla,52,F,0.002505754494332916,0.0014367816091954018 +1997,Fla,53,M,0.006349301877708232,0.005978260869565218 +1997,Fla,53,F,0.003794547993443021,0.002356637863315004 +1997,Fla,54,M,0.007106879183053887,0.007046388725778039 +1997,Fla,54,F,0.003658536585365854,0.001584786053882726 +1997,Fla,55,M,0.007956336241688126,0.002935995302407516 +1997,Fla,55,F,0.004048276644848852,0.006211180124223602 +1997,Fla,56,M,0.0076261447922833184,0.00727069351230425 +1997,Fla,56,F,0.003956478733926805,0.002250562640660165 +1997,Fla,57,M,0.00891549385467745,0.009356725146198829 +1997,Fla,57,F,0.004561072764314167,0.0036101083032490976 +1997,Fla,58,M,0.009259828954654529,0.006097560975609756 +1997,Fla,58,F,0.005076445293836598,0.004512635379061372 +1997,Fla,59,M,0.01082505317291515,0.01266666666666667 +1997,Fla,59,F,0.004728497697561579,0.0049261083743842365 +1997,Fla,60,M,0.01118641837204712,0.006254343293954135 +1997,Fla,60,F,0.005590276687289972,0.003154574132492114 +1997,Fla,61,M,0.013004632693580407,0.011869436201780421 +1997,Fla,61,F,0.0061320754716981144,0.0066815144766147 +1997,Fla,62,M,0.01395918097317323,0.01226053639846744 +1997,Fla,62,F,0.006250192432033007,0.007470651013874066 +1997,Fla,63,M,0.01401311866428146,0.01549186676994578 +1997,Fla,63,F,0.00736317792284132,0.004519774011299435 +1997,Fla,64,M,0.017122395833333342,0.020525451559934318 +1997,Fla,64,F,0.0077742500222545315,0.0049261083743842365 +1997,Fla,65,M,0.01882762699612276,0.0150093808630394 +1997,Fla,65,F,0.008753709198813056,0.013473053892215573 +1997,Fla,66,M,0.02242575257593104,0.02592592592592593 +1997,Fla,66,F,0.00938546150167384,0.00628140703517588 +1997,Fla,67,M,0.02392730204096589,0.03358613217768147 +1997,Fla,67,F,0.01115586242168521,0.01157742402315485 +1997,Fla,68,M,0.025217457652983367,0.01907968574635241 +1997,Fla,68,F,0.01183004173375834,0.011730205278592379 +1997,Fla,69,M,0.030863705239652286,0.030940594059405937 +1997,Fla,69,F,0.01214395360736824,0.018456375838926186 +1997,Fla,70,M,0.03325905752248907,0.032085561497326213 +1997,Fla,70,F,0.01475741239892183,0.0110062893081761 +1997,Fla,71,M,0.0370773807030039,0.0357653791130186 +1997,Fla,71,F,0.01671977250145613,0.01867572156196944 +1997,Fla,72,M,0.03886021789951921,0.02643171806167401 +1997,Fla,72,F,0.01955758426966292,0.0300187617260788 +1997,Fla,73,M,0.04360867558837102,0.03810975609756098 +1997,Fla,73,F,0.02125762385419268,0.007434944237918215 +1997,Fla,74,M,0.04670664769262045,0.05253623188405797 +1997,Fla,74,F,0.02471057126589486,0.03563941299790356 +1997,Fla,75,M,0.050448430493273536,0.058161350844277676 +1997,Fla,75,F,0.029142285186325837,0.03325942350332594 +1997,Fla,76,M,0.05731617438630308,0.05274725274725275 +1997,Fla,76,F,0.0315608645279853,0.0234192037470726 +1997,Fla,77,M,0.06752336448598131,0.06666666666666668 +1997,Fla,77,F,0.03582729954411371,0.036764705882352935 +1997,Fla,78,M,0.07235271950759954,0.08677685950413222 +1997,Fla,78,F,0.04188646563262735,0.04564315352697095 +1997,Fla,79,M,0.08550744433820516,0.09130434782608696 +1997,Fla,79,F,0.04610479849587183,0.03738317757009346 +1997,Fla,80,M,0.08935793731041455,0.07960199004975124 +1997,Fla,80,F,0.054572940287226,0.04932735426008968 +1997,Fla,81,M,0.0995685740236149,0.1111111111111111 +1997,Fla,81,F,0.06097079715864246,0.03524229074889868 +1997,Fla,82,M,0.1094964515038865,0.1485714285714286 +1997,Fla,82,F,0.07005948446794448,0.06306306306306306 +1997,Fla,83,M,0.1195484864032838,0.1324503311258278 +1997,Fla,83,F,0.08237474437627812,0.03636363636363636 +1997,Fla,84,M,0.1350241900014661,0.125 +1997,Fla,84,F,0.09464640727066173,0.08287292817679558 +1997,Fla,85,M,0.1396330275229358,0.125 +1997,Fla,85,F,0.1013447031813709,0.0896551724137931 +1997,Fla,86,M,0.155030584264923,0.1384615384615385 +1997,Fla,86,F,0.1131333455277118,0.1023622047244094 +1997,Fla,87,M,0.1896825396825397,0.1666666666666667 +1997,Fla,87,F,0.1248800255945398,0.1333333333333333 +1997,Fla,88,M,0.1915670650730412,0.1147540983606558 +1997,Fla,88,F,0.1345494613124388,0.125 +1997,Fla,89,M,0.2122699386503068,0.1764705882352941 +1997,Fla,89,F,0.1522827687776141,0.09876543209876544 +1997,Fla,90,M,0.230340211935304,0.1578947368421053 +1997,Fla,90,F,0.1754483268626364,0.126984126984127 +1997,Fla,91,M,0.2311015118790497,0.1111111111111111 +1997,Fla,91,F,0.1914941494149415,0.1555555555555556 +1997,Fla,92,M,0.2335907335907336,0.2857142857142857 +1997,Fla,92,F,0.2014430014430015,0.2380952380952381 +1997,Fla,93,M,0.2944444444444445,0.2142857142857143 +1997,Fla,93,F,0.2257154373236598,0.3333333333333333 +1997,Fla,94,M,0.3126338329764454,0.2 +1997,Fla,94,F,0.2439807383627608,0.2800000000000001 +1997,Fla,95,M,0.3658536585365854,0.125 +1997,Fla,95,F,0.2595936794582393,0.1851851851851852 +1997,Fla,96,M,0.3152709359605912,0.0 +1997,Fla,96,F,0.2662790697674419,0.2307692307692308 +1997,Fla,97,M,0.4049079754601227,0.0 +1997,Fla,97,F,0.3262411347517731,0.1 +1997,Fla,98,M,0.3943661971830986,0.5 +1997,Fla,98,F,0.3653333333333334,0.1666666666666667 +1997,Fla,99,M,0.2727272727272727,0.25 +1997,Fla,99,F,0.3206751054852321,0.0 +1997,Fla,100,M,0.4242424242424243,0.0 +1997,Fla,100,F,0.3456790123456789,0.6 +1997,Fla,101,M,0.3529411764705883,0.0 +1997,Fla,101,F,0.4259259259259261,0.0 +1997,Fla,102,M,0.5555555555555556,0.0 +1997,Fla,102,F,0.372093023255814,0.0 +1997,Fla,103,M,0.75,0.0 +1997,Fla,103,F,0.6538461538461539,0.0 +1997,Fla,104,M,0.0,0.0 +1997,Fla,104,F,0.6666666666666666,0.0 +1997,Fla,105,M,1.0,0.0 +1997,Fla,105,F,0.3333333333333333,0.0 +1997,Fla,106,M,0.0,0.0 +1997,Fla,106,F,0.0,0.0 +1997,Fla,107,M,0.0,0.0 +1997,Fla,107,F,0.0,0.0 +1997,Fla,108,M,0.0,0.0 +1997,Fla,108,F,0.5,0.0 +1997,Fla,109,M,0.0,0.0 +1997,Fla,109,F,1.0,0.0 +1997,Fla,110,M,0.0,0.0 +1997,Fla,110,F,0.0,0.0 +1997,Fla,111,M,0.0,0.0 +1997,Fla,111,F,0.0,0.0 +1997,Fla,112,M,0.0,0.0 +1997,Fla,112,F,0.0,0.0 +1997,Fla,113,M,0.0,0.0 +1997,Fla,113,F,0.0,0.0 +1997,Fla,114,M,0.0,0.0 +1997,Fla,114,F,0.0,0.0 +1997,Fla,115,M,0.0,0.0 +1997,Fla,115,F,0.0,0.0 +1997,Fla,116,M,0.0,0.0 +1997,Fla,116,F,0.0,0.0 +1997,Fla,117,M,0.0,0.0 +1997,Fla,117,F,0.0,0.0 +1997,Fla,118,M,0.0,0.0 +1997,Fla,118,F,0.0,0.0 +1997,Fla,119,M,0.0,0.0 +1997,Fla,119,F,0.0,0.0 +1997,Fla,120,M,0.0,0.0 +1997,Fla,120,F,0.0,0.0 +1997,Wal,0,M,0.0013908205841446446,0.0019323671497584536 +1997,Wal,0,F,0.001336154103106558,0.002132196162046908 +1997,Wal,1,M,0.000595689375067692,0.0 +1997,Wal,1,F,0.0003394433129667346,0.0 +1997,Wal,2,M,0.00042932274337233016,0.0 +1997,Wal,2,F,0.0002239516264486871,0.0 +1997,Wal,3,M,0.0002547640884540916,0.0 +1997,Wal,3,F,0.0002163331530557058,0.0 +1997,Wal,4,M,0.00033962447236912327,0.000782472613458529 +1997,Wal,4,F,0.0,0.0 +1997,Wal,5,M,0.00028344671201814065,0.0 +1997,Wal,5,F,0.0001965601965601966,0.0007401924500370098 +1997,Wal,6,M,0.00023965872597421278,0.0 +1997,Wal,6,F,0.0002489667878305034,0.0 +1997,Wal,7,M,9.539254030334828e-05,0.0 +1997,Wal,7,F,0.0001001702894921366,0.0007225433526011558 +1997,Wal,8,M,9.599692809830086e-05,0.0 +1997,Wal,8,F,5.068937550689376e-05,0.0 +1997,Wal,9,M,0.000149812734082397,0.0 +1997,Wal,9,F,0.0001048987726843596,0.0 +1997,Wal,10,M,0.000199054491166957,0.0 +1997,Wal,10,F,0.0002631025047358451,0.0006944444444444446 +1997,Wal,11,M,5.178932104200114e-05,0.0 +1997,Wal,11,F,0.0002171081198436822,0.0 +1997,Wal,12,M,0.0002096765738847827,0.0 +1997,Wal,12,F,5.450779461462989e-05,0.0014074595355383528 +1997,Wal,13,M,0.00015787811809283233,0.0 +1997,Wal,13,F,0.00011321822813472971,0.0 +1997,Wal,14,M,0.00020924879681941832,0.0005980861244019139 +1997,Wal,14,F,5.458813253998581e-05,0.0 +1997,Wal,15,M,0.0009358427784132266,0.0005711022272986865 +1997,Wal,15,F,0.0002673653815303995,0.0 +1997,Wal,16,M,0.0006766604205704767,0.0010559662090813089 +1997,Wal,16,F,0.0004826772498122922,0.0 +1997,Wal,17,M,0.0008449067962190421,0.0 +1997,Wal,17,F,0.00044795341284506414,0.0005186721991701245 +1997,Wal,18,M,0.001390076988879384,0.001029866117404737 +1997,Wal,18,F,0.0006121313299944351,0.0 +1997,Wal,19,M,0.001517847796503716,0.0005546311702717693 +1997,Wal,19,F,0.00011028398125172319,0.0005065856129685917 +1997,Wal,20,M,0.001297151455403933,0.00108283703302653 +1997,Wal,20,F,0.00054019014693172,0.0005235602094240838 +1997,Wal,21,M,0.0010840388189138964,0.0020283975659229213 +1997,Wal,21,F,0.0003220611916264092,0.0004975124378109452 +1997,Wal,22,M,0.001303258145363409,0.001752080595707403 +1997,Wal,22,F,0.00047425831269431415,0.0008707009142359599 +1997,Wal,23,M,0.0016058394160583939,0.001888217522658611 +1997,Wal,23,F,0.0005603667855323483,0.0 +1997,Wal,24,M,0.001675683439459951,0.001728907330567082 +1997,Wal,24,F,0.00035117644107761,0.00036873156342182885 +1997,Wal,25,M,0.0013334603295551961,0.00101763907734057 +1997,Wal,25,F,0.0005447162523521837,0.0007049700387733521 +1997,Wal,26,M,0.002066014068571991,0.001602564102564103 +1997,Wal,26,F,0.00040853845368195286,0.00035323207347227127 +1997,Wal,27,M,0.0013903371567605153,0.0006335128286347799 +1997,Wal,27,F,0.0007145044401347351,0.0006856359273225918 +1997,Wal,28,M,0.001680757869002751,0.001533272002453235 +1997,Wal,28,F,0.0004110152075626799,0.0003240440699935191 +1997,Wal,29,M,0.0014478282576135802,0.0009177118384827164 +1997,Wal,29,F,0.000303444090426339,0.0003395585738539899 +1997,Wal,30,M,0.001219988288112434,0.001096190737188271 +1997,Wal,30,F,0.0006845965770171152,0.0009230769230769233 +1997,Wal,31,M,0.001223586992329051,0.001040582726326743 +1997,Wal,31,F,0.0008016221059084262,0.00030969340353050485 +1997,Wal,32,M,0.001172121539987377,0.0018334206390780519 +1997,Wal,32,F,0.0007213055630691553,0.000915750915750916 +1997,Wal,33,M,0.001693131377842859,0.000784313725490196 +1997,Wal,33,F,0.0009904110205735384,0.0006285355122564425 +1997,Wal,34,M,0.001924611557057691,0.001582278481012658 +1997,Wal,34,F,0.0007812859046831196,0.002297341647522153 +1997,Wal,35,M,0.001817190623296384,0.001082251082251082 +1997,Wal,35,F,0.0009785171018102566,0.0003133813851457224 +1997,Wal,36,M,0.00215181759912096,0.0007501875468867218 +1997,Wal,36,F,0.0016325790213595759,0.0009891196834817012 +1997,Wal,37,M,0.002620639797578168,0.001059602649006623 +1997,Wal,37,F,0.001439664950702382,0.0009986684420772304 +1997,Wal,38,M,0.003027939624718998,0.002877321475281193 +1997,Wal,38,F,0.001288030202087497,0.000682360968952576 +1997,Wal,39,M,0.003053858967240422,0.002639218791237794 +1997,Wal,39,F,0.0008144427853943259,0.0007122507122507122 +1997,Wal,40,M,0.003166501252422137,0.001532567049808429 +1997,Wal,40,F,0.001411079248031317,0.0003513703443429375 +1997,Wal,41,M,0.0027625625148844962,0.0032 +1997,Wal,41,F,0.001774905565921813,0.001077586206896552 +1997,Wal,42,M,0.003821169277799007,0.002760143527463428 +1997,Wal,42,F,0.002155765526098523,0.001112759643916914 +1997,Wal,43,M,0.0038928978351690092,0.003195816385822197 +1997,Wal,43,F,0.002447923883423399,0.001642710472279261 +1997,Wal,44,M,0.004641370400497631,0.0048120300751879706 +1997,Wal,44,F,0.002346316283435007,0.001230012300123001 +1997,Wal,45,M,0.0035705430200843047,0.003786683496371095 +1997,Wal,45,F,0.0024714828897338397,0.0012853470437018 +1997,Wal,46,M,0.005174460004747211,0.0046111281893636644 +1997,Wal,46,F,0.0030106312917489893,0.001639344262295082 +1997,Wal,47,M,0.004782858236081882,0.006083893691962856 +1997,Wal,47,F,0.0030127571435296326,0.0008952551477170994 +1997,Wal,48,M,0.0058702944465150965,0.003908794788273616 +1997,Wal,48,F,0.003411572052401747,0.0004222972972972973 +1997,Wal,49,M,0.0061805845996561175,0.00495703899537343 +1997,Wal,49,F,0.003663339133620295,0.003274087932647334 +1997,Wal,50,M,0.005635148042024833,0.006966213862765587 +1997,Wal,50,F,0.004377678447997789,0.001964636542239686 +1997,Wal,51,M,0.00806348393702803,0.003952569169960474 +1997,Wal,51,F,0.00469766321368345,0.0035650623885918 +1997,Wal,52,M,0.00821039127645927,0.004420866489832008 +1997,Wal,52,F,0.0047843955100288285,0.003990877993158495 +1997,Wal,53,M,0.010368742704113159,0.006889763779527559 +1997,Wal,53,F,0.004607696800571095,0.002515723270440252 +1997,Wal,54,M,0.010488131850800407,0.008664627930682976 +1997,Wal,54,F,0.004900868790376476,0.0025575447570332487 +1997,Wal,55,M,0.009726803687727312,0.0069259456579648365 +1997,Wal,55,F,0.004469887076537014,0.00337609723160027 +1997,Wal,56,M,0.01106647464564542,0.009111617312072893 +1997,Wal,56,F,0.004983855117225888,0.003393665158371041 +1997,Wal,57,M,0.01216357916812304,0.015376984126984131 +1997,Wal,57,F,0.005766427983017553,0.0034168564920273353 +1997,Wal,58,M,0.01212455221824194,0.009549071618037136 +1997,Wal,58,F,0.006995604531665946,0.002293577981651377 +1997,Wal,59,M,0.015643021914648208,0.0077760497667185065 +1997,Wal,59,F,0.006777653484240311,0.0049658597144630655 +1997,Wal,60,M,0.01234108988179318,0.01107594936708861 +1997,Wal,60,F,0.007554358536425145,0.008014796547472256 +1997,Wal,61,M,0.01552490767955385,0.015283842794759831 +1997,Wal,61,F,0.007881255746748979,0.003614457831325302 +1997,Wal,62,M,0.018138801261829655,0.02044293015332198 +1997,Wal,62,F,0.008062992125984252,0.01079784043191362 +1997,Wal,63,M,0.01870431417514691,0.02243409983174425 +1997,Wal,63,F,0.008414442700156986,0.00768775872264932 +1997,Wal,64,M,0.02007785289899611,0.0281615302869288 +1997,Wal,64,F,0.009468275503723804,0.010539367637941721 +1997,Wal,65,M,0.0240803565489257,0.02396644697423607 +1997,Wal,65,F,0.01096687555953447,0.00927070457354759 +1997,Wal,66,M,0.02576445860736321,0.026493799323562568 +1997,Wal,66,F,0.012485303174514307,0.007220216606498195 +1997,Wal,67,M,0.028439105579274912,0.028262176788935663 +1997,Wal,67,F,0.014627581768182091,0.01012658227848101 +1997,Wal,68,M,0.03195319531953196,0.03749231714812538 +1997,Wal,68,F,0.014719464326945281,0.01389808074123097 +1997,Wal,69,M,0.03503356740489235,0.03626306084818685 +1997,Wal,69,F,0.0170960465392378,0.02346227013316424 +1997,Wal,70,M,0.04135368071479402,0.03992628992628993 +1997,Wal,70,F,0.01776514478593001,0.019808306709265186 +1997,Wal,71,M,0.04447655748233783,0.05 +1997,Wal,71,F,0.02041993539455469,0.02262142381902861 +1997,Wal,72,M,0.04824968367777309,0.05788005578800558 +1997,Wal,72,F,0.01994538762911077,0.02127659574468085 +1997,Wal,73,M,0.05022542831379621,0.05886681383370125 +1997,Wal,73,F,0.02424390841190156,0.01981707317073171 +1997,Wal,74,M,0.05534044763433752,0.06492411467116357 +1997,Wal,74,F,0.02716752274274398,0.02948207171314741 +1997,Wal,75,M,0.05774303859306304,0.06607495069033531 +1997,Wal,75,F,0.03264076715023359,0.03122289679098005 +1997,Wal,76,M,0.06773787019533711,0.07665903890160182 +1997,Wal,76,F,0.03451135493748405,0.03527168732125833 +1997,Wal,77,M,0.07376921882279858,0.07100591715976333 +1997,Wal,77,F,0.03992105499237463,0.04667609618104668 +1997,Wal,78,M,0.07794401544401544,0.07631578947368421 +1997,Wal,78,F,0.048098287805515616,0.06694560669456066 +1997,Wal,79,M,0.09375,0.095679012345679 +1997,Wal,79,F,0.05398995535714286,0.07061503416856492 +1997,Wal,80,M,0.090283091048202,0.1045751633986928 +1997,Wal,80,F,0.05912526997840172,0.04535637149028078 +1997,Wal,81,M,0.1063364894391843,0.1129032258064516 +1997,Wal,81,F,0.06770528288625981,0.04536862003780719 +1997,Wal,82,M,0.1172035640849897,0.1656626506024097 +1997,Wal,82,F,0.07992584200226592,0.0933572710951526 +1997,Wal,83,M,0.1300684570826751,0.125 +1997,Wal,83,F,0.08282455938255961,0.0928030303030303 +1997,Wal,84,M,0.1336915297092288,0.1641221374045802 +1997,Wal,84,F,0.09471992086064054,0.1120689655172414 +1997,Wal,85,M,0.1593384429205325,0.1677018633540373 +1997,Wal,85,F,0.1027777777777778,0.1171875 +1997,Wal,86,M,0.1732536764705882,0.1404958677685951 +1997,Wal,86,F,0.1240571336864067,0.112094395280236 +1997,Wal,87,M,0.1911242603550296,0.1882352941176471 +1997,Wal,87,F,0.1443771784993579,0.1224489795918368 +1997,Wal,88,M,0.1928625664388762,0.1770833333333334 +1997,Wal,88,F,0.1427081160025037,0.1428571428571429 +1997,Wal,89,M,0.217349857006673,0.1777777777777778 +1997,Wal,89,F,0.1652323580034424,0.2625698324022347 +1997,Wal,90,M,0.2219541616405308,0.2391304347826087 +1997,Wal,90,F,0.1841279799247177,0.1623376623376623 +1997,Wal,91,M,0.2914653784219002,0.1794871794871795 +1997,Wal,91,F,0.1915772089182494,0.2083333333333334 +1997,Wal,92,M,0.272093023255814,0.2173913043478261 +1997,Wal,92,F,0.2138141188420518,0.1886792452830189 +1997,Wal,93,M,0.3264705882352941,0.0 +1997,Wal,93,F,0.2327297116029511,0.2903225806451613 +1997,Wal,94,M,0.2748815165876778,0.1875 +1997,Wal,94,F,0.2634146341463415,0.1884057971014493 +1997,Wal,95,M,0.2805755395683453,0.4166666666666667 +1997,Wal,95,F,0.2560679611650486,0.3404255319148936 +1997,Wal,96,M,0.3580246913580247,0.3333333333333333 +1997,Wal,96,F,0.2775590551181103,0.28125 +1997,Wal,97,M,0.3272727272727273,0.0 +1997,Wal,97,F,0.2741935483870968,0.2727272727272727 +1997,Wal,98,M,0.4117647058823529,0.3333333333333333 +1997,Wal,98,F,0.3514851485148515,0.2 +1997,Wal,99,M,0.5,0.0 +1997,Wal,99,F,0.3082191780821918,0.2666666666666667 +1997,Wal,100,M,0.5,0.0 +1997,Wal,100,F,0.4505494505494506,0.4 +1997,Wal,101,M,0.3333333333333333,0.0 +1997,Wal,101,F,0.2931034482758621,0.0 +1997,Wal,102,M,0.5,0.0 +1997,Wal,102,F,0.52,0.5 +1997,Wal,103,M,0.3333333333333333,0.0 +1997,Wal,103,F,0.5,0.0 +1997,Wal,104,M,0.0,1.0 +1997,Wal,104,F,0.125,0.0 +1997,Wal,105,M,0.0,0.0 +1997,Wal,105,F,0.0,0.0 +1997,Wal,106,M,0.0,0.0 +1997,Wal,106,F,0.3333333333333333,0.0 +1997,Wal,107,M,0.0,0.0 +1997,Wal,107,F,0.0,0.0 +1997,Wal,108,M,0.0,0.0 +1997,Wal,108,F,1.0,0.0 +1997,Wal,109,M,0.0,0.0 +1997,Wal,109,F,0.0,0.0 +1997,Wal,110,M,0.0,0.0 +1997,Wal,110,F,0.0,0.0 +1997,Wal,111,M,0.0,0.0 +1997,Wal,111,F,0.0,0.0 +1997,Wal,112,M,0.0,0.0 +1997,Wal,112,F,0.0,0.0 +1997,Wal,113,M,0.0,0.0 +1997,Wal,113,F,0.0,0.0 +1997,Wal,114,M,0.0,0.0 +1997,Wal,114,F,0.0,0.0 +1997,Wal,115,M,0.0,0.0 +1997,Wal,115,F,0.0,0.0 +1997,Wal,116,M,0.0,0.0 +1997,Wal,116,F,0.0,0.0 +1997,Wal,117,M,0.0,0.0 +1997,Wal,117,F,0.0,0.0 +1997,Wal,118,M,0.0,0.0 +1997,Wal,118,F,0.0,0.0 +1997,Wal,119,M,0.0,0.0 +1997,Wal,119,F,0.0,0.0 +1997,Wal,120,M,0.0,0.0 +1997,Wal,120,F,0.0,0.0 +1998,BruCap,0,M,0.001252086811352254,0.0 +1998,BruCap,0,F,0.0009248554913294797,0.002365464222353637 +1998,BruCap,1,M,0.0004500450045004501,0.0 +1998,BruCap,1,F,0.00022962112514351318,0.0005656108597285067 +1998,BruCap,2,M,0.00023618327822390184,0.0 +1998,BruCap,2,F,0.0007290400972053463,0.001152737752161384 +1998,BruCap,3,M,0.00047036688617121367,0.0005288207297726071 +1998,BruCap,3,F,0.0002630886608787162,0.0 +1998,BruCap,4,M,0.0,0.0 +1998,BruCap,4,F,0.0005129520389843549,0.001193317422434368 +1998,BruCap,5,M,0.00048828125,0.0 +1998,BruCap,5,F,0.00025322866548493293,0.0005652911249293388 +1998,BruCap,6,M,0.0007429420505200594,0.0 +1998,BruCap,6,F,0.0,0.0 +1998,BruCap,7,M,0.000250501002004008,0.0 +1998,BruCap,7,F,0.0,0.0 +1998,BruCap,8,M,0.0005241090146750523,0.0005747126436781607 +1998,BruCap,8,F,0.0,0.0 +1998,BruCap,9,M,0.0,0.0 +1998,BruCap,9,F,0.0,0.0 +1998,BruCap,10,M,0.0005369127516778523,0.0 +1998,BruCap,10,F,0.0,0.0 +1998,BruCap,11,M,0.0,0.0 +1998,BruCap,11,F,0.0,0.0 +1998,BruCap,12,M,0.0,0.0 +1998,BruCap,12,F,0.0002971768202080238,0.0 +1998,BruCap,13,M,0.0,0.0 +1998,BruCap,13,F,0.0,0.0 +1998,BruCap,14,M,0.0005586592178770949,0.0 +1998,BruCap,14,F,0.0,0.0 +1998,BruCap,15,M,0.0002870264064293915,0.0 +1998,BruCap,15,F,0.0,0.0 +1998,BruCap,16,M,0.0002870264064293915,0.001015744032503809 +1998,BruCap,16,F,0.00030075187969924816,0.0 +1998,BruCap,17,M,0.0008883624518803672,0.0004962779156327543 +1998,BruCap,17,F,0.0,0.0 +1998,BruCap,18,M,0.00055005500550055,0.0 +1998,BruCap,18,F,0.0008673026886383347,0.0 +1998,BruCap,19,M,0.001324503311258278,0.0006090133982947625 +1998,BruCap,19,F,0.000255819902788437,0.0005268703898840885 +1998,BruCap,20,M,0.001020929045431343,0.001731102135025967 +1998,BruCap,20,F,0.0005011275369581559,0.0 +1998,BruCap,21,M,0.001538856116953065,0.0005417118093174432 +1998,BruCap,21,F,0.0004906771344455348,0.0 +1998,BruCap,22,M,0.001707733593559405,0.0010548523206751052 +1998,BruCap,22,F,0.0007327796775769418,0.0 +1998,BruCap,23,M,0.001940805434255216,0.00044923629829290204 +1998,BruCap,23,F,0.0006952491309385864,0.0 +1998,BruCap,24,M,0.002385599653003687,0.001219512195121951 +1998,BruCap,24,F,0.0,0.0003614022406938923 +1998,BruCap,25,M,0.001632986323739539,0.0 +1998,BruCap,25,F,0.0003890293717175647,0.000326477309826967 +1998,BruCap,26,M,0.001177856301531213,0.0006383657835939994 +1998,BruCap,26,F,0.0,0.0006265664160401003 +1998,BruCap,27,M,0.0007830853563038371,0.0002955956251847473 +1998,BruCap,27,F,0.0005821851348728897,0.001566906925728612 +1998,BruCap,28,M,0.0007984031936127744,0.001155401502021953 +1998,BruCap,28,F,0.0004026575397624321,0.0002973535533749628 +1998,BruCap,29,M,0.002049180327868853,0.001129305477131564 +1998,BruCap,29,F,0.0010440593025683859,0.00030845157310302283 +1998,BruCap,30,M,0.00103327133705311,0.0005936479667557139 +1998,BruCap,30,F,0.0012774111134766868,0.00030969340353050485 +1998,BruCap,31,M,0.001478977392774139,0.0013861935126143607 +1998,BruCap,31,F,0.00064963187527068,0.001212121212121212 +1998,BruCap,32,M,0.002257336343115124,0.0008398656215005599 +1998,BruCap,32,F,0.0006453000645300067,0.0003017501508750755 +1998,BruCap,33,M,0.001495406964323863,0.0005532503457814661 +1998,BruCap,33,F,0.0002183882943874208,0.0 +1998,BruCap,34,M,0.002137665669089355,0.0009115770282588877 +1998,BruCap,34,F,0.0002208480565371025,0.0006682258603407952 +1998,BruCap,35,M,0.002554575011611705,0.0006108735491753207 +1998,BruCap,35,F,0.001606978879706153,0.00204848071013998 +1998,BruCap,36,M,0.001156604210039325,0.0 +1998,BruCap,36,F,0.002037120869171571,0.0007135212272565109 +1998,BruCap,37,M,0.001136105430583958,0.000335345405767941 +1998,BruCap,37,F,0.0011088933244621866,0.0007097232079489 +1998,BruCap,38,M,0.001830244795241364,0.0007312614259597808 +1998,BruCap,38,F,0.0006675567423230972,0.000782472613458529 +1998,BruCap,39,M,0.002120141342756184,0.003518373729476153 +1998,BruCap,39,F,0.00223613595706619,0.001220008133387556 +1998,BruCap,40,M,0.002826189354686764,0.001300954032957502 +1998,BruCap,40,F,0.0006779661016949152,0.0008661758336942398 +1998,BruCap,41,M,0.003924454255580083,0.001633319722335647 +1998,BruCap,41,F,0.0018157058556513847,0.001297016861219196 +1998,BruCap,42,M,0.002169720347155256,0.001275510204081633 +1998,BruCap,42,F,0.001819422333409143,0.0018009905447996398 +1998,BruCap,43,M,0.0024142926122646072,0.00047505938242280285 +1998,BruCap,43,F,0.002775850104094379,0.0009442870632672332 +1998,BruCap,44,M,0.0036023054755043226,0.0009629272989889263 +1998,BruCap,44,F,0.002929907595221997,0.0005128205128205128 +1998,BruCap,45,M,0.005438637975880823,0.002918287937743191 +1998,BruCap,45,F,0.002923976608187135,0.001029866117404737 +1998,BruCap,46,M,0.0037193156459211507,0.003709591944886064 +1998,BruCap,46,F,0.00388749142465127,0.001167542323409224 +1998,BruCap,47,M,0.004559270516717325,0.0030303030303030307 +1998,BruCap,47,F,0.004037685060565276,0.002171552660152009 +1998,BruCap,48,M,0.006830255502150264,0.003912800447177194 +1998,BruCap,48,F,0.00473292765382015,0.001256281407035176 +1998,BruCap,49,M,0.007555447233731416,0.00111794298490777 +1998,BruCap,49,F,0.005309734513274336,0.002486016159105034 +1998,BruCap,50,M,0.004138266796494645,0.005184331797235022 +1998,BruCap,50,F,0.002765957446808511,0.0013218770654329153 +1998,BruCap,51,M,0.007864632983794091,0.002512562814070352 +1998,BruCap,51,F,0.0061175442429539,0.0006821282401091405 +1998,BruCap,52,M,0.01042253521126761,0.0020775623268698053 +1998,BruCap,52,F,0.004810126582278481,0.005970149253731343 +1998,BruCap,53,M,0.00872172254020169,0.003324468085106383 +1998,BruCap,53,F,0.005418138987043581,0.002291825821237586 +1998,BruCap,54,M,0.00788732394366197,0.004431314623338258 +1998,BruCap,54,F,0.004955401387512388,0.0008285004142502071 +1998,BruCap,55,M,0.0117724002616089,0.0057347670250896075 +1998,BruCap,55,F,0.00461361014994233,0.002497918401332223 +1998,BruCap,56,M,0.01044776119402985,0.007506255212677232 +1998,BruCap,56,F,0.006728612624158923,0.00576923076923077 +1998,BruCap,57,M,0.01311806256306761,0.007493188010899181 +1998,BruCap,57,F,0.005882352941176471,0.0037735849056603774 +1998,BruCap,58,M,0.01592863969417012,0.009181331293037493 +1998,BruCap,58,F,0.0069407367859049655,0.00351493848857645 +1998,BruCap,59,M,0.014502094747019018,0.004524886877828055 +1998,BruCap,59,F,0.005994550408719346,0.004752851711026616 +1998,BruCap,60,M,0.02154750244857982,0.01469387755102041 +1998,BruCap,60,F,0.008544652701212789,0.006048387096774193 +1998,BruCap,61,M,0.018323719036308108,0.01326699834162521 +1998,BruCap,61,F,0.008118701007838746,0.004935834155972359 +1998,BruCap,62,M,0.01708233686368295,0.0130718954248366 +1998,BruCap,62,F,0.008535242290748899,0.005107252298263534 +1998,BruCap,63,M,0.018327974276527333,0.006756756756756757 +1998,BruCap,63,F,0.00839653304442037,0.007058823529411766 +1998,BruCap,64,M,0.01798201798201798,0.01365546218487395 +1998,BruCap,64,F,0.0058898847631242,0.009198423127463865 +1998,BruCap,65,M,0.01736111111111111,0.02032085561497326 +1998,BruCap,65,F,0.011910549343704429,0.0064766839378238355 +1998,BruCap,66,M,0.02231866088034718,0.021080368906455867 +1998,BruCap,66,F,0.01357466063348417,0.006993006993006993 +1998,BruCap,67,M,0.03380102040816327,0.01740139211136891 +1998,BruCap,67,F,0.011849901250822907,0.007894736842105262 +1998,BruCap,68,M,0.032311242993735584,0.022955523672883792 +1998,BruCap,68,F,0.01449608835710999,0.01584507042253521 +1998,BruCap,69,M,0.03173553719008265,0.0208 +1998,BruCap,69,F,0.01695308871342313,0.006711409395973154 +1998,BruCap,70,M,0.034589041095890415,0.036231884057971016 +1998,BruCap,70,F,0.016528925619834708,0.021611001964636545 +1998,BruCap,71,M,0.03795767551226067,0.03732809430255403 +1998,BruCap,71,F,0.018189884649511986,0.0103950103950104 +1998,BruCap,72,M,0.03820148749154835,0.029978586723768737 +1998,BruCap,72,F,0.0206431986093003,0.02466367713004484 +1998,BruCap,73,M,0.04154302670623145,0.03072625698324022 +1998,BruCap,73,F,0.0223404255319149,0.011820330969267141 +1998,BruCap,74,M,0.04909925821264571,0.029255319148936167 +1998,BruCap,74,F,0.0262063227953411,0.0202020202020202 +1998,BruCap,75,M,0.05716379626236717,0.03303303303303303 +1998,BruCap,75,F,0.031243402997677864,0.0252808988764045 +1998,BruCap,76,M,0.06606081789584063,0.061290322580645165 +1998,BruCap,76,F,0.03017689906347555,0.03583061889250815 +1998,BruCap,77,M,0.06554235339210425,0.08614232209737828 +1998,BruCap,77,F,0.03666873834679926,0.021220159151193636 +1998,BruCap,78,M,0.08099688473520249,0.05844155844155844 +1998,BruCap,78,F,0.0393957345971564,0.0292887029288703 +1998,BruCap,79,M,0.0781387181738367,0.015748031496062992 +1998,BruCap,79,F,0.03877551020408164,0.029411764705882363 +1998,BruCap,80,M,0.08630393996247655,0.034188034188034185 +1998,BruCap,80,F,0.057204301075268825,0.0650887573964497 +1998,BruCap,81,M,0.1092436974789916,0.08602150537634409 +1998,BruCap,81,F,0.05829596412556054,0.050314465408805034 +1998,BruCap,82,M,0.1088871096877502,0.07291666666666667 +1998,BruCap,82,F,0.05903271692745377,0.0920245398773006 +1998,BruCap,83,M,0.1087118391660462,0.11 +1998,BruCap,83,F,0.07169344870210136,0.05681818181818182 +1998,BruCap,84,M,0.111304347826087,0.1538461538461539 +1998,BruCap,84,F,0.07786467188031282,0.05625 +1998,BruCap,85,M,0.133130081300813,0.046875 +1998,BruCap,85,F,0.0975699558173785,0.07692307692307693 +1998,BruCap,86,M,0.1223733003708282,0.1333333333333333 +1998,BruCap,86,F,0.1030277544154752,0.03636363636363636 +1998,BruCap,87,M,0.1612903225806452,0.1052631578947368 +1998,BruCap,87,F,0.1048758049678013,0.064 +1998,BruCap,88,M,0.1752380952380953,0.0 +1998,BruCap,88,F,0.1323692992213571,0.1538461538461539 +1998,BruCap,89,M,0.1752808988764045,0.1428571428571429 +1998,BruCap,89,F,0.1361621279290691,0.1194029850746269 +1998,BruCap,90,M,0.2124645892351275,0.1666666666666667 +1998,BruCap,90,F,0.1583333333333333,0.203125 +1998,BruCap,91,M,0.208,0.2142857142857143 +1998,BruCap,91,F,0.1715089034676664,0.07017543859649122 +1998,BruCap,92,M,0.2173913043478261,0.0 +1998,BruCap,92,F,0.1864801864801865,0.125 +1998,BruCap,93,M,0.2039473684210526,0.1333333333333333 +1998,BruCap,93,F,0.1884498480243161,0.1 +1998,BruCap,94,M,0.1720430107526882,0.0 +1998,BruCap,94,F,0.2375249500998004,0.1578947368421053 +1998,BruCap,95,M,0.2567567567567568,0.0 +1998,BruCap,95,F,0.2128205128205128,0.2413793103448276 +1998,BruCap,96,M,0.3148148148148149,0.0 +1998,BruCap,96,F,0.2340425531914894,0.3 +1998,BruCap,97,M,0.4782608695652174,0.0 +1998,BruCap,97,F,0.2631578947368421,0.1818181818181818 +1998,BruCap,98,M,0.2352941176470588,0.5 +1998,BruCap,98,F,0.2803030303030303,0.25 +1998,BruCap,99,M,0.4,0.0 +1998,BruCap,99,F,0.1927710843373494,0.0 +1998,BruCap,100,M,0.3333333333333333,0.5 +1998,BruCap,100,F,0.2093023255813954,0.4285714285714286 +1998,BruCap,101,M,0.4285714285714286,0.0 +1998,BruCap,101,F,0.3666666666666667,0.0 +1998,BruCap,102,M,0.6666666666666666,0.0 +1998,BruCap,102,F,0.4347826086956522,0.0 +1998,BruCap,103,M,0.5,0.0 +1998,BruCap,103,F,0.6,1.0 +1998,BruCap,104,M,1.0,0.0 +1998,BruCap,104,F,0.2222222222222222,0.0 +1998,BruCap,105,M,0.0,0.0 +1998,BruCap,105,F,0.4,0.0 +1998,BruCap,106,M,0.0,0.0 +1998,BruCap,106,F,0.0,0.0 +1998,BruCap,107,M,0.0,0.0 +1998,BruCap,107,F,0.0,0.0 +1998,BruCap,108,M,0.0,0.0 +1998,BruCap,108,F,0.0,0.0 +1998,BruCap,109,M,0.0,0.0 +1998,BruCap,109,F,0.0,0.0 +1998,BruCap,110,M,0.0,0.0 +1998,BruCap,110,F,0.0,0.0 +1998,BruCap,111,M,0.0,0.0 +1998,BruCap,111,F,0.0,0.0 +1998,BruCap,112,M,0.0,0.0 +1998,BruCap,112,F,0.0,0.0 +1998,BruCap,113,M,0.0,0.0 +1998,BruCap,113,F,0.0,0.0 +1998,BruCap,114,M,0.0,0.0 +1998,BruCap,114,F,0.0,0.0 +1998,BruCap,115,M,0.0,0.0 +1998,BruCap,115,F,0.0,0.0 +1998,BruCap,116,M,0.0,0.0 +1998,BruCap,116,F,0.0,0.0 +1998,BruCap,117,M,0.0,0.0 +1998,BruCap,117,F,0.0,0.0 +1998,BruCap,118,M,0.0,0.0 +1998,BruCap,118,F,0.0,0.0 +1998,BruCap,119,M,0.0,0.0 +1998,BruCap,119,F,0.0,0.0 +1998,BruCap,120,M,0.0,0.0 +1998,BruCap,120,F,0.0,0.0 +1998,Fla,0,M,0.0008709396471081577,0.001109877913429523 +1998,Fla,0,F,0.001007759750075582,0.001727115716753023 +1998,Fla,1,M,0.0002882952142994426,0.0005636978579481398 +1998,Fla,1,F,0.000500751126690035,0.0005733944954128443 +1998,Fla,2,M,0.0003181673560292714,0.001078167115902965 +1998,Fla,2,F,0.00023304591004427881,0.0 +1998,Fla,3,M,0.00034586844422085285,0.0 +1998,Fla,3,F,3.294024639304302e-05,0.0 +1998,Fla,4,M,0.0001806521542769398,0.0005279831045406547 +1998,Fla,4,F,0.0002174048077520343,0.0010989010989010991 +1998,Fla,5,M,0.0002607259769981749,0.0 +1998,Fla,5,F,0.0001816585424929607,0.0 +1998,Fla,6,M,8.568490803153206e-05,0.0 +1998,Fla,6,F,0.0002106974084218764,0.0 +1998,Fla,7,M,0.0001730852444829078,0.0005321979776476849 +1998,Fla,7,F,9.09394040437722e-05,0.0 +1998,Fla,8,M,8.931761343336905e-05,0.0 +1998,Fla,8,F,0.0001881526545203675,0.0 +1998,Fla,9,M,0.0001508432135638218,0.0005288207297726071 +1998,Fla,9,F,0.000189262507097344,0.0 +1998,Fla,10,M,9.117709631340607e-05,0.0005611672278338945 +1998,Fla,10,F,9.628345850182938e-05,0.0 +1998,Fla,11,M,9.066183136899366e-05,0.0 +1998,Fla,11,F,0.00019209835435743104,0.0006373486297004461 +1998,Fla,12,M,0.000247939007004277,0.0006414368184733802 +1998,Fla,12,F,0.0001299123091912959,0.000655307994757536 +1998,Fla,13,M,0.000151372952680815,0.0006191950464396285 +1998,Fla,13,F,0.0001907911472907657,0.0 +1998,Fla,14,M,0.0002652050919377652,0.0006184291898577612 +1998,Fla,14,F,0.000308005051282841,0.0 +1998,Fla,15,M,0.0006337318162177733,0.0005479452054794519 +1998,Fla,15,F,9.14968891057704e-05,0.0 +1998,Fla,16,M,0.000613685179502915,0.001027749229188078 +1998,Fla,16,F,0.0002384927259718579,0.0 +1998,Fla,17,M,0.0006237772548130086,0.0004524886877828054 +1998,Fla,17,F,0.0002362669816893089,0.00047348484848484855 +1998,Fla,18,M,0.0007763329359248066,0.0005411255411255411 +1998,Fla,18,F,0.0004127480173354168,0.0 +1998,Fla,19,M,0.001101352687018158,0.0 +1998,Fla,19,F,0.00047080979284369113,0.0 +1998,Fla,20,M,0.001236307179207039,0.0006583278472679394 +1998,Fla,20,F,0.00023821576392817797,0.0 +1998,Fla,21,M,0.001141886748257891,0.0012399256044637321 +1998,Fla,21,F,0.0004306632213608958,0.0 +1998,Fla,22,M,0.0009616829451540196,0.001788908765652952 +1998,Fla,22,F,0.00028446804475630566,0.0 +1998,Fla,23,M,0.0010141400092721366,0.001015744032503809 +1998,Fla,23,F,0.00045516613563950837,0.000408997955010225 +1998,Fla,24,M,0.001427611689620424,0.0 +1998,Fla,24,F,0.0005577572288272421,0.0 +1998,Fla,25,M,0.001023844806681934,0.0 +1998,Fla,25,F,0.00030839103983851534,0.0007122507122507122 +1998,Fla,26,M,0.0008565643980688368,0.0007147962830593281 +1998,Fla,26,F,0.0004260191176079026,0.00034059945504087187 +1998,Fla,27,M,0.001055992758906796,0.001032702237521515 +1998,Fla,27,F,0.0003400559784456826,0.0 +1998,Fla,28,M,0.001059081624933807,0.0012828736369467607 +1998,Fla,28,F,0.0003663387063010258,0.0003367003367003366 +1998,Fla,29,M,0.0012942084173324384,0.001298701298701299 +1998,Fla,29,F,0.0002059573153463945,0.0006793478260869565 +1998,Fla,30,M,0.0008133776703906605,0.002639392939623887 +1998,Fla,30,F,0.0004779513495836792,0.0 +1998,Fla,31,M,0.0009999767447268668,0.0002938583602703497 +1998,Fla,31,F,0.000552234147278446,0.0 +1998,Fla,32,M,0.0007836288733655742,0.0005989817310572028 +1998,Fla,32,F,0.0002561475409836065,0.0 +1998,Fla,33,M,0.0008173449195560526,0.0008713331397037468 +1998,Fla,33,F,0.0006414226311598693,0.0003274394237066143 +1998,Fla,34,M,0.001274215493596527,0.000608457560085184 +1998,Fla,34,F,0.0006692693809258228,0.000351493848857645 +1998,Fla,35,M,0.001243319882211801,0.001208459214501511 +1998,Fla,35,F,0.0006545832110692278,0.001108237901736239 +1998,Fla,36,M,0.0012275856021745802,0.0003238341968911917 +1998,Fla,36,F,0.0006029746750636473,0.0019716088328075713 +1998,Fla,37,M,0.001120322652924042,0.0003189792663476873 +1998,Fla,37,F,0.0007128075419636698,0.00038372985418265535 +1998,Fla,38,M,0.001315645214340533,0.0003529827038475115 +1998,Fla,38,F,0.0007872775940796725,0.002049180327868853 +1998,Fla,39,M,0.0017869108778199691,0.0003449465332873405 +1998,Fla,39,F,0.0009703354588300523,0.0004366812227074237 +1998,Fla,40,M,0.0017849880247638851,0.001454545454545455 +1998,Fla,40,F,0.001215606517521098,0.0004775549188156638 +1998,Fla,41,M,0.001793283338767525,0.001117734724292101 +1998,Fla,41,F,0.0011632323615990892,0.0027586206896551718 +1998,Fla,42,M,0.0020746398849517877,0.0007572889057175312 +1998,Fla,42,F,0.001291711517761034,0.0 +1998,Fla,43,M,0.002087432218436586,0.0003955696202531647 +1998,Fla,43,F,0.001792554758864552,0.0005227391531625719 +1998,Fla,44,M,0.002764999510619556,0.001788109074653554 +1998,Fla,44,F,0.0022816580048168338,0.0 +1998,Fla,45,M,0.002649331534404514,0.0008635578583765112 +1998,Fla,45,F,0.001503146416651805,0.0011730205278592382 +1998,Fla,46,M,0.003006475485661425,0.002233139794551139 +1998,Fla,46,F,0.002249212775528565,0.0 +1998,Fla,47,M,0.003547671840354767,0.003829787234042553 +1998,Fla,47,F,0.002015273652948664,0.0 +1998,Fla,48,M,0.004089238573425126,0.002532714225411566 +1998,Fla,48,F,0.001974070319585979,0.001801801801801802 +1998,Fla,49,M,0.0038429580390527632,0.004372540445999125 +1998,Fla,49,F,0.002607184241019699,0.004504504504504504 +1998,Fla,50,M,0.004565971769248832,0.006311992786293959 +1998,Fla,50,F,0.0035674351738459076,0.001265822784810127 +1998,Fla,51,M,0.0051383801383801395,0.003585835948005379 +1998,Fla,51,F,0.002960052390307793,0.003419972640218878 +1998,Fla,52,M,0.005536590263633495,0.0041884816753926715 +1998,Fla,52,F,0.003107664604571462,0.0 +1998,Fla,53,M,0.005547369333448904,0.005975013579576317 +1998,Fla,53,F,0.003329342016880348,0.002167630057803468 +1998,Fla,54,M,0.006570978682170543,0.007679648930334612 +1998,Fla,54,F,0.0029850746268656717,0.003930817610062893 +1998,Fla,55,M,0.007228748175436158,0.005906674542232723 +1998,Fla,55,F,0.004577538612062338,0.0023584905660377358 +1998,Fla,56,M,0.008321077482777304,0.008215962441314555 +1998,Fla,56,F,0.00330371383002962,0.0035492457852706297 +1998,Fla,57,M,0.008487952018519169,0.009080590238365494 +1998,Fla,57,F,0.005205301188315469,0.0045214770158251705 +1998,Fla,58,M,0.009411840287816005,0.005927682276229994 +1998,Fla,58,F,0.0051924251679902255,0.0045662100456621 +1998,Fla,59,M,0.01114283940654293,0.01155717761557178 +1998,Fla,59,F,0.004648651890951624,0.003690036900369004 +1998,Fla,60,M,0.01090932426362061,0.00821917808219178 +1998,Fla,60,F,0.00632931029133443,0.002952755905511811 +1998,Fla,61,M,0.01320779825670371,0.0105708245243129 +1998,Fla,61,F,0.005904082341426452,0.003134796238244514 +1998,Fla,62,M,0.013633470672964193,0.01208459214501511 +1998,Fla,62,F,0.006165033196332596,0.0066815144766147 +1998,Fla,63,M,0.014890334697162791,0.01386748844375963 +1998,Fla,63,F,0.007770897832817337,0.01067235859124867 +1998,Fla,64,M,0.01648923665916647,0.01583531274742676 +1998,Fla,64,F,0.008475104380881162,0.006818181818181818 +1998,Fla,65,M,0.019998013442373282,0.01440677966101695 +1998,Fla,65,F,0.00947824786963672,0.007528230865746549 +1998,Fla,66,M,0.02119041242635244,0.01508011310084826 +1998,Fla,66,F,0.009155098133078028,0.01075268817204301 +1998,Fla,67,M,0.02273275238521682,0.02318840579710145 +1998,Fla,67,F,0.010432999638161859,0.007731958762886598 +1998,Fla,68,M,0.02687385054235634,0.024830699774266368 +1998,Fla,68,F,0.01215058975601874,0.01321585903083701 +1998,Fla,69,M,0.02900309209753807,0.03128621089223639 +1998,Fla,69,F,0.01303538175046555,0.0145985401459854 +1998,Fla,70,M,0.03388854616491877,0.026041666666666668 +1998,Fla,70,F,0.01464088397790055,0.005217391304347826 +1998,Fla,71,M,0.03614252186899936,0.04189944134078212 +1998,Fla,71,F,0.01671966355523644,0.01757188498402556 +1998,Fla,72,M,0.03815199895593161,0.03157894736842106 +1998,Fla,72,F,0.01912558787667654,0.01215277777777778 +1998,Fla,73,M,0.04573604293774944,0.04580152671755725 +1998,Fla,73,F,0.020514105685235567,0.025 +1998,Fla,74,M,0.04801660071421678,0.03852327447833066 +1998,Fla,74,F,0.02341928904428905,0.03047619047619048 +1998,Fla,75,M,0.05099920063948842,0.06963249516441006 +1998,Fla,75,F,0.02805993383926834,0.03318584070796461 +1998,Fla,76,M,0.058046009336858086,0.06300813008130081 +1998,Fla,76,F,0.03116327016097058,0.03016241299303944 +1998,Fla,77,M,0.0605422954367823,0.06398104265402843 +1998,Fla,77,F,0.03872963497628377,0.0293398533007335 +1998,Fla,78,M,0.07045549519431676,0.046052631578947366 +1998,Fla,78,F,0.04098770924865136,0.04580152671755725 +1998,Fla,79,M,0.07952393832837436,0.0787037037037037 +1998,Fla,79,F,0.04924771849050399,0.05701754385964913 +1998,Fla,80,M,0.08782673637042569,0.08780487804878047 +1998,Fla,80,F,0.05522260273972603,0.05365853658536585 +1998,Fla,81,M,0.0992080033347228,0.1021505376344086 +1998,Fla,81,F,0.06303427338819206,0.04854368932038835 +1998,Fla,82,M,0.1075621764928671,0.08928571428571429 +1998,Fla,82,F,0.06735279703143597,0.06912442396313365 +1998,Fla,83,M,0.1235428281804359,0.1020408163265306 +1998,Fla,83,F,0.07963286148277422,0.0825242718446602 +1998,Fla,84,M,0.1302318798308298,0.1145038167938931 +1998,Fla,84,F,0.08795877150219375,0.1179245283018868 +1998,Fla,85,M,0.1434634974533107,0.1 +1998,Fla,85,F,0.09815469179426776,0.1052631578947368 +1998,Fla,86,M,0.1527272727272728,0.17 +1998,Fla,86,F,0.1134538152610442,0.06349206349206349 +1998,Fla,87,M,0.18011491381463896,0.1886792452830189 +1998,Fla,87,F,0.1329354871900402,0.09734513274336284 +1998,Fla,88,M,0.1898072525318524,0.1896551724137931 +1998,Fla,88,F,0.1403508771929825,0.2030075187969925 +1998,Fla,89,M,0.2009864364981504,0.1296296296296296 +1998,Fla,89,F,0.1438889675683331,0.1686746987951807 +1998,Fla,90,M,0.2130977130977131,0.1071428571428571 +1998,Fla,90,F,0.1645481455685182,0.2083333333333334 +1998,Fla,91,M,0.25,0.375 +1998,Fla,91,F,0.1918084153983886,0.2181818181818182 +1998,Fla,92,M,0.225140712945591,0.1739130434782609 +1998,Fla,92,F,0.2023378792095742,0.125 +1998,Fla,93,M,0.2765151515151515,0.2142857142857143 +1998,Fla,93,F,0.2298809094189823,0.2 +1998,Fla,94,M,0.2809430255402751,0.4545454545454545 +1998,Fla,94,F,0.2312889812889813,0.2 +1998,Fla,95,M,0.3,0.5 +1998,Fla,95,F,0.2381625441696113,0.3571428571428572 +1998,Fla,96,M,0.3707317073170732,0.4285714285714286 +1998,Fla,96,F,0.2742099898063201,0.1428571428571429 +1998,Fla,97,M,0.3381294964028777,0.1666666666666667 +1998,Fla,97,F,0.2945859872611465,0.1111111111111111 +1998,Fla,98,M,0.5104166666666666,0.5 +1998,Fla,98,F,0.3271767810026386,0.5555555555555556 +1998,Fla,99,M,0.4047619047619048,1.0 +1998,Fla,99,F,0.3487394957983193,0.2 +1998,Fla,100,M,0.4102564102564103,0.6666666666666666 +1998,Fla,100,F,0.3641975308641976,0.0 +1998,Fla,101,M,0.6111111111111112,0.0 +1998,Fla,101,F,0.3679245283018868,0.5 +1998,Fla,102,M,0.3636363636363637,0.0 +1998,Fla,102,F,0.3870967741935484,0.0 +1998,Fla,103,M,0.5,0.0 +1998,Fla,103,F,0.4444444444444444,0.0 +1998,Fla,104,M,0.0,0.0 +1998,Fla,104,F,0.6666666666666666,0.0 +1998,Fla,105,M,1.0,0.0 +1998,Fla,105,F,0.3333333333333333,0.0 +1998,Fla,106,M,0.0,0.0 +1998,Fla,106,F,0.5,0.0 +1998,Fla,107,M,1.0,0.0 +1998,Fla,107,F,0.0,0.0 +1998,Fla,108,M,0.0,0.0 +1998,Fla,108,F,0.0,0.0 +1998,Fla,109,M,0.0,0.0 +1998,Fla,109,F,0.0,0.0 +1998,Fla,110,M,0.0,0.0 +1998,Fla,110,F,0.0,0.0 +1998,Fla,111,M,0.0,0.0 +1998,Fla,111,F,0.0,0.0 +1998,Fla,112,M,0.0,0.0 +1998,Fla,112,F,0.0,0.0 +1998,Fla,113,M,0.0,0.0 +1998,Fla,113,F,0.0,0.0 +1998,Fla,114,M,0.0,0.0 +1998,Fla,114,F,0.0,0.0 +1998,Fla,115,M,0.0,0.0 +1998,Fla,115,F,0.0,0.0 +1998,Fla,116,M,0.0,0.0 +1998,Fla,116,F,0.0,0.0 +1998,Fla,117,M,0.0,0.0 +1998,Fla,117,F,0.0,0.0 +1998,Fla,118,M,0.0,0.0 +1998,Fla,118,F,0.0,0.0 +1998,Fla,119,M,0.0,0.0 +1998,Fla,119,F,0.0,0.0 +1998,Fla,120,M,0.0,0.0 +1998,Fla,120,F,0.0,0.0 +1998,Wal,0,M,0.001618821497949493,0.001895734597156398 +1998,Wal,0,F,0.001340257999664936,0.0 +1998,Wal,1,M,0.000475963826749167,0.0 +1998,Wal,1,F,5.496015388843089e-05,0.0 +1998,Wal,2,M,0.00016116035455278,0.0 +1998,Wal,2,F,0.00022396416573348263,0.0 +1998,Wal,3,M,5.3225463061528635e-05,0.0 +1998,Wal,3,F,0.00016642627316098969,0.001939864209505335 +1998,Wal,4,M,0.0002530108288634754,0.0 +1998,Wal,4,F,0.0003225112878950763,0.0008503401360544217 +1998,Wal,5,M,0.00024145257871354068,0.0 +1998,Wal,5,F,0.00010120433154539008,0.0 +1998,Wal,6,M,4.7052180868583256e-05,0.0 +1998,Wal,6,F,9.778038525471791e-05,0.0 +1998,Wal,7,M,0.0001430546945782271,0.0 +1998,Wal,7,F,0.0002978998063651259,0.0007639419404125286 +1998,Wal,8,M,4.753077617757498e-05,0.0 +1998,Wal,8,F,0.00024902878772786144,0.0 +1998,Wal,9,M,0.0001434994738352626,0.0 +1998,Wal,9,F,0.00015142337976983649,0.0007380073800738008 +1998,Wal,10,M,0.00014906091622776508,0.0006788866259334692 +1998,Wal,10,F,5.225752508361204e-05,0.0 +1998,Wal,11,M,4.950985246063966e-05,0.0 +1998,Wal,11,F,0.0003669147709403502,0.0007173601147776184 +1998,Wal,12,M,0.0003088326127239037,0.0 +1998,Wal,12,F,0.0001076368333243636,0.0 +1998,Wal,13,M,0.0003133486526007938,0.0007158196134574088 +1998,Wal,13,F,0.00027162103433289866,0.0 +1998,Wal,14,M,0.00015757130101370868,0.0 +1998,Wal,14,F,0.00016941495369324599,0.0 +1998,Wal,15,M,0.0005212133847597206,0.0 +1998,Wal,15,F,0.0002179123992155154,0.0 +1998,Wal,16,M,0.0007782908732423598,0.0 +1998,Wal,16,F,0.00026609898882384245,0.0005878894767783657 +1998,Wal,17,M,0.0010899465407172894,0.0 +1998,Wal,17,F,0.00032142283173514763,0.0 +1998,Wal,18,M,0.0016155930790077134,0.002232142857142857 +1998,Wal,18,F,0.0002769315978953199,0.0005387931034482759 +1998,Wal,19,M,0.0014298575438224858,0.0005717552887364207 +1998,Wal,19,F,0.0004425023507937387,0.0 +1998,Wal,20,M,0.001408156879107124,0.0005743825387708214 +1998,Wal,20,F,0.000275072894316994,0.0 +1998,Wal,21,M,0.0009342883836810962,0.0 +1998,Wal,21,F,0.00016262806960481383,0.0005165289256198346 +1998,Wal,22,M,0.001242107442293759,0.001049317943336831 +1998,Wal,22,F,0.00026916451335055994,0.0 +1998,Wal,23,M,0.001665993537964459,0.001333926189417519 +1998,Wal,23,F,0.00015917652676818592,0.0008699434536755111 +1998,Wal,24,M,0.0013303769401330381,0.002690238278247502 +1998,Wal,24,F,0.0003088803088803089,0.0004035512510088781 +1998,Wal,25,M,0.001113855392512955,0.0003539823008849558 +1998,Wal,25,F,0.0003541434787007994,0.0003676470588235294 +1998,Wal,26,M,0.0012967054077418119,0.001734304543877905 +1998,Wal,26,F,0.00034780880453145184,0.0 +1998,Wal,27,M,0.0011363074946889981,0.0003309066843150232 +1998,Wal,27,F,0.0006639427987742595,0.000715307582260372 +1998,Wal,28,M,0.001541751628785995,0.001287001287001287 +1998,Wal,28,F,0.0004568296025582458,0.00034376074252320387 +1998,Wal,29,M,0.0013224149331163221,0.0009375 +1998,Wal,29,F,0.0004096681687832857,0.0006478781988986073 +1998,Wal,30,M,0.001338953632531614,0.0009345794392523364 +1998,Wal,30,F,0.0005515166708448231,0.00033760972316002714 +1998,Wal,31,M,0.001798910929599378,0.001923076923076923 +1998,Wal,31,F,0.001020556932497449,0.0009168704156479216 +1998,Wal,32,M,0.0015025590458750062,0.0007855459544383348 +1998,Wal,32,F,0.0008445153420287135,0.0006161429451632777 +1998,Wal,33,M,0.001615001570140416,0.001062981663566303 +1998,Wal,33,F,0.0008083348302496857,0.0 +1998,Wal,34,M,0.0016878792025911233,0.00211864406779661 +1998,Wal,34,F,0.0008079357242246061,0.0003125 +1998,Wal,35,M,0.0018197088465845468,0.0027027027027027037 +1998,Wal,35,F,0.001005760263326323,0.000328515111695138 +1998,Wal,36,M,0.0013135842732255288,0.0008237232289950577 +1998,Wal,36,F,0.0008858965272856131,0.001589319771137953 +1998,Wal,37,M,0.002461706783369803,0.0007593014426727411 +1998,Wal,37,F,0.001039642001536862,0.001333777925975325 +1998,Wal,38,M,0.00234540616120157,0.0013351134846461947 +1998,Wal,38,F,0.0013943962699899779,0.0006684491978609625 +1998,Wal,39,M,0.002571756601607348,0.002651816494298595 +1998,Wal,39,F,0.001506758253933082,0.0010377032168799722 +1998,Wal,40,M,0.0031493145609485,0.002140754616002141 +1998,Wal,40,F,0.001848595518283061,0.001443522194153735 +1998,Wal,41,M,0.0032557920067946967,0.002601456815816858 +1998,Wal,41,F,0.0021832074956790693,0.001057455058160028 +1998,Wal,42,M,0.003811338732729871,0.0013620266957232359 +1998,Wal,42,F,0.001682047551938901,0.002183406113537118 +1998,Wal,43,M,0.003252810332456351,0.0025295109612141647 +1998,Wal,43,F,0.001696858518688374,0.0026455026455026467 +1998,Wal,44,M,0.004043383122443155,0.002940311673037342 +1998,Wal,44,F,0.002080059166127392,0.001659062629614268 +1998,Wal,45,M,0.004839946329308032,0.0024472315692872447 +1998,Wal,45,F,0.002302739790403684,0.001654944145635085 +1998,Wal,46,M,0.006370060714641187,0.0031857279388340237 +1998,Wal,46,F,0.002806049652810806,0.001720430107526882 +1998,Wal,47,M,0.0046695573450231094,0.005329153605015674 +1998,Wal,47,F,0.00273172569706104,0.0004154549231408392 +1998,Wal,48,M,0.005800019173617103,0.004213938411669369 +1998,Wal,48,F,0.003534734659251579,0.004063205417607224 +1998,Wal,49,M,0.006130375777996164,0.006254114549045424 +1998,Wal,49,F,0.003647305553022705,0.0029635901778154107 +1998,Wal,50,M,0.00738110810053256,0.002989040185984723 +1998,Wal,50,F,0.003991924382857668,0.0018717828731867109 +1998,Wal,51,M,0.007437619961612284,0.006004945249028611 +1998,Wal,51,F,0.003745491537963562,0.002982107355864811 +1998,Wal,52,M,0.006516969931604078,0.009760425909494237 +1998,Wal,52,F,0.004767652383826192,0.004169148302561049 +1998,Wal,53,M,0.00937055706346129,0.006230529595015576 +1998,Wal,53,F,0.004740211770499878,0.002310803004043905 +1998,Wal,54,M,0.00962803906628801,0.01001001001001001 +1998,Wal,54,F,0.004493942946463461,0.0025396825396825397 +1998,Wal,55,M,0.008983226011606647,0.01091476091476092 +1998,Wal,55,F,0.0045505408429690405,0.0019455252918287945 +1998,Wal,56,M,0.011600136472193791,0.007023230686115613 +1998,Wal,56,F,0.0059022585976233576,0.003364737550471064 +1998,Wal,57,M,0.01262626262626263,0.010608856088560893 +1998,Wal,57,F,0.00541757545908675,0.0034071550255536627 +1998,Wal,58,M,0.01235265052586998,0.01007049345417925 +1998,Wal,58,F,0.006552996564448403,0.005196304849884526 +1998,Wal,59,M,0.012943632567849693,0.014586709886547809 +1998,Wal,59,F,0.006791700417471493,0.002883506343713957 +1998,Wal,60,M,0.01344144933888524,0.01418067226890756 +1998,Wal,60,F,0.005491597194653963,0.005025125628140704 +1998,Wal,61,M,0.016514036931391682,0.01400107700592354 +1998,Wal,61,F,0.00628099173553719,0.005583126550868486 +1998,Wal,62,M,0.01773564712177968,0.015050167224080268 +1998,Wal,62,F,0.007805781570417411,0.00851581508515815 +1998,Wal,63,M,0.01918867649204728,0.016336056009334892 +1998,Wal,63,F,0.01009203427483339,0.009101941747572813 +1998,Wal,64,M,0.02363583309016633,0.01670506912442396 +1998,Wal,64,F,0.009756715661429296,0.007751937984496123 +1998,Wal,65,M,0.02278904453272005,0.02386237513873474 +1998,Wal,65,F,0.0114165890027959,0.006321112515802781 +1998,Wal,66,M,0.02731607629427793,0.02599009900990099 +1998,Wal,66,F,0.01329486309119711,0.010725552050473193 +1998,Wal,67,M,0.031247825179205237,0.027405247813411082 +1998,Wal,67,F,0.01296936059353231,0.009129640900791236 +1998,Wal,68,M,0.03195530726256983,0.03600248292985723 +1998,Wal,68,F,0.01566486678929567,0.01224226804123712 +1998,Wal,69,M,0.03592999845129317,0.03976908274534959 +1998,Wal,69,F,0.0164213242625066,0.01948924731182796 +1998,Wal,70,M,0.03838771593090212,0.03984575835475578 +1998,Wal,70,F,0.01792936915182614,0.013770491803278693 +1998,Wal,71,M,0.04281118535016086,0.0398970398970399 +1998,Wal,71,F,0.02048316163624315,0.018991486574983632 +1998,Wal,72,M,0.0457944710528527,0.057624736472241735 +1998,Wal,72,F,0.02189394385262786,0.01563562202583277 +1998,Wal,73,M,0.04809992027637523,0.05895522388059701 +1998,Wal,73,F,0.02804870660931726,0.024548736462093858 +1998,Wal,74,M,0.05613502749857766,0.04925723221266615 +1998,Wal,74,F,0.03110302878284317,0.029275808936825888 +1998,Wal,75,M,0.061430715357678835,0.06533575317604355 +1998,Wal,75,F,0.03129173821789735,0.03132728771640561 +1998,Wal,76,M,0.06755776603460781,0.07602956705385427 +1998,Wal,76,F,0.03557588463248841,0.034883720930232565 +1998,Wal,77,M,0.080545229244114,0.07393483709273183 +1998,Wal,77,F,0.04161162483487451,0.02176063303659743 +1998,Wal,78,M,0.07953020134228188,0.08779443254817987 +1998,Wal,78,F,0.04671587405400355,0.05563689604685212 +1998,Wal,79,M,0.09026687598116168,0.1310541310541311 +1998,Wal,79,F,0.04871020856201976,0.06415929203539822 +1998,Wal,80,M,0.098010098010098,0.1095890410958904 +1998,Wal,80,F,0.06149535466745318,0.039408866995073885 +1998,Wal,81,M,0.11164095371669,0.1340579710144928 +1998,Wal,81,F,0.0607188887297723,0.07954545454545454 +1998,Wal,82,M,0.1135560988861723,0.1318681318681319 +1998,Wal,82,F,0.07566821433053081,0.0631163708086785 +1998,Wal,83,M,0.1278467908902692,0.1423487544483986 +1998,Wal,83,F,0.08425646189996643,0.08445297504798464 +1998,Wal,84,M,0.1506807866868381,0.1449814126394052 +1998,Wal,84,F,0.09716649949849547,0.1051546391752577 +1998,Wal,85,M,0.1471877282688094,0.1111111111111111 +1998,Wal,85,F,0.1089446413962367,0.161592505854801 +1998,Wal,86,M,0.163470757430489,0.2105263157894737 +1998,Wal,86,F,0.1187378009108653,0.1206896551724138 +1998,Wal,87,M,0.1970965940815187,0.1759259259259259 +1998,Wal,87,F,0.1317900109369304,0.1003236245954693 +1998,Wal,88,M,0.1975218658892128,0.3098591549295775 +1998,Wal,88,F,0.1523646479777445,0.164179104477612 +1998,Wal,89,M,0.1962441314553991,0.2207792207792208 +1998,Wal,89,F,0.1621359223300971,0.1788990825688074 +1998,Wal,90,M,0.220462850182704,0.4054054054054055 +1998,Wal,90,F,0.1910509272887842,0.1888111888111888 +1998,Wal,91,M,0.2534775888717156,0.2857142857142857 +1998,Wal,91,F,0.1983089930822444,0.1481481481481482 +1998,Wal,92,M,0.2853932584269663,0.28125 +1998,Wal,92,F,0.2102040816326531,0.2434782608695653 +1998,Wal,93,M,0.2564102564102564,0.3333333333333333 +1998,Wal,93,F,0.21590174531351,0.1547619047619048 +1998,Wal,94,M,0.2894736842105264,0.05882352941176471 +1998,Wal,94,F,0.237347294938918,0.326530612244898 +1998,Wal,95,M,0.3333333333333333,0.3076923076923077 +1998,Wal,95,F,0.2972258916776751,0.2678571428571429 +1998,Wal,96,M,0.3535353535353536,0.2857142857142857 +1998,Wal,96,F,0.29248366013071897,0.2121212121212121 +1998,Wal,97,M,0.42,0.1666666666666667 +1998,Wal,97,F,0.3461538461538462,0.1904761904761905 +1998,Wal,98,M,0.2972972972972973,0.0 +1998,Wal,98,F,0.3212669683257919,0.125 +1998,Wal,99,M,0.38095238095238093,0.0 +1998,Wal,99,F,0.2461538461538462,0.375 +1998,Wal,100,M,0.4545454545454545,0.5 +1998,Wal,100,F,0.3737373737373738,0.4444444444444444 +1998,Wal,101,M,0.6,0.0 +1998,Wal,101,F,0.3529411764705883,0.3333333333333333 +1998,Wal,102,M,0.6666666666666666,0.0 +1998,Wal,102,F,0.4,0.0 +1998,Wal,103,M,0.5,0.0 +1998,Wal,103,F,0.5,1.0 +1998,Wal,104,M,0.0,0.0 +1998,Wal,104,F,0.5,0.0 +1998,Wal,105,M,0.0,0.0 +1998,Wal,105,F,0.2857142857142857,0.0 +1998,Wal,106,M,0.0,0.0 +1998,Wal,106,F,0.5,0.0 +1998,Wal,107,M,0.0,0.0 +1998,Wal,107,F,0.5,0.0 +1998,Wal,108,M,0.0,0.0 +1998,Wal,108,F,1.0,0.0 +1998,Wal,109,M,0.0,0.0 +1998,Wal,109,F,0.0,0.0 +1998,Wal,110,M,0.0,0.0 +1998,Wal,110,F,0.0,0.0 +1998,Wal,111,M,0.0,0.0 +1998,Wal,111,F,0.0,0.0 +1998,Wal,112,M,0.0,0.0 +1998,Wal,112,F,0.0,0.0 +1998,Wal,113,M,0.0,0.0 +1998,Wal,113,F,0.0,0.0 +1998,Wal,114,M,0.0,0.0 +1998,Wal,114,F,0.0,0.0 +1998,Wal,115,M,0.0,0.0 +1998,Wal,115,F,0.0,0.0 +1998,Wal,116,M,0.0,0.0 +1998,Wal,116,F,0.0,0.0 +1998,Wal,117,M,0.0,0.0 +1998,Wal,117,F,0.0,0.0 +1998,Wal,118,M,0.0,0.0 +1998,Wal,118,F,0.0,0.0 +1998,Wal,119,M,0.0,0.0 +1998,Wal,119,F,0.0,0.0 +1998,Wal,120,M,0.0,0.0 +1998,Wal,120,F,0.0,0.0 +1999,BruCap,0,M,0.0008179959100204499,0.0006285355122564425 +1999,BruCap,0,F,0.00107342206955775,0.0 +1999,BruCap,1,M,0.00103476821192053,0.0005913660555884093 +1999,BruCap,1,F,0.0,0.0006333122229259026 +1999,BruCap,2,M,0.000225022502250225,0.0 +1999,BruCap,2,F,0.00022747952684258417,0.0006203473945409428 +1999,BruCap,3,M,0.0,0.0 +1999,BruCap,3,F,0.00023975065931431308,0.0 +1999,BruCap,4,M,0.0006978367062107465,0.0 +1999,BruCap,4,F,0.0,0.0 +1999,BruCap,5,M,0.0002371354043158644,0.0 +1999,BruCap,5,F,0.0002520796571716663,0.0 +1999,BruCap,6,M,0.0,0.001176470588235294 +1999,BruCap,6,F,0.00024758603614756134,0.0 +1999,BruCap,7,M,0.0004870920603994155,0.0 +1999,BruCap,7,F,0.0,0.0 +1999,BruCap,8,M,0.0,0.0 +1999,BruCap,8,F,0.0,0.0 +1999,BruCap,9,M,0.0,0.0 +1999,BruCap,9,F,0.0,0.0 +1999,BruCap,10,M,0.00025380710659898484,0.0006261740763932372 +1999,BruCap,10,F,0.0,0.0006609385327164572 +1999,BruCap,11,M,0.0002619172341540074,0.0 +1999,BruCap,11,F,0.0002715915263443781,0.0 +1999,BruCap,12,M,0.0005184033177812338,0.0 +1999,BruCap,12,F,0.0,0.0 +1999,BruCap,13,M,0.0005209690023443605,0.0 +1999,BruCap,13,F,0.0,0.0 +1999,BruCap,14,M,0.0002633658151171978,0.0 +1999,BruCap,14,F,0.0,0.0 +1999,BruCap,15,M,0.0005452562704471102,0.0006743088334457181 +1999,BruCap,15,F,0.0,0.0 +1999,BruCap,16,M,0.0,0.0 +1999,BruCap,16,F,0.0,0.0 +1999,BruCap,17,M,0.0005518763796909492,0.001083423618634886 +1999,BruCap,17,F,0.0002902757619738752,0.0005555555555555557 +1999,BruCap,18,M,0.001075557945684324,0.000580046403712297 +1999,BruCap,18,F,0.00026845637583892615,0.0 +1999,BruCap,19,M,0.0002508780732563975,0.0 +1999,BruCap,19,F,0.0007847240387130526,0.0005747126436781607 +1999,BruCap,20,M,0.0002531645569620254,0.0006086427267194157 +1999,BruCap,20,F,0.0009606147934678194,0.0005045408678102925 +1999,BruCap,21,M,0.0009796718099436687,0.0 +1999,BruCap,21,F,0.0004775549188156638,0.0 +1999,BruCap,22,M,0.001230314960629921,0.0005192107995846313 +1999,BruCap,22,F,0.0002322340919647004,0.0004470272686633885 +1999,BruCap,23,M,0.001386001386001386,0.000501002004008016 +1999,BruCap,23,F,0.0002272727272727273,0.0 +1999,BruCap,24,M,0.0009057971014492754,0.001271186440677966 +1999,BruCap,24,F,0.000855431993156544,0.0 +1999,BruCap,25,M,0.001413284877851807,0.0 +1999,BruCap,25,F,0.000975800156128025,0.0 +1999,BruCap,26,M,0.001357378320729106,0.0 +1999,BruCap,26,F,0.0001898614011771407,0.0003234152652005175 +1999,BruCap,27,M,0.001146569845213071,0.0009430996541967935 +1999,BruCap,27,F,0.0001914608462569405,0.00030229746070133015 +1999,BruCap,28,M,0.001157854110382092,0.002048580626280363 +1999,BruCap,28,F,0.0001934610176049526,0.0 +1999,BruCap,29,M,0.001202645820805773,0.0020283975659229213 +1999,BruCap,29,F,0.0004063388866314506,0.0006009615384615385 +1999,BruCap,30,M,0.001854905193734543,0.001691570341133352 +1999,BruCap,30,F,0.0006342494714587737,0.0 +1999,BruCap,31,M,0.0014653548252041028,0.0005971931919976113 +1999,BruCap,31,F,0.0004351610095735422,0.0003177629488401653 +1999,BruCap,32,M,0.0014919011082693947,0.0014168319637291019 +1999,BruCap,32,F,0.0008733624454148473,0.0 +1999,BruCap,33,M,0.002254560360729658,0.001453911020645537 +1999,BruCap,33,F,0.0012933821944384571,0.0 +1999,BruCap,34,M,0.001680319260659525,0.0008733624454148473 +1999,BruCap,34,F,0.001095770326539557,0.0003129890453834116 +1999,BruCap,35,M,0.001715265866209263,0.0 +1999,BruCap,35,F,0.0006622516556291393,0.0003513703443429375 +1999,BruCap,36,M,0.0020515158422612268,0.0003171582619727244 +1999,BruCap,36,F,0.001830663615560641,0.0007215007215007215 +1999,BruCap,37,M,0.0016014641958361927,0.0007047216349541931 +1999,BruCap,37,F,0.001573741007194245,0.0 +1999,BruCap,38,M,0.0028979045920642,0.0014357501794687731 +1999,BruCap,38,F,0.001320713185119965,0.000370919881305638 +1999,BruCap,39,M,0.0031432420296362822,0.0015600624024961 +1999,BruCap,39,F,0.0006591957811470006,0.00122799836266885 +1999,BruCap,40,M,0.0025522041763341072,0.001242750621375311 +1999,BruCap,40,F,0.0019995556542990447,0.0008583690987124463 +1999,BruCap,41,M,0.003489995346672871,0.0004604051565377533 +1999,BruCap,41,F,0.003357206803939123,0.001352569882777277 +1999,BruCap,42,M,0.00192492781520693,0.0008768084173608067 +1999,BruCap,42,F,0.0017953321364452427,0.00045024763619990995 +1999,BruCap,43,M,0.004750593824228029,0.000903750564844103 +1999,BruCap,43,F,0.002474690663667042,0.0 +1999,BruCap,44,M,0.004523809523809525,0.002496255616575138 +1999,BruCap,44,F,0.001841196777905639,0.0 +1999,BruCap,45,M,0.00496336563460175,0.002553626149131767 +1999,BruCap,45,F,0.003122908766451038,0.001624255549539795 +1999,BruCap,46,M,0.004903105300023348,0.0046391752577319605 +1999,BruCap,46,F,0.00311873468478503,0.0005310674455655868 +1999,BruCap,47,M,0.005642787046123651,0.003344481605351171 +1999,BruCap,47,F,0.0016,0.0006119951040391675 +1999,BruCap,48,M,0.007545271629778672,0.004280363830925629 +1999,BruCap,48,F,0.003139013452914798,0.001114827201783724 +1999,BruCap,49,M,0.0062940584088620345,0.005275498241500586 +1999,BruCap,49,F,0.005221339387060159,0.00129366106080207 +1999,BruCap,50,M,0.007064555420219245,0.0046109510086455325 +1999,BruCap,50,F,0.004226918798665183,0.003152585119798235 +1999,BruCap,51,M,0.008033106134371958,0.0047590719809637114 +1999,BruCap,51,F,0.004272591326639607,0.0013522650439486141 +1999,BruCap,52,M,0.01051122790253225,0.003265839320705422 +1999,BruCap,52,F,0.003990246065174018,0.0034916201117318442 +1999,BruCap,53,M,0.008766968325791855,0.005021520803443328 +1999,BruCap,53,F,0.0027777777777777783,0.003134796238244514 +1999,BruCap,54,M,0.0106703146374829,0.010373443983402493 +1999,BruCap,54,F,0.005427088249174139,0.0007917656373713379 +1999,BruCap,55,M,0.01487093153759821,0.004590665646518746 +1999,BruCap,55,F,0.0067635270541082145,0.004258943781942078 +1999,BruCap,56,M,0.01252884932410155,0.006671608598962194 +1999,BruCap,56,F,0.006117098747451209,0.0025575447570332487 +1999,BruCap,57,M,0.009384384384384385,0.005226480836236934 +1999,BruCap,57,F,0.006182883176049463,0.001001001001001001 +1999,BruCap,58,M,0.014571331751948491,0.008534850640113799 +1999,BruCap,58,F,0.004760487950014877,0.006172839506172839 +1999,BruCap,59,M,0.01645692158760891,0.00726978998384491 +1999,BruCap,59,F,0.006764069264069264,0.00272975432211101 +1999,BruCap,60,M,0.0160392798690671,0.00878594249201278 +1999,BruCap,60,F,0.006067291781577496,0.004911591355599214 +1999,BruCap,61,M,0.01749663526244953,0.006003430531732418 +1999,BruCap,61,F,0.008666480290746436,0.004343105320304018 +1999,BruCap,62,M,0.01667824878387769,0.015665796344647518 +1999,BruCap,62,F,0.006808510638297872,0.01017293997965412 +1999,BruCap,63,M,0.01779483600837404,0.01182266009852217 +1999,BruCap,63,F,0.007823414361553507,0.007423117709437964 +1999,BruCap,64,M,0.01921165948989732,0.01303911735205617 +1999,BruCap,64,F,0.009917355371900829,0.002406738868832732 +1999,BruCap,65,M,0.02438186813186813,0.014705882352941181 +1999,BruCap,65,F,0.01140487299118715,0.01243093922651934 +1999,BruCap,66,M,0.0227125243348475,0.02304147465437788 +1999,BruCap,66,F,0.01188707280832095,0.006811989100817439 +1999,BruCap,67,M,0.02774234693877551,0.02524544179523142 +1999,BruCap,67,F,0.01164200824642251,0.008759124087591242 +1999,BruCap,68,M,0.0327597617471873,0.02088452088452089 +1999,BruCap,68,F,0.015562472209871059,0.009655172413793104 +1999,BruCap,69,M,0.036935704514363885,0.02615384615384616 +1999,BruCap,69,F,0.01657329598506069,0.014814814814814819 +1999,BruCap,70,M,0.03725222146274778,0.024054982817869417 +1999,BruCap,70,F,0.014441287878787882,0.01230228471001758 +1999,BruCap,71,M,0.02520411785587505,0.043478260869565216 +1999,BruCap,71,F,0.016643225503985,0.008298755186721992 +1999,BruCap,72,M,0.04534356470177886,0.028260869565217388 +1999,BruCap,72,F,0.01987802123334086,0.0130718954248366 +1999,BruCap,73,M,0.04285212504390587,0.05128205128205128 +1999,BruCap,73,F,0.025806451612903236,0.013986013986013993 +1999,BruCap,74,M,0.0448121337469838,0.045045045045045036 +1999,BruCap,74,F,0.02309871431684463,0.016990291262135918 +1999,BruCap,75,M,0.0543356903609974,0.04189944134078212 +1999,BruCap,75,F,0.02706766917293233,0.02144772117962467 +1999,BruCap,76,M,0.059190031152647975,0.04180064308681672 +1999,BruCap,76,F,0.030210157618213662,0.03560830860534125 +1999,BruCap,77,M,0.07008995502248876,0.03180212014134276 +1999,BruCap,77,F,0.03445305770887167,0.04040404040404042 +1999,BruCap,78,M,0.06820049301561218,0.07423580786026203 +1999,BruCap,78,F,0.03614718614718615,0.04155124653739612 +1999,BruCap,79,M,0.07779670641680864,0.06206896551724138 +1999,BruCap,79,F,0.04396284829721362,0.02666666666666667 +1999,BruCap,80,M,0.09395973154362416,0.05982905982905984 +1999,BruCap,80,F,0.04878048780487805,0.06289308176100629 +1999,BruCap,81,M,0.07574206755373593,0.07142857142857142 +1999,BruCap,81,F,0.06039963669391463,0.0379746835443038 +1999,BruCap,82,M,0.1158342189160468,0.08641975308641975 +1999,BruCap,82,F,0.0623637156563454,0.06293706293706294 +1999,BruCap,83,M,0.1214028776978417,0.1097560975609756 +1999,BruCap,83,F,0.07366412213740459,0.1180555555555556 +1999,BruCap,84,M,0.1142857142857143,0.08235294117647059 +1999,BruCap,84,F,0.08780160857908847,0.06790123456790123 +1999,BruCap,85,M,0.1272015655577299,0.1311475409836066 +1999,BruCap,85,F,0.0958955223880597,0.08163265306122447 +1999,BruCap,86,M,0.1518386714116252,0.1754385964912281 +1999,BruCap,86,F,0.1034340091021928,0.1 +1999,BruCap,87,M,0.1473533619456366,0.1276595744680851 +1999,BruCap,87,F,0.1112158341187559,0.08653846153846154 +1999,BruCap,88,M,0.1618181818181818,0.1764705882352941 +1999,BruCap,88,F,0.1275272161741835,0.1565217391304348 +1999,BruCap,89,M,0.1701631701631702,0.2666666666666667 +1999,BruCap,89,F,0.1536964980544747,0.06818181818181818 +1999,BruCap,90,M,0.2403314917127072,0.09090909090909093 +1999,BruCap,90,F,0.1582840236686391,0.1379310344827586 +1999,BruCap,91,M,0.2445255474452555,0.2 +1999,BruCap,91,F,0.1769019248395967,0.14 +1999,BruCap,92,M,0.2694300518134715,0.125 +1999,BruCap,92,F,0.204337899543379,0.14893617021276598 +1999,BruCap,93,M,0.2605633802816902,0.3333333333333333 +1999,BruCap,93,F,0.2217327459618209,0.2093023255813954 +1999,BruCap,94,M,0.3416666666666667,0.3846153846153847 +1999,BruCap,94,F,0.2243346007604563,0.32 +1999,BruCap,95,M,0.24,0.3333333333333333 +1999,BruCap,95,F,0.2122015915119364,0.2142857142857143 +1999,BruCap,96,M,0.2745098039215687,0.1428571428571429 +1999,BruCap,96,F,0.2842809364548495,0.2631578947368421 +1999,BruCap,97,M,0.4594594594594595,0.0 +1999,BruCap,97,F,0.326829268292683,0.1666666666666667 +1999,BruCap,98,M,0.4166666666666667,0.3333333333333333 +1999,BruCap,98,F,0.3385826771653544,0.2 +1999,BruCap,99,M,0.3571428571428572,0.0 +1999,BruCap,99,F,0.3020833333333333,0.0 +1999,BruCap,100,M,0.4,0.5 +1999,BruCap,100,F,0.3384615384615385,0.2 +1999,BruCap,101,M,0.5,0.0 +1999,BruCap,101,F,0.3235294117647059,0.0 +1999,BruCap,102,M,0.5,0.0 +1999,BruCap,102,F,0.3888888888888889,0.3333333333333333 +1999,BruCap,103,M,0.0,0.0 +1999,BruCap,103,F,0.5384615384615384,0.25 +1999,BruCap,104,M,1.0,0.0 +1999,BruCap,104,F,0.25,0.0 +1999,BruCap,105,M,0.0,0.0 +1999,BruCap,105,F,0.5714285714285714,0.0 +1999,BruCap,106,M,0.0,0.0 +1999,BruCap,106,F,0.3333333333333333,0.0 +1999,BruCap,107,M,0.0,0.0 +1999,BruCap,107,F,0.0,0.0 +1999,BruCap,108,M,0.0,0.0 +1999,BruCap,108,F,0.0,0.0 +1999,BruCap,109,M,0.0,0.0 +1999,BruCap,109,F,0.0,0.0 +1999,BruCap,110,M,0.0,0.0 +1999,BruCap,110,F,0.0,0.0 +1999,BruCap,111,M,0.0,0.0 +1999,BruCap,111,F,0.0,0.0 +1999,BruCap,112,M,0.0,0.0 +1999,BruCap,112,F,0.0,0.0 +1999,BruCap,113,M,0.0,0.0 +1999,BruCap,113,F,0.0,0.0 +1999,BruCap,114,M,0.0,0.0 +1999,BruCap,114,F,0.0,0.0 +1999,BruCap,115,M,0.0,0.0 +1999,BruCap,115,F,0.0,0.0 +1999,BruCap,116,M,0.0,0.0 +1999,BruCap,116,F,0.0,0.0 +1999,BruCap,117,M,0.0,0.0 +1999,BruCap,117,F,0.0,0.0 +1999,BruCap,118,M,0.0,0.0 +1999,BruCap,118,F,0.0,0.0 +1999,BruCap,119,M,0.0,0.0 +1999,BruCap,119,F,0.0,0.0 +1999,BruCap,120,M,0.0,0.0 +1999,BruCap,120,F,0.0,0.0 +1999,Fla,0,M,0.001079984291137583,0.001176470588235294 +1999,Fla,0,F,0.0006587386887633048,0.001204819277108434 +1999,Fla,1,M,0.0003522141462008902,0.0005614823133071309 +1999,Fla,1,F,0.0003333555570371358,0.001189060642092747 +1999,Fla,2,M,0.00019092471202189268,0.0005743825387708214 +1999,Fla,2,F,0.00013280212483399742,0.0 +1999,Fla,3,M,0.00018983136646945304,0.0005621135469364812 +1999,Fla,3,F,0.0002978554408260525,0.0 +1999,Fla,4,M,0.00025033638952342207,0.0 +1999,Fla,4,F,0.00016394517673290048,0.0 +1999,Fla,5,M,0.0002396285757076532,0.0 +1999,Fla,5,F,9.26497838171711e-05,0.0 +1999,Fla,6,M,8.655011251514626e-05,0.0 +1999,Fla,6,F,0.0002711251694532309,0.0 +1999,Fla,7,M,0.0001137850600216192,0.0 +1999,Fla,7,F,5.9955632831704544e-05,0.0005482456140350877 +1999,Fla,8,M,8.623167576889911e-05,0.0005506607929515419 +1999,Fla,8,F,0.00012067821154890493,0.0 +1999,Fla,9,M,0.0001482799525504152,0.001106194690265487 +1999,Fla,9,F,0.0001248946201642364,0.0 +1999,Fla,10,M,0.00015010056738014467,0.0 +1999,Fla,10,F,6.282393591958538e-05,0.0 +1999,Fla,11,M,3.02535245356084e-05,0.0 +1999,Fla,11,F,0.00025562372188139056,0.0 +1999,Fla,12,M,0.00014985763524651586,0.0 +1999,Fla,12,F,0.00025447720838502405,0.0007107320540156361 +1999,Fla,13,M,0.00015453084435653356,0.0 +1999,Fla,13,F,0.0002591428849081663,0.0006738544474393531 +1999,Fla,14,M,0.0003624501631025734,0.0006273525721455458 +1999,Fla,14,F,0.0002539198882752492,0.0 +1999,Fla,15,M,0.0005299885169154668,0.0 +1999,Fla,15,F,0.0001536759282026063,0.0006134969325153375 +1999,Fla,16,M,0.0004315429097499928,0.0005567928730512249 +1999,Fla,16,F,0.0004564264849074976,0.0 +1999,Fla,17,M,0.0009736285746077668,0.001046572475143904 +1999,Fla,17,F,0.00023771319902537592,0.0 +1999,Fla,18,M,0.000951208594449418,0.001658374792703151 +1999,Fla,18,F,0.0003499460499839609,0.001104972375690608 +1999,Fla,19,M,0.001128885707205595,0.0012391573729863688 +1999,Fla,19,F,0.0003798392987582177,0.0005494505494505496 +1999,Fla,20,M,0.0009854990848937068,0.0006426735218508997 +1999,Fla,20,F,0.0002642706131078224,0.0 +1999,Fla,21,M,0.0010347503664740881,0.0006195786864931846 +1999,Fla,21,F,0.00047576568539994053,0.0 +1999,Fla,22,M,0.001494111443135877,0.0 +1999,Fla,22,F,0.00036911719470932014,0.0004522840343735866 +1999,Fla,23,M,0.001023911341323857,0.001061007957559682 +1999,Fla,23,F,0.0003798790718288012,0.00043572984749455336 +1999,Fla,24,M,0.0008430722716437003,0.0009153318077803203 +1999,Fla,24,F,0.0002432424214783059,0.0 +1999,Fla,25,M,0.0009849444209933868,0.00253592561284869 +1999,Fla,25,F,0.0003830175893462185,0.0 +1999,Fla,26,M,0.001406621943302316,0.0 +1999,Fla,26,F,0.0004770456841396341,0.0 +1999,Fla,27,M,0.0007010801828001661,0.001040221914008322 +1999,Fla,27,F,0.0003990210683124069,0.000333889816360601 +1999,Fla,28,M,0.0008306275013214527,0.0006811989100817437 +1999,Fla,28,F,0.00028773214752811935,0.0 +1999,Fla,29,M,0.00103287567703741,0.000631911532385466 +1999,Fla,29,F,0.0006004594820384294,0.0003235198964736332 +1999,Fla,30,M,0.0008952551477170994,0.0006281407035175878 +1999,Fla,30,F,0.0005142181313313106,0.0 +1999,Fla,31,M,0.001435063381966037,0.001311475409836066 +1999,Fla,31,F,0.0002512752217503832,0.001025641025641026 +1999,Fla,32,M,0.0008591863273267695,0.0002901073397156948 +1999,Fla,32,F,0.0006241298190023522,0.0 +1999,Fla,33,M,0.0008720540226286839,0.001485884101040119 +1999,Fla,33,F,0.00044167557766516336,0.0009937065253395165 +1999,Fla,34,M,0.0011597190902648028,0.0005808887598024977 +1999,Fla,34,F,0.0006628369421122402,0.000321646831778707 +1999,Fla,35,M,0.001121269622218389,0.0018461538461538461 +1999,Fla,35,F,0.0005569045020159943,0.00104602510460251 +1999,Fla,36,M,0.001200244413407821,0.0027734976887519264 +1999,Fla,36,F,0.000698733264211333,0.00111358574610245 +1999,Fla,37,M,0.001468364417366149,0.001329787234042553 +1999,Fla,37,F,0.0007814593194605697,0.0007914523149980214 +1999,Fla,38,M,0.001411922904527118,0.001272669424117086 +1999,Fla,38,F,0.0008039877793857532,0.001135073779795687 +1999,Fla,39,M,0.0014901823281907429,0.001773049645390071 +1999,Fla,39,F,0.001102015113350126,0.001213101496158512 +1999,Fla,40,M,0.0017864719412250733,0.0014030164854437039 +1999,Fla,40,F,0.001176823499550038,0.0 +1999,Fla,41,M,0.001968370325120478,0.002571638501102131 +1999,Fla,41,F,0.001520432270590162,0.001442307692307693 +1999,Fla,42,M,0.00202759392187937,0.0007613247049866769 +1999,Fla,42,F,0.00132899826755583,0.001378043178686266 +1999,Fla,43,M,0.0020060890703547237,0.001523809523809524 +1999,Fla,43,F,0.001603522963884834,0.002016129032258065 +1999,Fla,44,M,0.002571497236241288,0.001200960768614892 +1999,Fla,44,F,0.001375887570329968,0.003146303093864709 +1999,Fla,45,M,0.002795282348037173,0.001339883876730684 +1999,Fla,45,F,0.001700766614205209,0.0027855153203342627 +1999,Fla,46,M,0.003143958932036451,0.00172191132156694 +1999,Fla,46,F,0.0018360321305622848,0.0011737089201877939 +1999,Fla,47,M,0.00324449594438007,0.0017993702204228519 +1999,Fla,47,F,0.001880744880930307,0.0025332488917036104 +1999,Fla,48,M,0.003660992128866923,0.0047909407665505215 +1999,Fla,48,F,0.002389803505045141,0.0017996400719856032 +1999,Fla,49,M,0.004443866943866944,0.004284490145672665 +1999,Fla,49,F,0.002618010846044934,0.001202645820805773 +1999,Fla,50,M,0.005157055789967183,0.0026619343389529732 +1999,Fla,50,F,0.002903447183656232,0.001287001287001287 +1999,Fla,51,M,0.005137345355420425,0.0058850158442734285 +1999,Fla,51,F,0.002990015484008757,0.004369538077403246 +1999,Fla,52,M,0.0055688959280641714,0.004504504504504504 +1999,Fla,52,F,0.00259972164596518,0.0034411562284927736 +1999,Fla,53,M,0.005506703185815194,0.007438894792773645 +1999,Fla,53,F,0.0031159905646640854,0.001530221882172915 +1999,Fla,54,M,0.007145969498910675,0.003313086692435119 +1999,Fla,54,F,0.0035746725658530867,0.002175489485134155 +1999,Fla,55,M,0.00715983182012065,0.007242339832869081 +1999,Fla,55,F,0.003787300326807367,0.0031670625494853518 +1999,Fla,56,M,0.009062598411420974,0.0053699284009546535 +1999,Fla,56,F,0.004525998175566627,0.0031446540880503146 +1999,Fla,57,M,0.01036915760339921,0.00661455201443175 +1999,Fla,57,F,0.0047227300426569176,0.004428697962798938 +1999,Fla,58,M,0.009654148100997241,0.009826589595375721 +1999,Fla,58,F,0.004438938783937236,0.0030326004548900678 +1999,Fla,59,M,0.009526895657809462,0.009685230024213077 +1999,Fla,59,F,0.00579950289975145,0.007332722273143905 +1999,Fla,60,M,0.011383235598482241,0.01125703564727955 +1999,Fla,60,F,0.0058120275845454285,0.0027855153203342627 +1999,Fla,61,M,0.012221609881025709,0.01404494382022472 +1999,Fla,61,F,0.005650070235679725,0.004945598417408506 +1999,Fla,62,M,0.01367694121610241,0.009461426491994178 +1999,Fla,62,F,0.00673208218221079,0.008385744234800839 +1999,Fla,63,M,0.01548019146552602,0.019230769230769232 +1999,Fla,63,F,0.0067735165044838785,0.004459308807134894 +1999,Fla,64,M,0.01670295278269152,0.014251781472684091 +1999,Fla,64,F,0.007548111412619693,0.014254385964912282 +1999,Fla,65,M,0.01805645629245315,0.01479046836483156 +1999,Fla,65,F,0.007793840351979888,0.007990867579908675 +1999,Fla,66,M,0.02066869300911854,0.02181500872600349 +1999,Fla,66,F,0.008875203767433436,0.003787878787878789 +1999,Fla,67,M,0.0228151188643749,0.01828681424446583 +1999,Fla,67,F,0.01007845503922752,0.01384615384615385 +1999,Fla,68,M,0.02410997532604864,0.02014098690835851 +1999,Fla,68,F,0.01148409893992933,0.01953125 +1999,Fla,69,M,0.02753142592735406,0.02453271028037383 +1999,Fla,69,F,0.01302185577803953,0.02714932126696833 +1999,Fla,70,M,0.030944034812039167,0.03125 +1999,Fla,70,F,0.01545298454701546,0.01343283582089552 +1999,Fla,71,M,0.03395600187226076,0.037685060565275916 +1999,Fla,71,F,0.0150225864061351,0.017123287671232883 +1999,Fla,72,M,0.03889430318065031,0.04810495626822157 +1999,Fla,72,F,0.017494435169727318,0.01963993453355156 +1999,Fla,73,M,0.04034921065725789,0.026356589147286814 +1999,Fla,73,F,0.02158477705197387,0.01926444833625219 +1999,Fla,74,M,0.046213031978841065,0.05608974358974359 +1999,Fla,74,F,0.0242716672149724,0.023346303501945533 +1999,Fla,75,M,0.05210075515685977,0.04873949579831933 +1999,Fla,75,F,0.02770320656226697,0.02529182879377432 +1999,Fla,76,M,0.05628264899174296,0.05371900826446281 +1999,Fla,76,F,0.02934699923930016,0.03211009174311927 +1999,Fla,77,M,0.062096966802006215,0.07860262008733625 +1999,Fla,77,F,0.03437551154035031,0.03800475059382423 +1999,Fla,78,M,0.06979573541653326,0.060606060606060615 +1999,Fla,78,F,0.04117697520802952,0.04040404040404042 +1999,Fla,79,M,0.07771181867242309,0.09574468085106384 +1999,Fla,79,F,0.04671651307019069,0.040816326530612235 +1999,Fla,80,M,0.09034817100044072,0.101010101010101 +1999,Fla,80,F,0.05363321799307959,0.04265402843601896 +1999,Fla,81,M,0.09828009828009827,0.1032608695652174 +1999,Fla,81,F,0.05931434790495192,0.04232804232804233 +1999,Fla,82,M,0.1071538698735739,0.1137724550898204 +1999,Fla,82,F,0.06846278455111263,0.06701030927835051 +1999,Fla,83,M,0.11675629776394,0.09333333333333334 +1999,Fla,83,F,0.08161273368871537,0.06770833333333333 +1999,Fla,84,M,0.1306234630406481,0.1307692307692308 +1999,Fla,84,F,0.08705419825891604,0.08021390374331551 +1999,Fla,85,M,0.1459032907991941,0.1415929203539823 +1999,Fla,85,F,0.09792556436851738,0.1043956043956044 +1999,Fla,86,M,0.1590729001584786,0.1683168316831683 +1999,Fla,86,F,0.1081198815124586,0.07894736842105263 +1999,Fla,87,M,0.1635537607269056,0.1807228915662651 +1999,Fla,87,F,0.1282183316168898,0.1322314049586777 +1999,Fla,88,M,0.1800122249388753,0.2045454545454546 +1999,Fla,88,F,0.1379883624272652,0.12 +1999,Fla,89,M,0.2041969330104923,0.2826086956521739 +1999,Fla,89,F,0.1575663026521061,0.1619047619047619 +1999,Fla,90,M,0.2272727272727273,0.2666666666666667 +1999,Fla,90,F,0.1657020009922276,0.1594202898550725 +1999,Fla,91,M,0.2490092470277411,0.1481481481481482 +1999,Fla,91,F,0.1964956195244055,0.1228070175438597 +1999,Fla,92,M,0.2649903288201161,0.2 +1999,Fla,92,F,0.2045391641295323,0.2222222222222222 +1999,Fla,93,M,0.2424242424242425,0.4 +1999,Fla,93,F,0.2343532684283728,0.1714285714285714 +1999,Fla,94,M,0.2996515679442509,0.09090909090909093 +1999,Fla,94,F,0.2567820392890552,0.3 +1999,Fla,95,M,0.2994505494505495,0.0 +1999,Fla,95,F,0.2714382174206617,0.1176470588235294 +1999,Fla,96,M,0.3008849557522124,0.6 +1999,Fla,96,F,0.2899628252788104,0.1111111111111111 +1999,Fla,97,M,0.375,0.0 +1999,Fla,97,F,0.2932960893854749,0.5555555555555556 +1999,Fla,98,M,0.3956043956043956,0.25 +1999,Fla,98,F,0.3318284424379233,0.0 +1999,Fla,99,M,0.4130434782608696,0.0 +1999,Fla,99,F,0.3527131782945737,0.0 +1999,Fla,100,M,0.4,0.0 +1999,Fla,100,F,0.3961038961038961,0.0 +1999,Fla,101,M,0.5217391304347826,0.0 +1999,Fla,101,F,0.3689320388349515,0.0 +1999,Fla,102,M,0.8571428571428571,0.0 +1999,Fla,102,F,0.4029850746268657,1.0 +1999,Fla,103,M,0.5714285714285714,0.0 +1999,Fla,103,F,0.368421052631579,0.0 +1999,Fla,104,M,0.0,0.0 +1999,Fla,104,F,0.5333333333333333,0.0 +1999,Fla,105,M,1.0,0.0 +1999,Fla,105,F,0.0,0.0 +1999,Fla,106,M,0.0,0.0 +1999,Fla,106,F,1.0,0.0 +1999,Fla,107,M,0.0,0.0 +1999,Fla,107,F,1.0,0.0 +1999,Fla,108,M,0.0,0.0 +1999,Fla,108,F,0.0,0.0 +1999,Fla,109,M,0.0,0.0 +1999,Fla,109,F,1.0,0.0 +1999,Fla,110,M,0.0,0.0 +1999,Fla,110,F,1.0,0.0 +1999,Fla,111,M,0.0,0.0 +1999,Fla,111,F,0.0,0.0 +1999,Fla,112,M,0.0,0.0 +1999,Fla,112,F,0.0,0.0 +1999,Fla,113,M,0.0,0.0 +1999,Fla,113,F,0.0,0.0 +1999,Fla,114,M,0.0,0.0 +1999,Fla,114,F,0.0,0.0 +1999,Fla,115,M,0.0,0.0 +1999,Fla,115,F,0.0,0.0 +1999,Fla,116,M,0.0,0.0 +1999,Fla,116,F,0.0,0.0 +1999,Fla,117,M,0.0,0.0 +1999,Fla,117,F,0.0,0.0 +1999,Fla,118,M,0.0,0.0 +1999,Fla,118,F,0.0,0.0 +1999,Fla,119,M,0.0,0.0 +1999,Fla,119,F,0.0,0.0 +1999,Fla,120,M,0.0,0.0 +1999,Fla,120,F,0.0,0.0 +1999,Wal,0,M,0.0009662354393687262,0.00111731843575419 +1999,Wal,0,F,0.0003932584269662922,0.0 +1999,Wal,1,M,0.00042623474878789486,0.0 +1999,Wal,1,F,0.00016560861164780568,0.002171552660152009 +1999,Wal,2,M,0.0005220024012110455,0.0 +1999,Wal,2,F,0.0002179598953792502,0.0 +1999,Wal,3,M,0.0005855112577846383,0.0 +1999,Wal,3,F,0.0,0.0 +1999,Wal,4,M,0.0001055631795629684,0.0 +1999,Wal,4,F,0.00027580120249324293,0.0 +1999,Wal,5,M,0.00020152148722857581,0.0 +1999,Wal,5,F,5.3475935828877e-05,0.0 +1999,Wal,6,M,0.00019201228878648236,0.0 +1999,Wal,6,F,0.0001006339941632283,0.0008183306055646483 +1999,Wal,7,M,0.0001404297149276787,0.0 +1999,Wal,7,F,0.0001457938474996355,0.0 +1999,Wal,8,M,0.00023734928320516478,0.0007390983000739097 +1999,Wal,8,F,4.939979252087141e-05,0.0 +1999,Wal,9,M,9.450902561194594e-05,0.0007369196757553428 +1999,Wal,9,F,4.9566294919454776e-05,0.001525553012967201 +1999,Wal,10,M,4.759411736709343e-05,0.0 +1999,Wal,10,F,0.0001005227181342983,0.0 +1999,Wal,11,M,0.0001974626055190798,0.0 +1999,Wal,11,F,0.0002075980900975711,0.0 +1999,Wal,12,M,0.0003932749975420313,0.0 +1999,Wal,12,F,0.0,0.0 +1999,Wal,13,M,0.0003080556553884069,0.0 +1999,Wal,13,F,5.361930294906166e-05,0.0 +1999,Wal,14,M,0.00020843103538116832,0.0 +1999,Wal,14,F,5.415357955160836e-05,0.001469507714915503 +1999,Wal,15,M,0.0005761273765254282,0.0 +1999,Wal,15,F,0.0003380091262464087,0.0 +1999,Wal,16,M,0.0005709540122495588,0.002517306482064193 +1999,Wal,16,F,0.0004343341115152832,0.0 +1999,Wal,17,M,0.0008282430893467233,0.0005780346820809249 +1999,Wal,17,F,0.000212517267027946,0.0 +1999,Wal,18,M,0.0009246417013407304,0.0005753739930955121 +1999,Wal,18,F,0.00026533644661430687,0.0005530973451327434 +1999,Wal,19,M,0.001345337886784643,0.001213592233009709 +1999,Wal,19,F,0.0003850596842510589,0.0 +1999,Wal,20,M,0.0017978954047908628,0.001168907071887785 +1999,Wal,20,F,0.0003311441028754347,0.0 +1999,Wal,21,M,0.001725399979086061,0.002324230098779779 +1999,Wal,21,F,0.0006045949214026603,0.0 +1999,Wal,22,M,0.001509708990577334,0.001637554585152839 +1999,Wal,22,F,0.0007069059271343121,0.0 +1999,Wal,23,M,0.001042861612264053,0.001550387596899225 +1999,Wal,23,F,0.0005435668859053107,0.0 +1999,Wal,24,M,0.0011752682677567713,0.0004405286343612335 +1999,Wal,24,F,0.0004297609454740801,0.0 +1999,Wal,25,M,0.001397693805221385,0.0019379844961240308 +1999,Wal,25,F,0.0001559089491736826,0.0004065040650406504 +1999,Wal,26,M,0.001610227383624476,0.001449275362318841 +1999,Wal,26,F,0.0004566905160602831,0.00036886757654002215 +1999,Wal,27,M,0.001254099942118464,0.0003536067892503536 +1999,Wal,27,F,0.0003969632312807026,0.00036010082823190496 +1999,Wal,28,M,0.0013333991802064304,0.0006731740154830024 +1999,Wal,28,F,0.0007619241123584091,0.0 +1999,Wal,29,M,0.001437636327582788,0.0013080444735121 +1999,Wal,29,F,0.0003031681067151736,0.0006889424733034793 +1999,Wal,30,M,0.001565419380901884,0.001273885350318471 +1999,Wal,30,F,0.0001014353096312826,0.0 +1999,Wal,31,M,0.001036269430051813,0.0006345177664974619 +1999,Wal,31,F,0.00044796177392862483,0.001009421265141319 +1999,Wal,32,M,0.001644736842105263,0.0013873473917869036 +1999,Wal,32,F,0.0006752520136979693,0.0009305210918114145 +1999,Wal,33,M,0.002148528724894909,0.0015814443858724301 +1999,Wal,33,F,0.0005601717860143779,0.0 +1999,Wal,34,M,0.001833221551531411,0.0008062348830959419 +1999,Wal,34,F,0.0006709908297919928,0.0006123698714023269 +1999,Wal,35,M,0.0014992503748125939,0.001902173913043479 +1999,Wal,35,F,0.001071572085547172,0.0006343165239454488 +1999,Wal,36,M,0.0020948745402914197,0.0019220208676551352 +1999,Wal,36,F,0.0008649731403077484,0.0 +1999,Wal,37,M,0.0019887904538058213,0.001678321678321679 +1999,Wal,37,F,0.0009715168911459484,0.0009640102827763496 +1999,Wal,38,M,0.002904601978760098,0.001285677552069941 +1999,Wal,38,F,0.001081812035158891,0.0003363605785401951 +1999,Wal,39,M,0.002794429170234822,0.002157497303128371 +1999,Wal,39,F,0.001129207383279045,0.002036659877800407 +1999,Wal,40,M,0.002617801047120419,0.0005382131324004305 +1999,Wal,40,F,0.001328138834779529,0.000350385423966363 +1999,Wal,41,M,0.002636569684074194,0.001363140676117776 +1999,Wal,41,F,0.001892488622538639,0.001096491228070175 +1999,Wal,42,M,0.003353327350871393,0.0026504108136761197 +1999,Wal,42,F,0.0017716803706900469,0.001427551748750892 +1999,Wal,43,M,0.004386174016686532,0.004714364947310039 +1999,Wal,43,F,0.002044989775051125,0.0026119402985074628 +1999,Wal,44,M,0.004163874796592323,0.0040011431837667895 +1999,Wal,44,F,0.001832508704416346,0.0 +1999,Wal,45,M,0.004389731844641664,0.002983293556085919 +1999,Wal,45,F,0.002684688020736901,0.001247920133111481 +1999,Wal,46,M,0.005823186871360508,0.0028011204481792717 +1999,Wal,46,F,0.002726460771870446,0.0012510425354462053 +1999,Wal,47,M,0.005905610329813323,0.0029051000645577787 +1999,Wal,47,F,0.00261992092602296,0.0012964563526361276 +1999,Wal,48,M,0.0062622496295234,0.0031575623618566467 +1999,Wal,48,F,0.003114676734308637,0.001258389261744967 +1999,Wal,49,M,0.006108706108706109,0.0036351619299405157 +1999,Wal,49,F,0.0033040687246294717,0.001364256480218281 +1999,Wal,50,M,0.006440693902496356,0.004344919786096257 +1999,Wal,50,F,0.0037482287333729493,0.002992731936725096 +1999,Wal,51,M,0.007519503712754958,0.006999999999999999 +1999,Wal,51,F,0.004094589620905411,0.0056338028169014105 +1999,Wal,52,M,0.007528230865746549,0.007913669064748202 +1999,Wal,52,F,0.0041222788327929605,0.002521432173474534 +1999,Wal,53,M,0.008233387358184765,0.0058637798827244035 +1999,Wal,53,F,0.0031488434055952533,0.001802884615384616 +1999,Wal,54,M,0.009503970837130579,0.009554140127388536 +1999,Wal,54,F,0.004145783057979085,0.00234192037470726 +1999,Wal,55,M,0.01005095274656244,0.007150153217568948 +1999,Wal,55,F,0.004770930004574864,0.0038338658146964853 +1999,Wal,56,M,0.01115569823434992,0.00957446808510638 +1999,Wal,56,F,0.005311985635193775,0.005235602094240838 +1999,Wal,57,M,0.014726145366861869,0.008264462809917356 +1999,Wal,57,F,0.005296442687747036,0.00272108843537415 +1999,Wal,58,M,0.01089897194094458,0.008932769158439116 +1999,Wal,58,F,0.005083668714255455,0.004006868918145393 +1999,Wal,59,M,0.01326297775242442,0.006701030927835051 +1999,Wal,59,F,0.005567643670805068,0.0040887850467289715 +1999,Wal,60,M,0.01676056338028169,0.009933774834437088 +1999,Wal,60,F,0.008649868371568259,0.004057971014492754 +1999,Wal,61,M,0.016019489148088,0.01454741379310345 +1999,Wal,61,F,0.0067720090293453715,0.007672634271099744 +1999,Wal,62,M,0.01606639762430519,0.009873834339001646 +1999,Wal,62,F,0.008639021796916533,0.0037902716361339225 +1999,Wal,63,M,0.02100513458845496,0.01362088535754824 +1999,Wal,63,F,0.01012118790784392,0.006184291898577613 +1999,Wal,64,M,0.02213145191236539,0.02376708259061201 +1999,Wal,64,F,0.008456117873158229,0.008658008658008658 +1999,Wal,65,M,0.02215591197314435,0.02443384982121573 +1999,Wal,65,F,0.0112589559877175,0.007312614259597806 +1999,Wal,66,M,0.02738553701326487,0.02525832376578645 +1999,Wal,66,F,0.0127141091294367,0.0102498398462524 +1999,Wal,67,M,0.027859442811143786,0.02783171521035599 +1999,Wal,67,F,0.012785964107562641,0.012870012870012873 +1999,Wal,68,M,0.03196609438977085,0.03081570996978852 +1999,Wal,68,F,0.01308539944903582,0.014197530864197531 +1999,Wal,69,M,0.03502155172413793,0.030401034928848637 +1999,Wal,69,F,0.0155440414507772,0.009848982271831909 +1999,Wal,70,M,0.03667068757539204,0.03537414965986395 +1999,Wal,70,F,0.01926403053617224,0.01310344827586207 +1999,Wal,71,M,0.04364452572948707,0.0418918918918919 +1999,Wal,71,F,0.01912316300805509,0.021206096752816442 +1999,Wal,72,M,0.04300611910712747,0.05862533692722373 +1999,Wal,72,F,0.02269651863697872,0.0227120908483634 +1999,Wal,73,M,0.047493171204511415,0.062218890554722635 +1999,Wal,73,F,0.02424643523253716,0.02006920415224913 +1999,Wal,74,M,0.055348837209302316,0.05826017557861132 +1999,Wal,74,F,0.02437503896265819,0.03249630723781388 +1999,Wal,75,M,0.05624183991161997,0.07666941467436109 +1999,Wal,75,F,0.02969336266011127,0.028324154209284032 +1999,Wal,76,M,0.06294004693834009,0.07156862745098039 +1999,Wal,76,F,0.03656055136199541,0.035775127768313465 +1999,Wal,77,M,0.07629852074296517,0.08160919540229886 +1999,Wal,77,F,0.03804884471068396,0.049210770659238616 +1999,Wal,78,M,0.07737512242899118,0.08401084010840107 +1999,Wal,78,F,0.045670593097747465,0.06 +1999,Wal,79,M,0.08793009284543965,0.08747044917257682 +1999,Wal,79,F,0.050284257988629684,0.06191950464396285 +1999,Wal,80,M,0.09670014347202296,0.1089108910891089 +1999,Wal,80,F,0.05445901166978821,0.07058823529411765 +1999,Wal,81,M,0.1090969017798286,0.1167315175097276 +1999,Wal,81,F,0.07049567269866247,0.07928388746803068 +1999,Wal,82,M,0.1220820189274448,0.1208333333333334 +1999,Wal,82,F,0.07391039317281317,0.08232445520581114 +1999,Wal,83,M,0.1334966319657073,0.1033057851239669 +1999,Wal,83,F,0.08670911800569027,0.0933609958506224 +1999,Wal,84,M,0.1444641799881587,0.1576763485477178 +1999,Wal,84,F,0.09423828125,0.1152263374485597 +1999,Wal,85,M,0.1554054054054054,0.1666666666666667 +1999,Wal,85,F,0.1050513461004718,0.1313364055299539 +1999,Wal,86,M,0.1755659974369928,0.1791044776119403 +1999,Wal,86,F,0.121549489095623,0.1355013550135501 +1999,Wal,87,M,0.1650429799426934,0.1666666666666667 +1999,Wal,87,F,0.1264304171280916,0.1360759493670886 +1999,Wal,88,M,0.1748785565579459,0.1910112359550562 +1999,Wal,88,F,0.1440251572327044,0.1296928327645051 +1999,Wal,89,M,0.2112420670897552,0.26 +1999,Wal,89,F,0.1700680272108844,0.196652719665272 +1999,Wal,90,M,0.2307692307692308,0.2622950819672132 +1999,Wal,90,F,0.1820809248554913,0.1822916666666667 +1999,Wal,91,M,0.2597200622083982,0.043478260869565216 +1999,Wal,91,F,0.1924882629107981,0.2195121951219512 +1999,Wal,92,M,0.2727272727272727,0.2083333333333334 +1999,Wal,92,F,0.2162421912542047,0.2066115702479339 +1999,Wal,93,M,0.271875,0.4166666666666667 +1999,Wal,93,F,0.2287371134020619,0.2222222222222222 +1999,Wal,94,M,0.331896551724138,0.4166666666666667 +1999,Wal,94,F,0.2574257425742575,0.2535211267605634 +1999,Wal,95,M,0.3125,0.5714285714285714 +1999,Wal,95,F,0.2993119266055046,0.1515151515151515 +1999,Wal,96,M,0.326923076923077,0.4 +1999,Wal,96,F,0.3184357541899442,0.1463414634146342 +1999,Wal,97,M,0.34375,0.75 +1999,Wal,97,F,0.3140877598152425,0.2333333333333334 +1999,Wal,98,M,0.2758620689655173,0.0 +1999,Wal,98,F,0.2808510638297873,0.2941176470588236 +1999,Wal,99,M,0.3214285714285715,0.0 +1999,Wal,99,F,0.3885350318471338,4.0 +1999,Wal,100,M,0.5,0.25 +1999,Wal,100,F,0.4421052631578947,0.3333333333333333 +1999,Wal,101,M,0.3333333333333333,0.0 +1999,Wal,101,F,0.3064516129032258,0.4285714285714286 +1999,Wal,102,M,1.0,0.0 +1999,Wal,102,F,0.6060606060606061,0.0 +1999,Wal,103,M,0.0,0.0 +1999,Wal,103,F,0.3333333333333333,0.0 +1999,Wal,104,M,0.0,0.0 +1999,Wal,104,F,0.6666666666666666,0.0 +1999,Wal,105,M,0.5,0.0 +1999,Wal,105,F,0.25,0.0 +1999,Wal,106,M,0.0,0.0 +1999,Wal,106,F,0.4,1.0 +1999,Wal,107,M,0.0,0.0 +1999,Wal,107,F,0.5,0.0 +1999,Wal,108,M,0.0,0.0 +1999,Wal,108,F,0.0,0.0 +1999,Wal,109,M,0.0,0.0 +1999,Wal,109,F,0.0,0.0 +1999,Wal,110,M,0.0,0.0 +1999,Wal,110,F,0.0,0.0 +1999,Wal,111,M,0.0,0.0 +1999,Wal,111,F,0.0,0.0 +1999,Wal,112,M,0.0,0.0 +1999,Wal,112,F,0.0,0.0 +1999,Wal,113,M,0.0,0.0 +1999,Wal,113,F,0.0,0.0 +1999,Wal,114,M,0.0,0.0 +1999,Wal,114,F,0.0,0.0 +1999,Wal,115,M,0.0,0.0 +1999,Wal,115,F,0.0,0.0 +1999,Wal,116,M,0.0,0.0 +1999,Wal,116,F,0.0,0.0 +1999,Wal,117,M,0.0,0.0 +1999,Wal,117,F,0.0,0.0 +1999,Wal,118,M,0.0,0.0 +1999,Wal,118,F,0.0,0.0 +1999,Wal,119,M,0.0,0.0 +1999,Wal,119,F,0.0,0.0 +1999,Wal,120,M,0.0,0.0 +1999,Wal,120,F,0.0,0.0 +2000,BruCap,0,M,0.001207972619287296,0.001213592233009709 +2000,BruCap,0,F,0.0004162330905306972,0.001231527093596059 +2000,BruCap,1,M,0.001461988304093567,0.0 +2000,BruCap,1,F,0.00021963540522732268,0.0 +2000,BruCap,2,M,0.0,0.0 +2000,BruCap,2,F,0.0,0.0 +2000,BruCap,3,M,0.00022836263987211696,0.0006157635467980296 +2000,BruCap,3,F,0.0002298322224775914,0.0 +2000,BruCap,4,M,0.0004688232536333802,0.0 +2000,BruCap,4,F,0.0,0.0 +2000,BruCap,5,M,0.0002322340919647004,0.0 +2000,BruCap,5,F,0.0,0.0 +2000,BruCap,6,M,0.00023691068467187872,0.0 +2000,BruCap,6,F,0.0002498126405196103,0.0 +2000,BruCap,7,M,0.0,0.0006006006006006006 +2000,BruCap,7,F,0.0,0.0 +2000,BruCap,8,M,0.00024218939210462584,0.0 +2000,BruCap,8,F,0.0002499375156210948,0.0 +2000,BruCap,9,M,0.0002409058058299205,0.0006038647342995169 +2000,BruCap,9,F,0.0002568713074749551,0.0006353240152477764 +2000,BruCap,10,M,0.0,0.0 +2000,BruCap,10,F,0.0,0.0 +2000,BruCap,11,M,0.0,0.0 +2000,BruCap,11,F,0.0002639915522703274,0.0 +2000,BruCap,12,M,0.0002516989680342311,0.0 +2000,BruCap,12,F,0.0,0.0 +2000,BruCap,13,M,0.0,0.0 +2000,BruCap,13,F,0.0005363368195226601,0.0 +2000,BruCap,14,M,0.0005192107995846313,0.0 +2000,BruCap,14,F,0.0,0.0 +2000,BruCap,15,M,0.0005257623554153521,0.0007002801120448178 +2000,BruCap,15,F,0.0,0.0 +2000,BruCap,16,M,0.0008121277747698973,0.0 +2000,BruCap,16,F,0.0002793296089385475,0.0 +2000,BruCap,17,M,0.0002759381898454746,0.0 +2000,BruCap,17,F,0.0002840909090909092,0.0 +2000,BruCap,18,M,0.001523616048755714,0.0012055455093429779 +2000,BruCap,18,F,0.0005300821627352238,0.0 +2000,BruCap,19,M,0.0009794319294809011,0.0006510416666666666 +2000,BruCap,19,F,0.0004828585224529213,0.0 +2000,BruCap,20,M,0.001200768491834775,0.0005988023952095807 +2000,BruCap,20,F,0.0007378258730939497,0.0 +2000,BruCap,21,M,0.0007297494526879105,0.0 +2000,BruCap,21,F,0.0002287282708142727,0.0004587155963302753 +2000,BruCap,22,M,0.00023803856224708408,0.000517063081695967 +2000,BruCap,22,F,0.000450755014649538,0.0 +2000,BruCap,23,M,0.001410105757931845,0.0 +2000,BruCap,23,F,0.00043535045711797995,0.000407000407000407 +2000,BruCap,24,M,0.0017414018284719198,0.0009078529278256922 +2000,BruCap,24,F,0.000427807486631016,0.0 +2000,BruCap,25,M,0.0008437038599451593,0.0011393847322445881 +2000,BruCap,25,F,0.0004016870857601928,0.0003494060097833683 +2000,BruCap,26,M,0.002353402627966268,0.0 +2000,BruCap,26,F,0.0007571455612341472,0.0 +2000,BruCap,27,M,0.0007564296520423603,0.0009484666455896301 +2000,BruCap,27,F,0.00018960940462646954,0.0003125 +2000,BruCap,28,M,0.0009502090459901178,0.0006049606775559589 +2000,BruCap,28,F,0.00038431975403535736,0.0 +2000,BruCap,29,M,0.0023183925811437398,0.0011425307055127106 +2000,BruCap,29,F,0.000982897582071948,0.0 +2000,BruCap,30,M,0.0006033789219629927,0.0002842524161455372 +2000,BruCap,30,F,0.0008335069806209628,0.0 +2000,BruCap,31,M,0.002286902286902287,0.0 +2000,BruCap,31,F,0.0004333694474539545,0.0 +2000,BruCap,32,M,0.0008492569002123143,0.000297707651086633 +2000,BruCap,32,F,0.0006663705019991118,0.0 +2000,BruCap,33,M,0.002372223420314859,0.002258610954263128 +2000,BruCap,33,F,0.0008818342151675485,0.0003191828917969997 +2000,BruCap,34,M,0.002275548200248242,0.001178897730621869 +2000,BruCap,34,F,0.001531058617672791,0.0 +2000,BruCap,35,M,0.001700680272108844,0.0005889281507656068 +2000,BruCap,35,F,0.0006683002895967921,0.001275510204081633 +2000,BruCap,36,M,0.001497005988023952,0.0012742911755336099 +2000,BruCap,36,F,0.001112347052280311,0.0003577817531305904 +2000,BruCap,37,M,0.001370175839232702,0.0016005121638924464 +2000,BruCap,37,F,0.00091324200913242,0.0 +2000,BruCap,38,M,0.0022888532845044642,0.0014662756598240474 +2000,BruCap,38,F,0.0017981568891885821,0.0003799392097264438 +2000,BruCap,39,M,0.0035666518056174774,0.0007328691828508611 +2000,BruCap,39,F,0.001325088339222615,0.001126972201352367 +2000,BruCap,40,M,0.004303510758776897,0.002409638554216868 +2000,BruCap,40,F,0.001977152899824253,0.0004142502071251036 +2000,BruCap,41,M,0.001868285847734703,0.002127659574468085 +2000,BruCap,41,F,0.001122082585278277,0.0 +2000,BruCap,42,M,0.003714882749013235,0.001440922190201729 +2000,BruCap,42,F,0.00179291797400269,0.00046382189239332097 +2000,BruCap,43,M,0.004116222760290557,0.001345895020188426 +2000,BruCap,43,F,0.002681564245810056,0.001358695652173913 +2000,BruCap,44,M,0.004060186290900407,0.001374885426214482 +2000,BruCap,44,F,0.002463605823068309,0.001940805434255216 +2000,BruCap,45,M,0.004778972520908004,0.001042209484106305 +2000,BruCap,45,F,0.002287282708142727,0.001012658227848101 +2000,BruCap,46,M,0.005486641221374045,0.001574803149606299 +2000,BruCap,46,F,0.002459199642298234,0.001637554585152839 +2000,BruCap,47,M,0.00471253534401508,0.0026109660574412537 +2000,BruCap,47,F,0.003567447045707916,0.002145922746781116 +2000,BruCap,48,M,0.004189255791030064,0.005163511187607574 +2000,BruCap,48,F,0.002995391705069125,0.0030618493570116357 +2000,BruCap,49,M,0.006057546693589096,0.001631321370309951 +2000,BruCap,49,F,0.002026114362899595,0.00226628895184136 +2000,BruCap,50,M,0.006256256256256257,0.003690036900369004 +2000,BruCap,50,F,0.004345837145471179,0.0019493177387914235 +2000,BruCap,51,M,0.004212091179385529,0.0005910165484633572 +2000,BruCap,51,F,0.0026990553306342783,0.004504504504504504 +2000,BruCap,52,M,0.004683263495193493,0.00243605359317905 +2000,BruCap,52,F,0.004101899827288429,0.001373626373626374 +2000,BruCap,53,M,0.00976324139614352,0.005312084993359893 +2000,BruCap,53,F,0.005577867023650156,0.0006978367062107465 +2000,BruCap,54,M,0.009450171821305843,0.009658246656760771 +2000,BruCap,54,F,0.004572009144018288,0.002388535031847134 +2000,BruCap,55,M,0.01050594415261266,0.004264392324093817 +2000,BruCap,55,F,0.005035971223021582,0.002384737678855326 +2000,BruCap,56,M,0.01030632693959347,0.005511811023622047 +2000,BruCap,56,F,0.005296343001261034,0.0008598452278589854 +2000,BruCap,57,M,0.009051290646999664,0.006838905775075988 +2000,BruCap,57,F,0.0064839375184202784,0.004325259515570936 +2000,BruCap,58,M,0.01249526694433927,0.014311270125223619 +2000,BruCap,58,F,0.008239947264337508,0.005165289256198347 +2000,BruCap,59,M,0.01278507256392536,0.01185185185185185 +2000,BruCap,59,F,0.006306306306306306,0.0023771790808240893 +2000,BruCap,60,M,0.01324942033786022,0.01175482787573468 +2000,BruCap,60,F,0.006030701754385965,0.0064995357474466105 +2000,BruCap,61,M,0.01570330771800869,0.01086048454469507 +2000,BruCap,61,F,0.01068917018284107,0.006042296072507553 +2000,BruCap,62,M,0.01829478771142561,0.00980392156862745 +2000,BruCap,62,F,0.007683551508252703,0.006688963210702341 +2000,BruCap,63,M,0.017406749555950268,0.0136986301369863 +2000,BruCap,63,F,0.01212121212121212,0.006295907660020986 +2000,BruCap,64,M,0.01970619849516302,0.01954732510288066 +2000,BruCap,64,F,0.01011520089912897,0.0076335877862595426 +2000,BruCap,65,M,0.02821210061182869,0.02708559046587216 +2000,BruCap,65,F,0.012105855855855859,0.01098901098901099 +2000,BruCap,66,M,0.02995066948555321,0.02181818181818182 +2000,BruCap,66,F,0.01001053740779768,0.004273504273504274 +2000,BruCap,67,M,0.017725752508361208,0.02430133657351155 +2000,BruCap,67,F,0.01187168476888103,0.0055248618784530384 +2000,BruCap,68,M,0.03194993412384717,0.028231797919762262 +2000,BruCap,68,F,0.01828514949345194,0.01361573373676248 +2000,BruCap,69,M,0.030250945342041938,0.03511053315994798 +2000,BruCap,69,F,0.017731302568765633,0.01800554016620499 +2000,BruCap,70,M,0.035855145213338116,0.01794453507340946 +2000,BruCap,70,F,0.01979961832061069,0.01717557251908397 +2000,BruCap,71,M,0.04007092198581561,0.02003642987249545 +2000,BruCap,71,F,0.01904532304725169,0.02150537634408602 +2000,BruCap,72,M,0.03718556325191396,0.02553191489361702 +2000,BruCap,72,F,0.01912502988285919,0.014675052410901468 +2000,BruCap,73,M,0.04212454212454213,0.03153153153153153 +2000,BruCap,73,F,0.02057327785483125,0.02914798206278027 +2000,BruCap,74,M,0.04926470588235294,0.04060913705583756 +2000,BruCap,74,F,0.02224260490713139,0.02619047619047619 +2000,BruCap,75,M,0.05326086956521739,0.03921568627450981 +2000,BruCap,75,F,0.02169051878354204,0.0275 +2000,BruCap,76,M,0.05702970297029704,0.07250755287009064 +2000,BruCap,76,F,0.02805389882924674,0.01662049861495845 +2000,BruCap,77,M,0.060066280033140025,0.07216494845360824 +2000,BruCap,77,F,0.03141242937853108,0.03987730061349693 +2000,BruCap,78,M,0.0547001620745543,0.06106870229007633 +2000,BruCap,78,F,0.035955056179775284,0.04166666666666667 +2000,BruCap,79,M,0.08045977011494253,0.06435643564356436 +2000,BruCap,79,F,0.04191209787041233,0.05882352941176471 +2000,BruCap,80,M,0.08983890954151177,0.08888888888888889 +2000,BruCap,80,F,0.04369090316269971,0.04830917874396135 +2000,BruCap,81,M,0.07543103448275862,0.05607476635514018 +2000,BruCap,81,F,0.05277525022747952,0.06293706293706294 +2000,BruCap,82,M,0.08231368186874305,0.08333333333333333 +2000,BruCap,82,F,0.058365758754863814,0.05844155844155844 +2000,BruCap,83,M,0.1044957472660996,0.1857142857142857 +2000,BruCap,83,F,0.07222739981360671,0.07086614173228346 +2000,BruCap,84,M,0.1383196721311476,0.1 +2000,BruCap,84,F,0.0690803162713275,0.046875 +2000,BruCap,85,M,0.1114341085271318,0.1025641025641026 +2000,BruCap,85,F,0.09649776453055142,0.1153846153846154 +2000,BruCap,86,M,0.1358447488584475,0.25 +2000,BruCap,86,F,0.1071279699874948,0.07407407407407407 +2000,BruCap,87,M,0.1622002820874471,0.06521739130434782 +2000,BruCap,87,F,0.1123595505617977,0.1297709923664122 +2000,BruCap,88,M,0.1706484641638226,0.1666666666666667 +2000,BruCap,88,F,0.1270182992465016,0.1521739130434783 +2000,BruCap,89,M,0.203056768558952,0.2195121951219512 +2000,BruCap,89,F,0.1468277945619336,0.1052631578947368 +2000,BruCap,90,M,0.2386363636363637,0.2608695652173913 +2000,BruCap,90,F,0.1748633879781421,0.1 +2000,BruCap,91,M,0.2103321033210332,0.1111111111111111 +2000,BruCap,91,F,0.16875,0.16 +2000,BruCap,92,M,0.2686567164179105,0.25 +2000,BruCap,92,F,0.1843003412969283,0.25 +2000,BruCap,93,M,0.2805755395683453,0.1666666666666667 +2000,BruCap,93,F,0.1827485380116959,0.2307692307692308 +2000,BruCap,94,M,0.2685185185185186,0.0 +2000,BruCap,94,F,0.2057142857142857,0.1944444444444445 +2000,BruCap,95,M,0.3246753246753247,0.1428571428571429 +2000,BruCap,95,F,0.2581453634085213,0.1764705882352941 +2000,BruCap,96,M,0.375,0.0 +2000,BruCap,96,F,0.288659793814433,0.25 +2000,BruCap,97,M,0.2857142857142857,0.3333333333333333 +2000,BruCap,97,F,0.2428571428571429,0.0 +2000,BruCap,98,M,0.368421052631579,0.2 +2000,BruCap,98,F,0.3235294117647059,0.125 +2000,BruCap,99,M,0.7142857142857143,0.3333333333333333 +2000,BruCap,99,F,0.3375,0.3333333333333333 +2000,BruCap,100,M,0.5,0.0 +2000,BruCap,100,F,0.3448275862068966,0.3333333333333333 +2000,BruCap,101,M,1.0,0.0 +2000,BruCap,101,F,0.3333333333333333,0.125 +2000,BruCap,102,M,0.5,0.0 +2000,BruCap,102,F,0.4285714285714286,0.25 +2000,BruCap,103,M,1.0,0.0 +2000,BruCap,103,F,0.2727272727272727,0.5 +2000,BruCap,104,M,1.0,0.0 +2000,BruCap,104,F,0.1666666666666667,0.0 +2000,BruCap,105,M,0.0,0.0 +2000,BruCap,105,F,0.6666666666666666,0.0 +2000,BruCap,106,M,0.0,0.0 +2000,BruCap,106,F,0.0,0.0 +2000,BruCap,107,M,0.0,0.0 +2000,BruCap,107,F,0.0,0.0 +2000,BruCap,108,M,0.0,0.0 +2000,BruCap,108,F,0.0,0.0 +2000,BruCap,109,M,0.0,0.0 +2000,BruCap,109,F,0.0,1.0 +2000,BruCap,110,M,0.0,0.0 +2000,BruCap,110,F,0.0,0.0 +2000,BruCap,111,M,0.0,0.0 +2000,BruCap,111,F,0.0,0.0 +2000,BruCap,112,M,0.0,0.0 +2000,BruCap,112,F,0.0,0.0 +2000,BruCap,113,M,0.0,0.0 +2000,BruCap,113,F,0.0,0.0 +2000,BruCap,114,M,0.0,0.0 +2000,BruCap,114,F,0.0,0.0 +2000,BruCap,115,M,0.0,0.0 +2000,BruCap,115,F,0.0,0.0 +2000,BruCap,116,M,0.0,0.0 +2000,BruCap,116,F,0.0,0.0 +2000,BruCap,117,M,0.0,0.0 +2000,BruCap,117,F,0.0,0.0 +2000,BruCap,118,M,0.0,0.0 +2000,BruCap,118,F,0.0,0.0 +2000,BruCap,119,M,0.0,0.0 +2000,BruCap,119,F,0.0,0.0 +2000,BruCap,120,M,0.0,0.0 +2000,BruCap,120,F,0.0,0.0 +2000,Fla,0,M,0.001011429149388085,0.00116211504938989 +2000,Fla,0,F,0.0010131004366812232,0.0005959475566150177 +2000,Fla,1,M,0.0005216654168432722,0.0005750431282346176 +2000,Fla,1,F,0.0002065617791854581,0.0005770340450086555 +2000,Fla,2,M,0.0003511684331503001,0.0005589714924538849 +2000,Fla,2,F,0.00026578073089701004,0.0005757052389176742 +2000,Fla,3,M,0.0002219122495561755,0.0 +2000,Fla,3,F,9.913422774436588e-05,0.0 +2000,Fla,4,M,6.306363120388472e-05,0.0 +2000,Fla,4,F,0.0001318739285243307,0.0005844535359438924 +2000,Fla,5,M,6.24005491248323e-05,0.0 +2000,Fla,5,F,6.542147787118511e-05,0.0 +2000,Fla,6,M,0.000119495728027723,0.0 +2000,Fla,6,F,9.234747275749556e-05,0.0 +2000,Fla,7,M,0.00017267180844940716,0.0 +2000,Fla,7,F,6.012686769082765e-05,0.0010689470871191884 +2000,Fla,8,M,8.513536523071685e-05,0.0 +2000,Fla,8,F,8.965661516392217e-05,0.0 +2000,Fla,9,M,5.7291815864103806e-05,0.0 +2000,Fla,9,F,0.0001504166541319455,0.0 +2000,Fla,10,M,5.91261160054396e-05,0.0 +2000,Fla,10,F,6.220259384816346e-05,0.0 +2000,Fla,11,M,0.0001794634044207819,0.0 +2000,Fla,11,F,6.259584989515197e-05,0.0 +2000,Fla,12,M,0.0001501050735514861,0.0006640106241699867 +2000,Fla,12,F,0.00022208121827411168,0.0 +2000,Fla,13,M,0.0003291442250149611,0.0 +2000,Fla,13,F,9.533494343460022e-05,0.0 +2000,Fla,14,M,0.0002469440671687864,0.0 +2000,Fla,14,F,0.0001940742657523612,0.0006613756613756612 +2000,Fla,15,M,0.0003923343896182285,0.0006199628022318662 +2000,Fla,15,F,0.0004440497335701599,0.0 +2000,Fla,16,M,0.00038264555248130916,0.0 +2000,Fla,16,F,0.0002455343441163833,0.0 +2000,Fla,17,M,0.0008904463721491351,0.0010958904109589038 +2000,Fla,17,F,0.0004866920152091255,0.0 +2000,Fla,18,M,0.00121288970973344,0.001812688821752266 +2000,Fla,18,F,0.000411292928699433,0.0005595970900951317 +2000,Fla,19,M,0.001141171231351592,0.001866832607342875 +2000,Fla,19,F,0.0003185820203892493,0.0 +2000,Fla,20,M,0.001264465763215042,0.003128911138923655 +2000,Fla,20,F,0.0004079610688580004,0.0 +2000,Fla,21,M,0.00112568244498227,0.0 +2000,Fla,21,F,0.0004982707075444047,0.0 +2000,Fla,22,M,0.001092613358635958,0.000588235294117647 +2000,Fla,22,F,0.00044543429844097997,0.00046061722708429296 +2000,Fla,23,M,0.001146923891306905,0.0020855057351407717 +2000,Fla,23,F,0.0004928991713132681,0.0004266211604095563 +2000,Fla,24,M,0.001663490911290567,0.00048567265662943164 +2000,Fla,24,F,0.0005081946385465633,0.0008120178643930166 +2000,Fla,25,M,0.001313830253131296,0.0008536064874093043 +2000,Fla,25,F,0.0003355295265983406,0.0 +2000,Fla,26,M,0.001044106442418941,0.001582904629996043 +2000,Fla,26,F,0.0005903710482037961,0.0003606202668589975 +2000,Fla,27,M,0.001168510013859073,0.00140498770635757 +2000,Fla,27,F,0.0004208163837845421,0.0 +2000,Fla,28,M,0.000883552922221356,0.0 +2000,Fla,28,F,0.00039884070302321264,0.0006445375443119562 +2000,Fla,29,M,0.001233418078384978,0.000643293663557414 +2000,Fla,29,F,0.0002873338035159209,0.0 +2000,Fla,30,M,0.001133301432996701,0.001553277415346381 +2000,Fla,30,F,0.000547074454228104,0.0006325110689437065 +2000,Fla,31,M,0.0008708633988554367,0.0003048780487804878 +2000,Fla,31,F,0.0005645368231973313,0.0003265839320705422 +2000,Fla,32,M,0.0009331036462819408,0.001617076326002588 +2000,Fla,32,F,0.0005022980134113571,0.0006624710168930112 +2000,Fla,33,M,0.001044762258543834,0.0014367816091954018 +2000,Fla,33,F,0.0006469235192639448,0.0 +2000,Fla,34,M,0.0010515247108307036,0.0008925914906277895 +2000,Fla,34,F,0.0006734319485405104,0.0003254149040026033 +2000,Fla,35,M,0.001117534546861232,0.0005758710048949035 +2000,Fla,35,F,0.0008161464652034851,0.0009566326530612245 +2000,Fla,36,M,0.001251726519337017,0.0009219422249539028 +2000,Fla,36,F,0.0005114520791638871,0.0003442340791738384 +2000,Fla,37,M,0.001702870865626024,0.0015389350569405972 +2000,Fla,37,F,0.0009013678256754623,0.0007358351729212656 +2000,Fla,38,M,0.001316106955625261,0.001307616868257601 +2000,Fla,38,F,0.0010043521928356212,0.0019379844961240308 +2000,Fla,39,M,0.001299486926713419,0.0006420545746388442 +2000,Fla,39,F,0.0009410360577474813,0.001142857142857143 +2000,Fla,40,M,0.002019226548439489,0.001769911504424779 +2000,Fla,40,F,0.001214247166756611,0.0008067769261799112 +2000,Fla,41,M,0.00203583972795812,0.001049685094471658 +2000,Fla,41,F,0.001592687487016135,0.0004372540445999127 +2000,Fla,42,M,0.0019943342776203967,0.001480932987782303 +2000,Fla,42,F,0.001030155459823937,0.001415094339622642 +2000,Fla,43,M,0.00216869155609449,0.0022787694644891762 +2000,Fla,43,F,0.0012341869793273679,0.0013869625520110964 +2000,Fla,44,M,0.002461480201652032,0.001153846153846154 +2000,Fla,44,F,0.0017955470433325352,0.0010101010101010099 +2000,Fla,45,M,0.002792556392787501,0.0004020908725371933 +2000,Fla,45,F,0.002016872863221586,0.0005307855626326964 +2000,Fla,46,M,0.0032441997640581988,0.0017873100983020558 +2000,Fla,46,F,0.0016013420771694368,0.002268859897901305 +2000,Fla,47,M,0.003400773799255773,0.00216076058772688 +2000,Fla,47,F,0.001839268379911102,0.0 +2000,Fla,48,M,0.003589690615154176,0.0036101083032490976 +2000,Fla,48,F,0.002439412419791059,0.0044164037854889605 +2000,Fla,49,M,0.0045941405019426645,0.0030527692978630627 +2000,Fla,49,F,0.002553802771940092,0.001201923076923077 +2000,Fla,50,M,0.004408159006729615,0.0051129100979974435 +2000,Fla,50,F,0.002730996813837051,0.0023852116875372692 +2000,Fla,51,M,0.004814485321052907,0.0017817371937639199 +2000,Fla,51,F,0.0027521236338617053,0.004481434058898848 +2000,Fla,52,M,0.005343370798346977,0.005512172714745062 +2000,Fla,52,F,0.002651596314548961,0.001889168765743073 +2000,Fla,53,M,0.005780643835264497,0.0049751243781094535 +2000,Fla,53,F,0.0030264750776356646,0.002059025394646534 +2000,Fla,54,M,0.006781625851325896,0.006966773847802787 +2000,Fla,54,F,0.003738099410081187,0.003762227238525207 +2000,Fla,55,M,0.007484067122727006,0.00554016620498615 +2000,Fla,55,F,0.004026924546603569,0.005747126436781609 +2000,Fla,56,M,0.008104125736738703,0.007278835386338186 +2000,Fla,56,F,0.004568169972713616,0.0007867820613690008 +2000,Fla,57,M,0.0097426665254686,0.007172743574417216 +2000,Fla,57,F,0.004190435946193394,0.003184713375796179 +2000,Fla,58,M,0.009652129377930113,0.009085402786190185 +2000,Fla,58,F,0.0049722700325109965,0.00265017667844523 +2000,Fla,59,M,0.01060146350169552,0.013521457965902407 +2000,Fla,59,F,0.004768651301012474,0.004576659038901603 +2000,Fla,60,M,0.01079595642359407,0.011090573012939 +2000,Fla,60,F,0.006078933563736229,0.0074487895716946 +2000,Fla,61,M,0.01147858071471605,0.006389776357827476 +2000,Fla,61,F,0.006084824266642449,0.005649717514124294 +2000,Fla,62,M,0.01249426116613104,0.01152737752161383 +2000,Fla,62,F,0.006806348409760994,0.006923837784371909 +2000,Fla,63,M,0.01361914189166126,0.019019751280175568 +2000,Fla,63,F,0.006838590100022369,0.004179728317659353 +2000,Fla,64,M,0.01572251146433128,0.01247077162899455 +2000,Fla,64,F,0.007529155453030883,0.01004464285714286 +2000,Fla,65,M,0.01794791990870422,0.01395730706075534 +2000,Fla,65,F,0.00854459208996953,0.006674082313681869 +2000,Fla,66,M,0.01935640811787601,0.021114864864864868 +2000,Fla,66,F,0.008109991763289616,0.01376146788990826 +2000,Fla,67,M,0.02133599889700814,0.02504472271914133 +2000,Fla,67,F,0.01007855794409598,0.005134788189987164 +2000,Fla,68,M,0.02485298235788295,0.02885572139303483 +2000,Fla,68,F,0.01048428880558349,0.009404388714733545 +2000,Fla,69,M,0.025893824485373786,0.034161490683229816 +2000,Fla,69,F,0.01229470310911164,0.01190476190476191 +2000,Fla,70,M,0.02985844006503034,0.036188178528347416 +2000,Fla,70,F,0.0148749378830545,0.02034428794992175 +2000,Fla,71,M,0.03499209453274528,0.04192355117139334 +2000,Fla,71,F,0.01541669515279962,0.01651651651651652 +2000,Fla,72,M,0.03672714461863661,0.04667609618104668 +2000,Fla,72,F,0.01838679849206914,0.02586206896551724 +2000,Fla,73,M,0.04231974921630094,0.04231974921630094 +2000,Fla,73,F,0.02056564369402853,0.023529411764705882 +2000,Fla,74,M,0.04612337294850028,0.0576 +2000,Fla,74,F,0.02275449101796408,0.02333931777378815 +2000,Fla,75,M,0.04738142043449771,0.05962521294718909 +2000,Fla,75,F,0.02772781774580336,0.02772277227722773 +2000,Fla,76,M,0.057271075969654875,0.05985915492957746 +2000,Fla,76,F,0.028345671435694837,0.03441295546558705 +2000,Fla,77,M,0.056627366916755975,0.06263498920086392 +2000,Fla,77,F,0.03411293981767933,0.037647058823529415 +2000,Fla,78,M,0.0678925935352507,0.06839622641509434 +2000,Fla,78,F,0.03818120179676244,0.0293398533007335 +2000,Fla,79,M,0.07625017220002757,0.07180851063829788 +2000,Fla,79,F,0.04569459362692446,0.0549738219895288 +2000,Fla,80,M,0.09355184860013656,0.0963855421686747 +2000,Fla,80,F,0.05003952088526783,0.04184100418410042 +2000,Fla,81,M,0.09461637653127017,0.06629834254143646 +2000,Fla,81,F,0.05574339760577538,0.08374384236453201 +2000,Fla,82,M,0.1045941528963138,0.1325301204819277 +2000,Fla,82,F,0.07288151932902727,0.09042553191489362 +2000,Fla,83,M,0.1150855365474339,0.0945945945945946 +2000,Fla,83,F,0.0742605988462595,0.0913978494623656 +2000,Fla,84,M,0.1338141025641026,0.1417910447761194 +2000,Fla,84,F,0.08875061404945145,0.1263736263736264 +2000,Fla,85,M,0.1414544849392578,0.125 +2000,Fla,85,F,0.09957708573625527,0.09142857142857144 +2000,Fla,86,M,0.1528023598820059,0.154639175257732 +2000,Fla,86,F,0.1108009811384589,0.1144578313253012 +2000,Fla,87,M,0.1685128446853641,0.2380952380952381 +2000,Fla,87,F,0.1253789731051345,0.1142857142857143 +2000,Fla,88,M,0.1723095525997582,0.1176470588235294 +2000,Fla,88,F,0.1349243856332703,0.180952380952381 +2000,Fla,89,M,0.2082242990654206,0.2 +2000,Fla,89,F,0.1574444597764592,0.2065217391304348 +2000,Fla,90,M,0.2156265854895992,0.1428571428571429 +2000,Fla,90,F,0.1782462057335582,0.1494252873563219 +2000,Fla,91,M,0.2439678284182306,0.15625 +2000,Fla,91,F,0.1851704996034893,0.1428571428571429 +2000,Fla,92,M,0.2589991220368745,0.2083333333333334 +2000,Fla,92,F,0.2047346514047867,0.19607843137254896 +2000,Fla,93,M,0.2791005291005292,0.3333333333333333 +2000,Fla,93,F,0.2225705329153605,0.2058823529411765 +2000,Fla,94,M,0.3053311793214863,0.1818181818181818 +2000,Fla,94,F,0.2384860921112631,0.1290322580645161 +2000,Fla,95,M,0.3052109181141439,0.3 +2000,Fla,95,F,0.2919293820933166,0.2592592592592593 +2000,Fla,96,M,0.2677165354330709,0.5 +2000,Fla,96,F,0.2590529247910864,0.2 +2000,Fla,97,M,0.43125,0.5 +2000,Fla,97,F,0.2922673656618611,0.3333333333333333 +2000,Fla,98,M,0.4430379746835443,0.25 +2000,Fla,98,F,0.294234592445328,0.2222222222222222 +2000,Fla,99,M,0.3454545454545455,0.3333333333333333 +2000,Fla,99,F,0.3367003367003367,0.2222222222222222 +2000,Fla,100,M,0.32,0.0 +2000,Fla,100,F,0.3018867924528302,0.5 +2000,Fla,101,M,0.6,0.0 +2000,Fla,101,F,0.4347826086956522,0.2 +2000,Fla,102,M,0.4545454545454545,0.0 +2000,Fla,102,F,0.4461538461538462,0.0 +2000,Fla,103,M,0.0,0.0 +2000,Fla,103,F,0.475,0.0 +2000,Fla,104,M,0.0,0.0 +2000,Fla,104,F,0.25,0.0 +2000,Fla,105,M,0.5,0.0 +2000,Fla,105,F,0.4285714285714286,0.0 +2000,Fla,106,M,0.0,0.0 +2000,Fla,106,F,0.6666666666666666,0.0 +2000,Fla,107,M,0.0,0.0 +2000,Fla,107,F,0.0,0.0 +2000,Fla,108,M,0.0,0.0 +2000,Fla,108,F,0.0,0.0 +2000,Fla,109,M,0.0,0.0 +2000,Fla,109,F,0.0,0.0 +2000,Fla,110,M,0.0,0.0 +2000,Fla,110,F,0.0,0.0 +2000,Fla,111,M,0.0,0.0 +2000,Fla,111,F,0.0,0.0 +2000,Fla,112,M,0.0,0.0 +2000,Fla,112,F,0.0,0.0 +2000,Fla,113,M,0.0,0.0 +2000,Fla,113,F,0.0,0.0 +2000,Fla,114,M,0.0,0.0 +2000,Fla,114,F,0.0,0.0 +2000,Fla,115,M,0.0,0.0 +2000,Fla,115,F,0.0,0.0 +2000,Fla,116,M,0.0,0.0 +2000,Fla,116,F,0.0,0.0 +2000,Fla,117,M,0.0,0.0 +2000,Fla,117,F,0.0,0.0 +2000,Fla,118,M,0.0,0.0 +2000,Fla,118,F,0.0,0.0 +2000,Fla,119,M,0.0,0.0 +2000,Fla,119,F,0.0,0.0 +2000,Fla,120,M,0.0,0.0 +2000,Fla,120,F,0.0,0.0 +2000,Wal,0,M,0.001124016485575122,0.0 +2000,Wal,0,F,0.001124416708832293,0.0 +2000,Wal,1,M,0.0005824111822947001,0.0011025358324145528 +2000,Wal,1,F,0.00038837106080781184,0.0 +2000,Wal,2,M,0.0002112266990547605,0.000942507068803016 +2000,Wal,2,F,0.0002190460544329445,0.0 +2000,Wal,3,M,0.0003626755090409824,0.0 +2000,Wal,3,F,0.0003244470880873844,0.0 +2000,Wal,4,M,0.0002121003234529933,0.0 +2000,Wal,4,F,5.5212014134275624e-05,0.0 +2000,Wal,5,M,0.0,0.0 +2000,Wal,5,F,5.496317467296911e-05,0.0 +2000,Wal,6,M,0.0001507083291469909,0.0 +2000,Wal,6,F,0.0001063829787234043,0.0 +2000,Wal,7,M,0.0001911771734454906,0.000784313725490196 +2000,Wal,7,F,0.00020047110710168895,0.0 +2000,Wal,8,M,9.33445346774946e-05,0.0 +2000,Wal,8,F,9.677731539727088e-05,0.0 +2000,Wal,9,M,0.0001419379258137775,0.0 +2000,Wal,9,F,4.918839153959665e-05,0.0 +2000,Wal,10,M,0.0001415294617162806,0.000731528895391368 +2000,Wal,10,F,4.940223298093074e-05,0.0 +2000,Wal,11,M,0.000142153146322972,0.0007342143906020558 +2000,Wal,11,F,0.0001001351824963701,0.0 +2000,Wal,12,M,0.0003438451714313784,0.0 +2000,Wal,12,F,0.0002576921094676081,0.00078003120124805 +2000,Wal,13,M,0.000196319018404908,0.0 +2000,Wal,13,F,0.0003634664312788826,0.0 +2000,Wal,14,M,0.0005122425980944575,0.0 +2000,Wal,14,F,0.00032088993475237987,0.0007645259938837921 +2000,Wal,15,M,0.0003117854915817918,0.0 +2000,Wal,15,F,0.0001081022647424464,0.0 +2000,Wal,16,M,0.0006271230729030572,0.0 +2000,Wal,16,F,0.0002810409757742679,0.0007117437722419928 +2000,Wal,17,M,0.001036752889948681,0.0006305170239596469 +2000,Wal,17,F,0.00048727666486193827,0.0005991611743559018 +2000,Wal,18,M,0.0011816687217427052,0.001829268292682927 +2000,Wal,18,F,0.0003160556257901391,0.0 +2000,Wal,19,M,0.00142900888026947,0.0006188118811881187 +2000,Wal,19,F,0.00015816111345423869,0.0 +2000,Wal,20,M,0.001139306059036769,0.001814882032667877 +2000,Wal,20,F,0.0006043956043956044,0.0 +2000,Wal,21,M,0.001964427926732148,0.001148105625717566 +2000,Wal,21,F,0.0004428452809299751,0.0005390835579514825 +2000,Wal,22,M,0.001627980254174982,0.001146131805157593 +2000,Wal,22,F,0.0002772079614126518,0.0004935834155972358 +2000,Wal,23,M,0.001313991380216546,0.0010449320794148381 +2000,Wal,23,F,0.0005494807407000385,0.000991571641051066 +2000,Wal,24,M,0.001694556238085152,0.0004918839153959665 +2000,Wal,24,F,0.0003852080123266564,0.0004761904761904762 +2000,Wal,25,M,0.0011416709911779973,0.001751313485113836 +2000,Wal,25,F,0.0003268864069735767,0.0 +2000,Wal,26,M,0.0014618409113821961,0.0003793626707132018 +2000,Wal,26,F,0.0004182569143096147,0.0004024144869215292 +2000,Wal,27,M,0.001325023310595279,0.0018115942028985512 +2000,Wal,27,F,0.0004564588933407719,0.0018261504747991238 +2000,Wal,28,M,0.001063675482280133,0.0 +2000,Wal,28,F,0.0003462090113259805,0.0 +2000,Wal,29,M,0.00172873654055122,0.001712328767123288 +2000,Wal,29,F,0.0004552812626467017,0.0007228044813877846 +2000,Wal,30,M,0.0012870649967823382,0.001967213114754098 +2000,Wal,30,F,0.00060234916173075,0.0006798096532970768 +2000,Wal,31,M,0.001364532268661242,0.0028580501746586213 +2000,Wal,31,F,0.0005542957923910305,0.0009787928221859708 +2000,Wal,32,M,0.002015534362402911,0.001593879502709595 +2000,Wal,32,F,0.0004948045522018803,0.0003373819163292848 +2000,Wal,33,M,0.0017872669307313308,0.001103448275862069 +2000,Wal,33,F,0.0009145607701564381,0.0006188118811881187 +2000,Wal,34,M,0.0016740292955126721,0.001850872554204125 +2000,Wal,34,F,0.000695829660899012,0.0012296341838303108 +2000,Wal,35,M,0.002098776457979816,0.0005392289026691831 +2000,Wal,35,F,0.0006683002895967921,0.0009179926560587516 +2000,Wal,36,M,0.002451202905129369,0.001877682403433477 +2000,Wal,36,F,0.000935620405435509,0.0 +2000,Wal,37,M,0.002370659601171385,0.001103752759381898 +2000,Wal,37,F,0.000955240174672489,0.001340482573726542 +2000,Wal,38,M,0.00279985549132948,0.00169061707523246 +2000,Wal,38,F,0.000970873786407767,0.0006377551020408162 +2000,Wal,39,M,0.001909090909090909,0.002061855670103093 +2000,Wal,39,F,0.001304308716380319,0.0006775067750677508 +2000,Wal,40,M,0.002252759630547421,0.002725538293813028 +2000,Wal,40,F,0.001561889886762983,0.001019021739130435 +2000,Wal,41,M,0.003075934257643927,0.0018934271030565328 +2000,Wal,41,F,0.0009264569638681783,0.0006990562740300594 +2000,Wal,42,M,0.0033793167299324143,0.0021971985718209283 +2000,Wal,42,F,0.0018478456823508207,0.001471670345842531 +2000,Wal,43,M,0.003637737988378136,0.002943537597002944 +2000,Wal,43,F,0.002088820270638453,0.0010737294201861134 +2000,Wal,44,M,0.003585600229478415,0.0041946308724832215 +2000,Wal,44,F,0.002093002093002093,0.0015043249341857839 +2000,Wal,45,M,0.004270018711317949,0.0025780578630764826 +2000,Wal,45,F,0.002017515704525655,0.0003853564547206166 +2000,Wal,46,M,0.005512943432406521,0.003305288461538462 +2000,Wal,46,F,0.0030120481927710854,0.001674340728338217 +2000,Wal,47,M,0.006042442113404553,0.002810743285446596 +2000,Wal,47,F,0.002870318087709392,0.001253656498119515 +2000,Wal,48,M,0.0059293502839053314,0.003228931223764934 +2000,Wal,48,F,0.002767307600553462,0.0012931034482758616 +2000,Wal,49,M,0.006293235972328978,0.0038083148206918436 +2000,Wal,49,F,0.004015495086923659,0.001261564339781329 +2000,Wal,50,M,0.006381435823060188,0.006646726487205053 +2000,Wal,50,F,0.00401682340154057,0.0009086778736937756 +2000,Wal,51,M,0.0070392592242641844,0.0047011417058428475 +2000,Wal,51,F,0.003252404947320202,0.002589555459646094 +2000,Wal,52,M,0.0095711916607439,0.003359086328518643 +2000,Wal,52,F,0.0045169616519174045,0.001885014137606032 +2000,Wal,53,M,0.00970638194612958,0.007272727272727274 +2000,Wal,53,F,0.00371643593793552,0.00506842372022301 +2000,Wal,54,M,0.01017347071866441,0.006389776357827476 +2000,Wal,54,F,0.004553457592131625,0.0 +2000,Wal,55,M,0.009396149549904724,0.007342817806333181 +2000,Wal,55,F,0.006387200793749225,0.0035211267605633812 +2000,Wal,56,M,0.01180272586764086,0.007161125319693096 +2000,Wal,56,F,0.004591067095166262,0.007731958762886598 +2000,Wal,57,M,0.01166369674388466,0.01414581066376496 +2000,Wal,57,F,0.005863339096444411,0.005259697567389875 +2000,Wal,58,M,0.0123714932915142,0.006141820212171971 +2000,Wal,58,F,0.005316194556851543,0.005483207676490747 +2000,Wal,59,M,0.01271649243251678,0.009017560512577124 +2000,Wal,59,F,0.006525748333096893,0.008059873344847437 +2000,Wal,60,M,0.01276043544084781,0.012953367875647671 +2000,Wal,60,F,0.0071286365679789345,0.0040935672514619895 +2000,Wal,61,M,0.01608751608751609,0.018363939899833055 +2000,Wal,61,F,0.008654453569172457,0.0058173356602675965 +2000,Wal,62,M,0.015617960654752969,0.01311475409836066 +2000,Wal,62,F,0.007023881196066627,0.009073233959818535 +2000,Wal,63,M,0.0195487559882553,0.016192071468453386 +2000,Wal,63,F,0.008103944812805573,0.005076142131979695 +2000,Wal,64,M,0.02147385103011094,0.01734104046242775 +2000,Wal,64,F,0.01001882732651963,0.004369538077403246 +2000,Wal,65,M,0.022328548644338118,0.01912399753238742 +2000,Wal,65,F,0.01013622570856737,0.009398496240601505 +2000,Wal,66,M,0.024250743536948068,0.02407407407407408 +2000,Wal,66,F,0.009956681968061029,0.007975460122699387 +2000,Wal,67,M,0.0252014652014652,0.030339083878643668 +2000,Wal,67,F,0.012216196889339141,0.01229773462783172 +2000,Wal,68,M,0.03333573331413349,0.02484889187374077 +2000,Wal,68,F,0.0139921040408732,0.008430609597924774 +2000,Wal,69,M,0.0381877502595284,0.03125 +2000,Wal,69,F,0.01440520446096654,0.01689612015018774 +2000,Wal,70,M,0.038188631108985086,0.03552278820375336 +2000,Wal,70,F,0.01738278859101481,0.01389808074123097 +2000,Wal,71,M,0.03979310920163511,0.04961020552799433 +2000,Wal,71,F,0.01903429822427633,0.014634146341463419 +2000,Wal,72,M,0.041750021744803,0.0390347764371895 +2000,Wal,72,F,0.02256770310932799,0.02105978260869565 +2000,Wal,73,M,0.04643210654188788,0.05407354001441962 +2000,Wal,73,F,0.02644503211182471,0.01629327902240326 +2000,Wal,74,M,0.05134610047182903,0.06645316253002402 +2000,Wal,74,F,0.02768187422934649,0.03246294989414256 +2000,Wal,75,M,0.05863224280646433,0.06689246401354784 +2000,Wal,75,F,0.03018095786175587,0.03189066059225513 +2000,Wal,76,M,0.06607788891253458,0.08064516129032258 +2000,Wal,76,F,0.03314217124566552,0.03484602917341977 +2000,Wal,77,M,0.06882821387940842,0.08315789473684211 +2000,Wal,77,F,0.03803680981595093,0.03265666372462489 +2000,Wal,78,M,0.08274117788751054,0.08531994981179424 +2000,Wal,78,F,0.04457205359584359,0.04243008678881389 +2000,Wal,79,M,0.0861726103672279,0.1073025335320417 +2000,Wal,79,F,0.0523356401384083,0.0481675392670157 +2000,Wal,80,M,0.0970059880239521,0.09207161125319692 +2000,Wal,80,F,0.0572696316169642,0.04918032786885247 +2000,Wal,81,M,0.1027027027027027,0.1323529411764706 +2000,Wal,81,F,0.07544873745056282,0.0810126582278481 +2000,Wal,82,M,0.1066666666666667,0.1189427312775331 +2000,Wal,82,F,0.07325325664016241,0.0576923076923077 +2000,Wal,83,M,0.1225296442687747,0.1339712918660287 +2000,Wal,83,F,0.08331961139469785,0.08571428571428573 +2000,Wal,84,M,0.1441728657456607,0.1296296296296296 +2000,Wal,84,F,0.0958438100872652,0.1151241534988713 +2000,Wal,85,M,0.1602763385146805,0.1658536585365854 +2000,Wal,85,F,0.1075124311248488,0.1272727272727273 +2000,Wal,86,M,0.1580050293378039,0.1435897435897436 +2000,Wal,86,F,0.122000309645456,0.08831168831168831 +2000,Wal,87,M,0.1933471933471934,0.1746987951807229 +2000,Wal,87,F,0.1274458874458875,0.165625 +2000,Wal,88,M,0.196866485013624,0.2413793103448276 +2000,Wal,88,F,0.1497788076680008,0.1294964028776979 +2000,Wal,89,M,0.2237061769616027,0.2361111111111111 +2000,Wal,89,F,0.1624390243902439,0.1704545454545455 +2000,Wal,90,M,0.2303240740740741,0.2368421052631579 +2000,Wal,90,F,0.1886735311932162,0.155 +2000,Wal,91,M,0.2549019607843137,0.1818181818181818 +2000,Wal,91,F,0.2015503875968992,0.2121212121212121 +2000,Wal,92,M,0.2584745762711864,0.4090909090909091 +2000,Wal,92,F,0.221183800623053,0.2156862745098039 +2000,Wal,93,M,0.2711864406779661,0.2727272727272727 +2000,Wal,93,F,0.2319018404907976,0.2424242424242425 +2000,Wal,94,M,0.2618025751072962,0.4285714285714286 +2000,Wal,94,F,0.2372598162071846,0.2465753424657534 +2000,Wal,95,M,0.3419354838709678,0.2857142857142857 +2000,Wal,95,F,0.2955555555555556,0.1481481481481482 +2000,Wal,96,M,0.3363636363636364,0.1666666666666667 +2000,Wal,96,F,0.2932454695222405,0.2142857142857143 +2000,Wal,97,M,0.4492753623188406,0.5714285714285714 +2000,Wal,97,F,0.3241758241758242,0.2727272727272727 +2000,Wal,98,M,0.4285714285714286,0.0 +2000,Wal,98,F,0.3355704697986578,0.375 +2000,Wal,99,M,0.3333333333333333,0.6 +2000,Wal,99,F,0.3212121212121213,0.1818181818181818 +2000,Wal,100,M,0.3888888888888889,0.0 +2000,Wal,100,F,0.3695652173913043,0.3333333333333333 +2000,Wal,101,M,0.2857142857142857,0.6666666666666666 +2000,Wal,101,F,0.3584905660377358,1.0 +2000,Wal,102,M,0.25,1.0 +2000,Wal,102,F,0.5365853658536586,0.25 +2000,Wal,103,M,0.0,0.0 +2000,Wal,103,F,0.4615384615384616,1.0 +2000,Wal,104,M,0.0,0.0 +2000,Wal,104,F,0.5,0.0 +2000,Wal,105,M,1.0,0.0 +2000,Wal,105,F,0.5,0.0 +2000,Wal,106,M,0.0,0.0 +2000,Wal,106,F,0.3333333333333333,0.0 +2000,Wal,107,M,0.0,0.0 +2000,Wal,107,F,0.3333333333333333,0.0 +2000,Wal,108,M,0.0,0.0 +2000,Wal,108,F,0.0,0.0 +2000,Wal,109,M,0.0,0.0 +2000,Wal,109,F,0.0,0.0 +2000,Wal,110,M,0.0,0.0 +2000,Wal,110,F,0.0,0.0 +2000,Wal,111,M,0.0,0.0 +2000,Wal,111,F,0.0,0.0 +2000,Wal,112,M,0.0,0.0 +2000,Wal,112,F,0.0,0.0 +2000,Wal,113,M,0.0,0.0 +2000,Wal,113,F,0.0,0.0 +2000,Wal,114,M,0.0,0.0 +2000,Wal,114,F,0.0,0.0 +2000,Wal,115,M,0.0,0.0 +2000,Wal,115,F,0.0,0.0 +2000,Wal,116,M,0.0,0.0 +2000,Wal,116,F,0.0,0.0 +2000,Wal,117,M,0.0,0.0 +2000,Wal,117,F,0.0,0.0 +2000,Wal,118,M,0.0,0.0 +2000,Wal,118,F,0.0,0.0 +2000,Wal,119,M,0.0,0.0 +2000,Wal,119,F,0.0,0.0 +2000,Wal,120,M,0.0,0.0 +2000,Wal,120,F,0.0,0.0 +2001,BruCap,0,M,0.000547645125958379,0.0006523157208088715 +2001,BruCap,0,F,0.0003935458480913026,0.0006761325219743072 +2001,BruCap,1,M,0.0001953125,0.0006825938566552901 +2001,BruCap,1,F,0.0008193363375665711,0.0006988120195667365 +2001,BruCap,2,M,0.0002045408058907752,0.0 +2001,BruCap,2,F,0.000216169476869866,0.0 +2001,BruCap,3,M,0.0004100041000410004,0.0006702412868632707 +2001,BruCap,3,F,0.00022123893805309745,0.0 +2001,BruCap,4,M,0.0,0.0 +2001,BruCap,4,F,0.0,0.0 +2001,BruCap,5,M,0.0002257336343115124,0.0 +2001,BruCap,5,F,0.0,0.0 +2001,BruCap,6,M,0.00022588660492432798,0.0 +2001,BruCap,6,F,0.0,0.0007369196757553428 +2001,BruCap,7,M,0.0,0.000725689404934688 +2001,BruCap,7,F,0.0,0.0 +2001,BruCap,8,M,0.0002300966405890474,0.0006811989100817437 +2001,BruCap,8,F,0.00023668639053254438,0.0 +2001,BruCap,9,M,0.0,0.0007127583749109052 +2001,BruCap,9,F,0.0002378121284185494,0.0 +2001,BruCap,10,M,0.0,0.0006963788300835657 +2001,BruCap,10,F,0.0,0.0 +2001,BruCap,11,M,0.0,0.0007358351729212656 +2001,BruCap,11,F,0.0,0.0 +2001,BruCap,12,M,0.00023540489642184562,0.0 +2001,BruCap,12,F,0.0,0.0 +2001,BruCap,13,M,0.0,0.0 +2001,BruCap,13,F,0.0002515090543259558,0.0 +2001,BruCap,14,M,0.0002476473501733532,0.0 +2001,BruCap,14,F,0.0005200208008320333,0.0 +2001,BruCap,15,M,0.0005044136191677175,0.0 +2001,BruCap,15,F,0.0002812939521800282,0.0 +2001,BruCap,16,M,0.0005072279989855441,0.0 +2001,BruCap,16,F,0.0007884362680683312,0.0 +2001,BruCap,17,M,0.0005217845030002609,0.0007485029940119763 +2001,BruCap,17,F,0.0,0.0007552870090634441 +2001,BruCap,18,M,0.0002579313902501935,0.0006518904823989572 +2001,BruCap,18,F,0.0008006405124099278,0.0006277463904582549 +2001,BruCap,19,M,0.0007092198581560284,0.001336898395721925 +2001,BruCap,19,F,0.0004837929366231253,0.0006195786864931846 +2001,BruCap,20,M,0.00023380874444704232,0.00128783000643915 +2001,BruCap,20,F,0.0002264492753623189,0.0 +2001,BruCap,21,M,0.00046104195481788836,0.0005988023952095807 +2001,BruCap,21,F,0.0004662004662004662,0.0 +2001,BruCap,22,M,0.0009369875849144998,0.000564334085778781 +2001,BruCap,22,F,0.00021649707728945656,0.0 +2001,BruCap,23,M,0.0006697923643670463,0.0009606147934678194 +2001,BruCap,23,F,0.0002103934357248054,0.0 +2001,BruCap,24,M,0.0008898776418242492,0.0004171881518564873 +2001,BruCap,24,F,0.0002034174125305126,0.0003808073115003808 +2001,BruCap,25,M,0.0004132231404958678,0.0008322929671244277 +2001,BruCap,25,F,0.0006038647342995169,0.0 +2001,BruCap,26,M,0.001000400160064026,0.0013927576601671314 +2001,BruCap,26,F,0.0007786645902277592,0.0 +2001,BruCap,27,M,0.0007606008746910059,0.001001335113484646 +2001,BruCap,27,F,0.0003755868544600939,0.0 +2001,BruCap,28,M,0.0014872652909462731,0.001250390747108472 +2001,BruCap,28,F,0.0001890716581584421,0.0003058103975535168 +2001,BruCap,29,M,0.0016838166510757722,0.0002969121140142518 +2001,BruCap,29,F,0.0003824091778202677,0.0 +2001,BruCap,30,M,0.0007680491551459293,0.000282326369282891 +2001,BruCap,30,F,0.0009769441187964048,0.0003166561114629513 +2001,BruCap,31,M,0.001554907677356657,0.00029481132075471697 +2001,BruCap,31,F,0.0004200798151648813,0.0003051571559353067 +2001,BruCap,32,M,0.001026272577996716,0.0002888503755054882 +2001,BruCap,32,F,0.0006450225757901526,0.0006514657980456026 +2001,BruCap,33,M,0.002302700439606448,0.0006184291898577612 +2001,BruCap,33,F,0.0008804754567466431,0.0010043521928356212 +2001,BruCap,34,M,0.00167890870933893,0.001486325802615934 +2001,BruCap,34,F,0.0004315925766076824,0.0003356831151393085 +2001,BruCap,35,M,0.0008093889113719142,0.0006190034045187249 +2001,BruCap,35,F,0.001711229946524064,0.0 +2001,BruCap,36,M,0.001861042183622829,0.0015693659761456366 +2001,BruCap,36,F,0.001952277657266811,0.0003394433129667346 +2001,BruCap,37,M,0.00104602510460251,0.0010312822275696108 +2001,BruCap,37,F,0.00108837614279495,0.0 +2001,BruCap,38,M,0.001548672566371682,0.002069679199724043 +2001,BruCap,38,F,0.00089126559714795,0.0007827788649706457 +2001,BruCap,39,M,0.0019942388654996678,0.001189532117367169 +2001,BruCap,39,F,0.0017625027539105531,0.0008166598611678236 +2001,BruCap,40,M,0.0030401737242128127,0.001982553528945282 +2001,BruCap,40,F,0.002148689299527289,0.0008163265306122449 +2001,BruCap,41,M,0.001983252534156016,0.0034497628288055198 +2001,BruCap,41,F,0.0015053763440860224,0.0004448398576512456 +2001,BruCap,42,M,0.002939181550983496,0.003194888178913738 +2001,BruCap,42,F,0.002845884413309983,0.0018912529550827427 +2001,BruCap,43,M,0.004110527517698105,0.002548419979612641 +2001,BruCap,43,F,0.001969365426695843,0.0010005002501250618 +2001,BruCap,44,M,0.0051825677267373395,0.003375120540019287 +2001,BruCap,44,F,0.001308615049073065,0.0009832841691248774 +2001,BruCap,45,M,0.006338028169014085,0.0039273441335297005 +2001,BruCap,45,F,0.0032858707557502733,0.0 +2001,BruCap,46,M,0.004453820909517112,0.0005574136008918619 +2001,BruCap,46,F,0.0020165807752632768,0.001078748651564185 +2001,BruCap,47,M,0.00420954162768943,0.0011312217194570141 +2001,BruCap,47,F,0.00417215634606939,0.0005858230814294082 +2001,BruCap,48,M,0.006265954977953121,0.002793296089385475 +2001,BruCap,48,F,0.0021963540522732267,0.001687289088863892 +2001,BruCap,49,M,0.007581315725116166,0.0031113876789047924 +2001,BruCap,49,F,0.003420752565564425,0.001314060446780552 +2001,BruCap,50,M,0.007698038241867395,0.004648460197559558 +2001,BruCap,50,F,0.003564268211182892,0.0018094089264173712 +2001,BruCap,51,M,0.00748502994011976,0.001297858533419857 +2001,BruCap,51,F,0.001588021778584392,0.003378378378378379 +2001,BruCap,52,M,0.0076092292587137955,0.001865671641791045 +2001,BruCap,52,F,0.0051224944320712685,0.0006854009595613432 +2001,BruCap,53,M,0.007400098667982241,0.002567394094993582 +2001,BruCap,53,F,0.004967602591792656,0.0035765379113018602 +2001,BruCap,54,M,0.009796718099436693,0.005610098176718092 +2001,BruCap,54,F,0.006890420093354078,0.0007293946024799418 +2001,BruCap,55,M,0.010641357492090879,0.0038971161340607954 +2001,BruCap,55,F,0.005583756345177665,0.004177109440267335 +2001,BruCap,56,M,0.00946021146355036,0.003863987635239568 +2001,BruCap,56,F,0.005311443746982134,0.0040650406504065045 +2001,BruCap,57,M,0.012384792626728107,0.006639004149377593 +2001,BruCap,57,F,0.005834601725012685,0.00546448087431694 +2001,BruCap,58,M,0.01692103516921035,0.002477291494632535 +2001,BruCap,58,F,0.005028098195800059,0.001813236627379873 +2001,BruCap,59,M,0.01487414187643021,0.006685768863419293 +2001,BruCap,59,F,0.009650582362728786,0.005452562704471101 +2001,BruCap,60,M,0.01167983510821024,0.01376518218623482 +2001,BruCap,60,F,0.006900690069006901,0.0008368200836820082 +2001,BruCap,61,M,0.018443997317236758,0.01070472792149866 +2001,BruCap,61,F,0.004965517241379311,0.004849660523763337 +2001,BruCap,62,M,0.01543624161073826,0.015165031222123109 +2001,BruCap,62,F,0.0107770845150312,0.0063424947145877385 +2001,BruCap,63,M,0.02204338698390483,0.01626794258373206 +2001,BruCap,63,F,0.008393632416787264,0.00922722029988466 +2001,BruCap,64,M,0.02288984263233191,0.01693227091633466 +2001,BruCap,64,F,0.01133062173155143,0.009944751381215469 +2001,BruCap,65,M,0.02102973168963017,0.017441860465116282 +2001,BruCap,65,F,0.009664582148948265,0.0101925254813137 +2001,BruCap,66,M,0.02125435540069686,0.0243605359317905 +2001,BruCap,66,F,0.01003440366972477,0.011435832274459979 +2001,BruCap,67,M,0.02827111272200073,0.01587301587301587 +2001,BruCap,67,F,0.014635444385311341,0.008784773060029283 +2001,BruCap,68,M,0.02540650406504065,0.01849405548216645 +2001,BruCap,68,F,0.0142966556037784,0.0071530758226037204 +2001,BruCap,69,M,0.02447314751869477,0.03184713375796179 +2001,BruCap,69,F,0.01586502140518761,0.0095389507154213 +2001,BruCap,70,M,0.03904863329783458,0.02453102453102453 +2001,BruCap,70,F,0.01907420330309374,0.014184397163120569 +2001,BruCap,71,M,0.0340993328391401,0.03125 +2001,BruCap,71,F,0.01868478524629944,0.01553398058252427 +2001,BruCap,72,M,0.0344574780058651,0.03754940711462451 +2001,BruCap,72,F,0.02249134948096886,0.01270417422867514 +2001,BruCap,73,M,0.03672851192730027,0.03225806451612903 +2001,BruCap,73,F,0.02141640301776588,0.01505376344086022 +2001,BruCap,74,M,0.05080213903743317,0.03597122302158273 +2001,BruCap,74,F,0.02535545023696683,0.01385681293302541 +2001,BruCap,75,M,0.04911059551430781,0.05013927576601671 +2001,BruCap,75,F,0.028699129616560813,0.0173697270471464 +2001,BruCap,76,M,0.05674846625766871,0.05923344947735192 +2001,BruCap,76,F,0.03114266086558278,0.02083333333333333 +2001,BruCap,77,M,0.05934343434343434,0.1084745762711864 +2001,BruCap,77,F,0.035436671239140384,0.02292263610315186 +2001,BruCap,78,M,0.07360070515645659,0.044280442804428034 +2001,BruCap,78,F,0.03776683087027915,0.04666666666666667 +2001,BruCap,79,M,0.0818688384054865,0.042735042735042736 +2001,BruCap,79,F,0.044200187090739015,0.04744525547445255 +2001,BruCap,80,M,0.07729468599033816,0.07526881720430108 +2001,BruCap,80,F,0.0495260663507109,0.04100946372239748 +2001,BruCap,81,M,0.0704514363885089,0.1544715447154472 +2001,BruCap,81,F,0.0593278463648834,0.05181347150259067 +2001,BruCap,82,M,0.08574739281575898,0.0505050505050505 +2001,BruCap,82,F,0.06271268838113757,0.007575757575757577 +2001,BruCap,83,M,0.1208791208791209,0.1123595505617977 +2001,BruCap,83,F,0.06656266250650028,0.06 +2001,BruCap,84,M,0.1238223418573351,0.1428571428571429 +2001,BruCap,84,F,0.08506329113924051,0.1196581196581197 +2001,BruCap,85,M,0.1384248210023866,0.08064516129032258 +2001,BruCap,85,F,0.08393501805054153,0.06896551724137931 +2001,BruCap,86,M,0.143646408839779,0.1846153846153846 +2001,BruCap,86,F,0.09287796751353602,0.08270676691729323 +2001,BruCap,87,M,0.1668874172185431,0.047619047619047616 +2001,BruCap,87,F,0.1188118811881188,0.078125 +2001,BruCap,88,M,0.2027257240204429,0.04444444444444445 +2001,BruCap,88,F,0.1318327974276527,0.09649122807017543 +2001,BruCap,89,M,0.2054507337526206,0.28125 +2001,BruCap,89,F,0.131396083385976,0.05333333333333334 +2001,BruCap,90,M,0.1797752808988764,0.1612903225806452 +2001,BruCap,90,F,0.1680972818311874,0.1395348837209302 +2001,BruCap,91,M,0.2137404580152672,0.25 +2001,BruCap,91,F,0.1684311838306064,0.1571428571428572 +2001,BruCap,92,M,0.2511848341232228,0.1428571428571429 +2001,BruCap,92,F,0.1651884700665189,0.0975609756097561 +2001,BruCap,93,M,0.2916666666666667,0.1818181818181818 +2001,BruCap,93,F,0.2270114942528736,0.1666666666666667 +2001,BruCap,94,M,0.2673267326732674,0.0 +2001,BruCap,94,F,0.2234432234432235,0.2 +2001,BruCap,95,M,0.18987341772151894,0.8 +2001,BruCap,95,F,0.2334152334152334,0.3461538461538462 +2001,BruCap,96,M,0.2826086956521739,0.0 +2001,BruCap,96,F,0.2175438596491228,0.1428571428571429 +2001,BruCap,97,M,0.46875,0.0 +2001,BruCap,97,F,0.2575757575757576,0.3571428571428572 +2001,BruCap,98,M,0.48,0.75 +2001,BruCap,98,F,0.30201342281879195,0.1538461538461539 +2001,BruCap,99,M,0.09090909090909093,0.0 +2001,BruCap,99,F,0.3888888888888889,0.3333333333333333 +2001,BruCap,100,M,0.3333333333333333,0.0 +2001,BruCap,100,F,0.3,0.2 +2001,BruCap,101,M,0.5,0.0 +2001,BruCap,101,F,0.3142857142857143,0.0 +2001,BruCap,102,M,0.0,0.0 +2001,BruCap,102,F,0.375,0.0 +2001,BruCap,103,M,1.0,0.0 +2001,BruCap,103,F,0.2727272727272727,0.0 +2001,BruCap,104,M,0.0,0.0 +2001,BruCap,104,F,0.125,0.0 +2001,BruCap,105,M,0.0,0.0 +2001,BruCap,105,F,0.0,0.0 +2001,BruCap,106,M,0.0,0.0 +2001,BruCap,106,F,0.0,0.0 +2001,BruCap,107,M,0.0,0.0 +2001,BruCap,107,F,0.0,0.0 +2001,BruCap,108,M,0.0,0.0 +2001,BruCap,108,F,0.0,0.0 +2001,BruCap,109,M,0.0,0.0 +2001,BruCap,109,F,0.0,0.0 +2001,BruCap,110,M,0.0,0.0 +2001,BruCap,110,F,0.0,0.0 +2001,BruCap,111,M,0.0,0.0 +2001,BruCap,111,F,0.0,0.0 +2001,BruCap,112,M,0.0,0.0 +2001,BruCap,112,F,0.0,0.0 +2001,BruCap,113,M,0.0,0.0 +2001,BruCap,113,F,0.0,0.0 +2001,BruCap,114,M,0.0,0.0 +2001,BruCap,114,F,0.0,0.0 +2001,BruCap,115,M,0.0,0.0 +2001,BruCap,115,F,0.0,0.0 +2001,BruCap,116,M,0.0,0.0 +2001,BruCap,116,F,0.0,0.0 +2001,BruCap,117,M,0.0,0.0 +2001,BruCap,117,F,0.0,0.0 +2001,BruCap,118,M,0.0,0.0 +2001,BruCap,118,F,0.0,0.0 +2001,BruCap,119,M,0.0,0.0 +2001,BruCap,119,F,0.0,0.0 +2001,BruCap,120,M,0.0,0.0 +2001,BruCap,120,F,0.0,0.0 +2001,Fla,0,M,0.001070807120867354,0.0012698412698412696 +2001,Fla,0,F,0.001115099139282852,0.001319261213720317 +2001,Fla,1,M,0.0002332944509248459,0.0 +2001,Fla,1,F,0.0003446730775859098,0.0006418485237483952 +2001,Fla,2,M,0.0005165289256198346,0.0 +2001,Fla,2,F,0.0003061432750527247,0.0 +2001,Fla,3,M,0.00018961539677021786,0.0 +2001,Fla,3,F,0.0002302252918927808,0.0 +2001,Fla,4,M,0.0003136467710064925,0.0 +2001,Fla,4,F,0.000163569746139754,0.0 +2001,Fla,5,M,0.00015614265192680031,0.0012953367875647669 +2001,Fla,5,F,0.0002285191956124315,0.0 +2001,Fla,6,M,6.173792251890722e-05,0.0006172839506172839 +2001,Fla,6,F,0.000227132612998475,0.0 +2001,Fla,7,M,0.0001185431052366417,0.0006337135614702152 +2001,Fla,7,F,0.000152401853206535,0.0 +2001,Fla,8,M,0.0001710230025938489,0.0 +2001,Fla,8,F,8.924852739929791e-05,0.0 +2001,Fla,9,M,5.6236643797098194e-05,0.0 +2001,Fla,9,F,8.887045649791154e-05,0.0 +2001,Fla,10,M,0.0001136137699889227,0.0 +2001,Fla,10,F,0.00014893363517216732,0.001298701298701299 +2001,Fla,11,M,0.00011720581340834507,0.0 +2001,Fla,11,F,9.228497600590623e-05,0.0 +2001,Fla,12,M,0.00011826621725504109,0.0 +2001,Fla,12,F,0.00018579302656840282,0.000731528895391368 +2001,Fla,13,M,0.0002684403614996869,0.0 +2001,Fla,13,F,9.465812640015148e-05,0.0 +2001,Fla,14,M,0.0003568985515867115,0.0007347538574577517 +2001,Fla,14,F,0.00012638629972510978,0.0 +2001,Fla,15,M,0.0006138923846649683,0.0 +2001,Fla,15,F,0.0002574168221893301,0.001463057790782736 +2001,Fla,16,M,0.0006903797088398619,0.0006863417982155112 +2001,Fla,16,F,0.0003153479865031062,0.0 +2001,Fla,17,M,0.0009651945013161742,0.0006958942240779402 +2001,Fla,17,F,0.0003350798099183624,0.00065359477124183 +2001,Fla,18,M,0.000768223979969271,0.0006609385327164572 +2001,Fla,18,F,0.0002402835345707936,0.001892744479495268 +2001,Fla,19,M,0.001070076277232069,0.0006657789613848202 +2001,Fla,19,F,0.0003500481316180975,0.0005824111822947001 +2001,Fla,20,M,0.001165792322424848,0.0006430868167202572 +2001,Fla,20,F,0.0005484513465923851,0.0005479452054794519 +2001,Fla,21,M,0.0009615648781559932,0.003021148036253777 +2001,Fla,21,F,0.00046468401486988845,0.000512295081967213 +2001,Fla,22,M,0.001350666891777816,0.0005963029218843173 +2001,Fla,22,F,0.00029220115127253596,0.0004657661853749418 +2001,Fla,23,M,0.00100809355108154,0.0005359056806002144 +2001,Fla,23,F,0.0003563897716135547,0.0 +2001,Fla,24,M,0.001413718964450859,0.000975609756097561 +2001,Fla,24,F,0.0002159427443237907,0.0004068348250610252 +2001,Fla,25,M,0.001061474539774967,0.0 +2001,Fla,25,F,9.545628102329136e-05,0.0 +2001,Fla,26,M,0.001024800163968026,0.0008213552361396304 +2001,Fla,26,F,0.0005481788281154831,0.001107011070110701 +2001,Fla,27,M,0.001100948509485095,0.0007779074290159472 +2001,Fla,27,F,0.0005294896308280629,0.0 +2001,Fla,28,M,0.0008947696645969467,0.0007165890361877463 +2001,Fla,28,F,0.0005021901068548951,0.0 +2001,Fla,29,M,0.0010360010360010359,0.0006901311249137336 +2001,Fla,29,F,0.00026429156645611443,0.0006724949562878277 +2001,Fla,30,M,0.0011790973633375981,0.001310615989515072 +2001,Fla,30,F,0.0004927641475180248,0.0003157562361856647 +2001,Fla,31,M,0.0008525790516311844,0.001276324186343331 +2001,Fla,31,F,0.0004651403173290608,0.0006585446163977607 +2001,Fla,32,M,0.0011392624513955972,0.00160668380462725 +2001,Fla,32,F,0.00045924225028702635,0.0003370407819346141 +2001,Fla,33,M,0.0010245169283552929,0.001684636118598383 +2001,Fla,33,F,0.0003493711319624676,0.0006875214850464077 +2001,Fla,34,M,0.0009705148350124779,0.0006071645415907711 +2001,Fla,34,F,0.0005720823798627003,0.0006381620931716656 +2001,Fla,35,M,0.001247883055530796,0.0009448818897637796 +2001,Fla,35,F,0.0006927126627874758,0.0006835269993164733 +2001,Fla,36,M,0.0010486666952018151,0.0009110233829334953 +2001,Fla,36,F,0.0006802870372402291,0.0006882312456985548 +2001,Fla,37,M,0.001463656126907596,0.00131233595800525 +2001,Fla,37,F,0.0006860532023193022,0.0003705075954057058 +2001,Fla,38,M,0.001284787247942163,0.0006508298080052066 +2001,Fla,38,F,0.0007850173825277557,0.0 +2001,Fla,39,M,0.0014666608292106301,0.0031174229303775553 +2001,Fla,39,F,0.0007558074913860174,0.0016785564414603439 +2001,Fla,40,M,0.001896644055694395,0.001736714136853074 +2001,Fla,40,F,0.001005071040248527,0.0 +2001,Fla,41,M,0.00184327752298611,0.0014847809948032669 +2001,Fla,41,F,0.001008765047411957,0.0 +2001,Fla,42,M,0.001876633676638145,0.003319808188860199 +2001,Fla,42,F,0.0014041710786796187,0.001413760603204524 +2001,Fla,43,M,0.002194520485961856,0.0007730962504831851 +2001,Fla,43,F,0.001518407774247804,0.0004967709885742673 +2001,Fla,44,M,0.002467411545623836,0.001208215867901732 +2001,Fla,44,F,0.001609505550427229,0.002483854942871337 +2001,Fla,45,M,0.0033096926713947986,0.002449979583503471 +2001,Fla,45,F,0.001721417300243868,0.002641310089804543 +2001,Fla,46,M,0.002768549280177188,0.002969876962240136 +2001,Fla,46,F,0.0020153857497480767,0.0 +2001,Fla,47,M,0.003813225742963985,0.00046339202965708985 +2001,Fla,47,F,0.002133821063862216,0.001750291715285881 +2001,Fla,48,M,0.004289306315633782,0.002265518803806072 +2001,Fla,48,F,0.002018962917529199,0.002396644697423607 +2001,Fla,49,M,0.004316026154601608,0.003260363297624593 +2001,Fla,49,F,0.0021766251692193353,0.0019354838709677426 +2001,Fla,50,M,0.003549922427621026,0.005020538566864446 +2001,Fla,50,F,0.002739288848700833,0.0018645121193287765 +2001,Fla,51,M,0.0048371071484599685,0.003978779840848807 +2001,Fla,51,F,0.003056054472830604,0.001215066828675577 +2001,Fla,52,M,0.00503765119513027,0.003234750462107209 +2001,Fla,52,F,0.003179734492169904,0.0019582245430809398 +2001,Fla,53,M,0.005495521678247775,0.005535055350553504 +2001,Fla,53,F,0.003270689793839308,0.002582311168495804 +2001,Fla,54,M,0.006395708685785022,0.006416131989000917 +2001,Fla,54,F,0.003428631712205929,0.002070393374741201 +2001,Fla,55,M,0.007603787327021122,0.004422332780541736 +2001,Fla,55,F,0.0037483893639451795,0.0023273855702094647 +2001,Fla,56,M,0.007971760553022504,0.005652911249293386 +2001,Fla,56,F,0.004454671504852937,0.0036153289949385392 +2001,Fla,57,M,0.008209369791988148,0.007005253940455342 +2001,Fla,57,F,0.00439459127228027,0.0032206119162640893 +2001,Fla,58,M,0.007500088863612128,0.01058530510585305 +2001,Fla,58,F,0.005331732636559444,0.005709624796084829 +2001,Fla,59,M,0.01042864506919386,0.01325757575757576 +2001,Fla,59,F,0.004682043212956211,0.0018099547511312216 +2001,Fla,60,M,0.01003886010362694,0.006169031462060457 +2001,Fla,60,F,0.005024777350382922,0.002347417840375587 +2001,Fla,61,M,0.011194399498068221,0.013470173187940993 +2001,Fla,61,F,0.0063006300630063,0.005730659025787965 +2001,Fla,62,M,0.011527746645745941,0.02140468227424749 +2001,Fla,62,F,0.005294547224926972,0.003824091778202677 +2001,Fla,63,M,0.01425682172341766,0.01438304314912945 +2001,Fla,63,F,0.006403381490126806,0.008088978766430737 +2001,Fla,64,M,0.01602431275037989,0.024672320740169614 +2001,Fla,64,F,0.006626351003602675,0.003191489361702128 +2001,Fla,65,M,0.017012636958728608,0.01937046004842615 +2001,Fla,65,F,0.008740525721657797,0.01277584204413473 +2001,Fla,66,M,0.01687704370451109,0.018087855297157614 +2001,Fla,66,F,0.008927440800303912,0.0125 +2001,Fla,67,M,0.02063278595696489,0.020390070921985817 +2001,Fla,67,F,0.00960403305574168,0.010501750291715291 +2001,Fla,68,M,0.02438423645320197,0.03470919324577861 +2001,Fla,68,F,0.0101720958819914,0.02219321148825065 +2001,Fla,69,M,0.02416896761932083,0.019916142557651992 +2001,Fla,69,F,0.01250153959847272,0.009433962264150943 +2001,Fla,70,M,0.02788785600533314,0.03246753246753247 +2001,Fla,70,F,0.014903501387459859,0.018592297476759632 +2001,Fla,71,M,0.030956464918729068,0.02538071065989848 +2001,Fla,71,F,0.01479638161213303,0.01935483870967742 +2001,Fla,72,M,0.03609781342993919,0.0369881109643329 +2001,Fla,72,F,0.017353278034220668,0.0212443095599393 +2001,Fla,73,M,0.03883761308599105,0.046616541353383466 +2001,Fla,73,F,0.019791930981984267,0.02276707530647986 +2001,Fla,74,M,0.04318313113807048,0.0512396694214876 +2001,Fla,74,F,0.02289056576524534,0.024734982332155483 +2001,Fla,75,M,0.04594861660079051,0.0358974358974359 +2001,Fla,75,F,0.02540012625793754,0.02583025830258303 +2001,Fla,76,M,0.05403976311336717,0.04735883424408015 +2001,Fla,76,F,0.02879056501965621,0.02922755741127349 +2001,Fla,77,M,0.058843537414965986,0.07007575757575757 +2001,Fla,77,F,0.03385550250562285,0.02510460251046025 +2001,Fla,78,M,0.06528189910979229,0.06511627906976744 +2001,Fla,78,F,0.03625261539775397,0.029411764705882363 +2001,Fla,79,M,0.0695212729631906,0.08080808080808081 +2001,Fla,79,F,0.04318512316573393,0.04060913705583756 +2001,Fla,80,M,0.0814135540147618,0.09826589595375723 +2001,Fla,80,F,0.04912725225225225,0.05681818181818182 +2001,Fla,81,M,0.09257265877287406,0.1052631578947368 +2001,Fla,81,F,0.057709532949456174,0.07079646017699115 +2001,Fla,82,M,0.09652715939447908,0.125748502994012 +2001,Fla,82,F,0.06306219170132507,0.0427807486631016 +2001,Fla,83,M,0.1149169031211999,0.1134751773049646 +2001,Fla,83,F,0.07429760665972945,0.06470588235294117 +2001,Fla,84,M,0.1277636470358051,0.1203007518796993 +2001,Fla,84,F,0.08288003164869942,0.09815950920245403 +2001,Fla,85,M,0.1419844502036283,0.08035714285714286 +2001,Fla,85,F,0.09509671614934773,0.08749999999999998 +2001,Fla,86,M,0.1550387596899225,0.1224489795918368 +2001,Fla,86,F,0.1062393162393162,0.0759493670886076 +2001,Fla,87,M,0.1631419939577039,0.1518987341772152 +2001,Fla,87,F,0.1195538182858233,0.1258741258741259 +2001,Fla,88,M,0.1880487114131974,0.25 +2001,Fla,88,F,0.1393112701252236,0.1311475409836066 +2001,Fla,89,M,0.2083333333333334,0.1785714285714286 +2001,Fla,89,F,0.1457423580786026,0.1264367816091954 +2001,Fla,90,M,0.2142857142857143,0.07142857142857142 +2001,Fla,90,F,0.1692130770494497,0.1506849315068493 +2001,Fla,91,M,0.2334630350194553,0.21875 +2001,Fla,91,F,0.1838915142798439,0.1690140845070423 +2001,Fla,92,M,0.2504440497335702,0.1538461538461539 +2001,Fla,92,F,0.1982528512496967,0.2553191489361702 +2001,Fla,93,M,0.273696682464455,0.4210526315789474 +2001,Fla,93,F,0.2210251387528567,0.2820512820512821 +2001,Fla,94,M,0.3001841620626151,0.2 +2001,Fla,94,F,0.2414721723518851,0.3461538461538462 +2001,Fla,95,M,0.3037383177570093,0.2 +2001,Fla,95,F,0.2725642558278542,0.2 +2001,Fla,96,M,0.3512544802867384,0.3333333333333333 +2001,Fla,96,F,0.2625448028673835,0.4 +2001,Fla,97,M,0.4,0.5 +2001,Fla,97,F,0.3155893536121673,0.07692307692307693 +2001,Fla,98,M,0.3483146067415731,0.0 +2001,Fla,98,F,0.3154981549815498,0.5 +2001,Fla,99,M,0.3636363636363637,0.3333333333333333 +2001,Fla,99,F,0.3522727272727273,0.7142857142857143 +2001,Fla,100,M,0.4,0.5 +2001,Fla,100,F,0.3575129533678757,0.1666666666666667 +2001,Fla,101,M,0.3529411764705883,0.0 +2001,Fla,101,F,0.3761467889908257,0.0 +2001,Fla,102,M,0.1666666666666667,0.0 +2001,Fla,102,F,0.4,0.75 +2001,Fla,103,M,0.6666666666666666,0.0 +2001,Fla,103,F,0.5142857142857142,0.0 +2001,Fla,104,M,0.0,0.0 +2001,Fla,104,F,0.5238095238095238,0.0 +2001,Fla,105,M,0.6666666666666666,0.0 +2001,Fla,105,F,0.5,0.0 +2001,Fla,106,M,1.0,0.0 +2001,Fla,106,F,1.0,0.0 +2001,Fla,107,M,0.0,0.0 +2001,Fla,107,F,1.0,0.0 +2001,Fla,108,M,0.0,0.0 +2001,Fla,108,F,0.0,0.0 +2001,Fla,109,M,0.0,0.0 +2001,Fla,109,F,0.0,0.0 +2001,Fla,110,M,0.0,0.0 +2001,Fla,110,F,0.0,0.0 +2001,Fla,111,M,0.0,0.0 +2001,Fla,111,F,0.0,0.0 +2001,Fla,112,M,0.0,0.0 +2001,Fla,112,F,0.0,0.0 +2001,Fla,113,M,0.0,0.0 +2001,Fla,113,F,0.0,0.0 +2001,Fla,114,M,0.0,0.0 +2001,Fla,114,F,0.0,0.0 +2001,Fla,115,M,0.0,0.0 +2001,Fla,115,F,0.0,0.0 +2001,Fla,116,M,0.0,0.0 +2001,Fla,116,F,0.0,0.0 +2001,Fla,117,M,0.0,0.0 +2001,Fla,117,F,0.0,0.0 +2001,Fla,118,M,0.0,0.0 +2001,Fla,118,F,0.0,0.0 +2001,Fla,119,M,0.0,0.0 +2001,Fla,119,F,0.0,0.0 +2001,Fla,120,M,0.0,0.0 +2001,Fla,120,F,0.0,0.0 +2001,Wal,0,M,0.0010869002639614929,0.003597122302158274 +2001,Wal,0,F,0.0005961736491247088,0.0 +2001,Wal,1,M,0.00031704095112285337,0.0 +2001,Wal,1,F,0.0004423800044238001,0.0 +2001,Wal,2,M,0.0002622882022766616,0.0 +2001,Wal,2,F,0.00010955302366345307,0.0 +2001,Wal,3,M,0.0002086811352253756,0.0 +2001,Wal,3,F,0.00021670820240546107,0.0 +2001,Wal,4,M,0.0002563445270443476,0.0 +2001,Wal,4,F,0.00010712372790573108,0.0 +2001,Wal,5,M,0.0002103270585760858,0.0 +2001,Wal,5,F,0.0002184121437151906,0.0 +2001,Wal,6,M,0.0004156491920818829,0.0 +2001,Wal,6,F,0.00010912860806460408,0.0 +2001,Wal,7,M,0.0003987439565369087,0.0 +2001,Wal,7,F,0.0002638383198775791,0.0 +2001,Wal,8,M,9.487215976471704e-05,0.0 +2001,Wal,8,F,9.928514694201746e-05,0.0 +2001,Wal,9,M,0.0002313529520636684,0.0008257638315441782 +2001,Wal,9,F,4.807923457858551e-05,0.0 +2001,Wal,10,M,0.00023466466419486557,0.0 +2001,Wal,10,F,0.00014652014652014652,0.0 +2001,Wal,11,M,0.0,0.0 +2001,Wal,11,F,0.00014727540500736382,0.0 +2001,Wal,12,M,0.0001410437235543018,0.0 +2001,Wal,12,F,0.00029741251115296917,0.0 +2001,Wal,13,M,0.00034171344886502317,0.0 +2001,Wal,13,F,5.11561285041948e-05,0.0 +2001,Wal,14,M,0.0004393887614119025,0.00076103500761035 +2001,Wal,14,F,0.00015484670176525242,0.0 +2001,Wal,15,M,0.0005091131249363608,0.0 +2001,Wal,15,F,0.000265717170643567,0.0 +2001,Wal,16,M,0.0009300883583940474,0.0007446016381236039 +2001,Wal,16,F,0.0004298995109893063,0.0007530120481927711 +2001,Wal,17,M,0.0006753948462177887,0.0 +2001,Wal,17,F,0.0003353641495724107,0.0 +2001,Wal,18,M,0.0008217770929635338,0.000700770847932726 +2001,Wal,18,F,0.000321646831778707,0.0006277463904582549 +2001,Wal,19,M,0.00122305457881058,0.0 +2001,Wal,19,F,0.00031420192710515286,0.0005963029218843173 +2001,Wal,20,M,0.001681614349775785,0.0006377551020408162 +2001,Wal,20,F,0.0002105928187848795,0.0005599104143337066 +2001,Wal,21,M,0.001608968702963617,0.0 +2001,Wal,21,F,0.0003301964668978042,0.0 +2001,Wal,22,M,0.00128,0.001143510577472842 +2001,Wal,22,F,0.00027807129748067406,0.0 +2001,Wal,23,M,0.0016426451886392536,0.0 +2001,Wal,23,F,0.0003920690041447295,0.000992063492063492 +2001,Wal,24,M,0.001860811313732788,0.0005252100840336134 +2001,Wal,24,F,0.0002769469369668772,0.0005025125628140704 +2001,Wal,25,M,0.001504082509669102,0.001943634596695821 +2001,Wal,25,F,0.0006117228339450561,0.0 +2001,Wal,26,M,0.0015195975686438901,0.0 +2001,Wal,26,F,0.0005449591280653951,0.0008635578583765112 +2001,Wal,27,M,0.001311276982045592,0.0007698229407236335 +2001,Wal,27,F,0.0007279155617948318,0.0004058441558441559 +2001,Wal,28,M,0.00181390332385528,0.000731528895391368 +2001,Wal,28,F,0.0002513320599175631,0.0007541478129713424 +2001,Wal,29,M,0.001060803317421284,0.0007173601147776184 +2001,Wal,29,F,0.000391561842298468,0.0003721622627465575 +2001,Wal,30,M,0.00152409046214356,0.0007002801120448178 +2001,Wal,30,F,0.0006014434643143544,0.0 +2001,Wal,31,M,0.001674381956072097,0.00033602150537634417 +2001,Wal,31,F,0.0005457432030164715,0.00070298769771529 +2001,Wal,32,M,0.001450797938866377,0.001350438892640108 +2001,Wal,32,F,0.000946262264056975,0.0 +2001,Wal,33,M,0.00190104801364855,0.0013249420337860221 +2001,Wal,33,F,0.00044089550776465976,0.0003483106931382794 +2001,Wal,34,M,0.002012554506684556,0.0020231213872832373 +2001,Wal,34,F,0.001239748235742895,0.0003170577045022194 +2001,Wal,35,M,0.001660363435107463,0.0005492996429552321 +2001,Wal,35,F,0.0011465786094294634,0.001300390117035111 +2001,Wal,36,M,0.00216766202167662,0.0005691519635742745 +2001,Wal,36,F,0.001059181782073348,0.00031685678073510766 +2001,Wal,37,M,0.002336973619163184,0.000569313976658127 +2001,Wal,37,F,0.001238499646142958,0.0 +2001,Wal,38,M,0.0026270913029451076,0.0008713331397037468 +2001,Wal,38,F,0.0009465428648697377,0.0007087172218284907 +2001,Wal,39,M,0.002110557276932058,0.001778304682868998 +2001,Wal,39,F,0.001880932592624995,0.0006718172657037286 +2001,Wal,40,M,0.0031069884726224787,0.0024563318777292573 +2001,Wal,40,F,0.001205303334672559,0.0010733452593917714 +2001,Wal,41,M,0.0035843899816300007,0.002871088142405972 +2001,Wal,41,F,0.001378478504350823,0.001077199281867145 +2001,Wal,42,M,0.003973147006439239,0.001132182281347297 +2001,Wal,42,F,0.001752694768206117,0.0018301610541727675 +2001,Wal,43,M,0.003963133640552996,0.0034383954154727802 +2001,Wal,43,F,0.001568943876636185,0.0003810975609756098 +2001,Wal,44,M,0.0039040451552210726,0.002258610954263128 +2001,Wal,44,F,0.002124773960216998,0.00150093808630394 +2001,Wal,45,M,0.0050387412653895534,0.0020636792452830197 +2001,Wal,45,F,0.0021311326743447896,0.002731174404994148 +2001,Wal,46,M,0.005221556886227545,0.0044736057262153295 +2001,Wal,46,F,0.0027416038382453733,0.0007990411506192569 +2001,Wal,47,M,0.005648906122839772,0.003772398616787174 +2001,Wal,47,F,0.002912352071005918,0.00044091710758377433 +2001,Wal,48,M,0.005895998453508604,0.005884275907159202 +2001,Wal,48,F,0.0028146549702115693,0.001757469244288225 +2001,Wal,49,M,0.005833542871511189,0.0046760187040748155 +2001,Wal,49,F,0.0024766622213755,0.001769128704113225 +2001,Wal,50,M,0.008223130560230824,0.0056031641397495035 +2001,Wal,50,F,0.004206049149338374,0.0025862068965517237 +2001,Wal,51,M,0.007352585497992552,0.006894174422612892 +2001,Wal,51,F,0.003979345302951348,0.002333177788147457 +2001,Wal,52,M,0.008291481095423103,0.005853994490358128 +2001,Wal,52,F,0.004309159255523975,0.00264783759929391 +2001,Wal,53,M,0.00832817779469852,0.007609823590453132 +2001,Wal,53,F,0.004016064257028112,0.004791566842357451 +2001,Wal,54,M,0.008877615726062145,0.00749063670411985 +2001,Wal,54,F,0.004604865342574073,0.002082248828735034 +2001,Wal,55,M,0.009515060043309927,0.008466603951081843 +2001,Wal,55,F,0.004865292221614061,0.00426049908703591 +2001,Wal,56,M,0.01142970401691332,0.007085498346717054 +2001,Wal,56,F,0.006030088275519085,0.001204093919325708 +2001,Wal,57,M,0.01190476190476191,0.008438818565400843 +2001,Wal,57,F,0.00545908971323336,0.003298153034300792 +2001,Wal,58,M,0.01404081632653061,0.01124859392575928 +2001,Wal,58,F,0.005723322539347843,0.003380662609871535 +2001,Wal,59,M,0.012832908499604471,0.01376146788990826 +2001,Wal,59,F,0.00810553083280356,0.006306937631394534 +2001,Wal,60,M,0.01518250471994966,0.016831683168316833 +2001,Wal,60,F,0.007127075760815338,0.0041297935103244855 +2001,Wal,61,M,0.01497310655618549,0.012339055793991421 +2001,Wal,61,F,0.006979449398991857,0.005363528009535161 +2001,Wal,62,M,0.01789466058103311,0.013929193267556593 +2001,Wal,62,F,0.0071301247771836,0.0035949670461354107 +2001,Wal,63,M,0.0155203895313451,0.018549747048903883 +2001,Wal,63,F,0.008208854797470059,0.01062416998671979 +2001,Wal,64,M,0.020433825840930533,0.0285381479324403 +2001,Wal,64,F,0.008428292090890702,0.007166123778501629 +2001,Wal,65,M,0.01971557853910795,0.01862980769230769 +2001,Wal,65,F,0.01071840445017299,0.01006289308176101 +2001,Wal,66,M,0.025993171942892617,0.0178343949044586 +2001,Wal,66,F,0.01335940045617465,0.008883248730964471 +2001,Wal,67,M,0.02601854015735764,0.02583979328165375 +2001,Wal,67,F,0.01286152640856565,0.01365611421477343 +2001,Wal,68,M,0.02821128451380552,0.03560274828232355 +2001,Wal,68,F,0.01290322580645161,0.01982815598149372 +2001,Wal,69,M,0.03215242631735636,0.03419399860432658 +2001,Wal,69,F,0.0151764705882353,0.01187335092348285 +2001,Wal,70,M,0.03774456940378986,0.03403141361256545 +2001,Wal,70,F,0.01489637305699482,0.01208651399491094 +2001,Wal,71,M,0.03896534571381198,0.03708887333799861 +2001,Wal,71,F,0.01913607180701864,0.014093959731543631 +2001,Wal,72,M,0.04027777777777778,0.04593373493975904 +2001,Wal,72,F,0.02286387012826074,0.02139800285306705 +2001,Wal,73,M,0.04220749750385768,0.04309063893016345 +2001,Wal,73,F,0.022300544697212432,0.02020905923344948 +2001,Wal,74,M,0.04637571872938071,0.05007704160246533 +2001,Wal,74,F,0.02548347454886489,0.03038674033149171 +2001,Wal,75,M,0.055940642389924834,0.05459272097053727 +2001,Wal,75,F,0.02871450304259635,0.02779809802487199 +2001,Wal,76,M,0.061303483627994565,0.06221408966148216 +2001,Wal,76,F,0.03441909534485033,0.03912363067292645 +2001,Wal,77,M,0.06492766829935072,0.08145240431795878 +2001,Wal,77,F,0.03666689640912537,0.04522613065326633 +2001,Wal,78,M,0.0791015625,0.08816705336426914 +2001,Wal,78,F,0.043151704102600434,0.045330915684496834 +2001,Wal,79,M,0.07854984894259819,0.110803324099723 +2001,Wal,79,F,0.04897404732966326,0.06097560975609756 +2001,Wal,80,M,0.0981443896781676,0.106312292358804 +2001,Wal,80,F,0.05302339714372531,0.05997818974918211 +2001,Wal,81,M,0.09712389380530974,0.1067415730337079 +2001,Wal,81,F,0.06476315501586259,0.07925801011804384 +2001,Wal,82,M,0.1198581560283688,0.123404255319149 +2001,Wal,82,F,0.07080663709544932,0.1054054054054054 +2001,Wal,83,M,0.1139188069594035,0.135678391959799 +2001,Wal,83,F,0.07936507936507936,0.08259587020648967 +2001,Wal,84,M,0.1281314168377824,0.1160220994475138 +2001,Wal,84,F,0.09763101220387653,0.08262108262108261 +2001,Wal,85,M,0.1602643535729038,0.1764705882352941 +2001,Wal,85,F,0.100604278948228,0.0891089108910891 +2001,Wal,86,M,0.1555555555555556,0.1488095238095238 +2001,Wal,86,F,0.1155294472059045,0.09898477157360408 +2001,Wal,87,M,0.1733266733266733,0.193939393939394 +2001,Wal,87,F,0.1260312445146568,0.1551246537396122 +2001,Wal,88,M,0.2002575660012878,0.2014388489208633 +2001,Wal,88,F,0.1527777777777778,0.1465201465201465 +2001,Wal,89,M,0.2307039864291773,0.1230769230769231 +2001,Wal,89,F,0.1690106094251172,0.2139917695473251 +2001,Wal,90,M,0.2149732620320856,0.2545454545454545 +2001,Wal,90,F,0.1940732132481116,0.2272727272727273 +2001,Wal,91,M,0.2679640718562874,0.1666666666666667 +2001,Wal,91,F,0.18801191362621,0.2298850574712644 +2001,Wal,92,M,0.3087934560327199,0.25 +2001,Wal,92,F,0.2280546978385532,0.1908396946564886 +2001,Wal,93,M,0.3008595988538682,0.2307692307692308 +2001,Wal,93,F,0.22139588100686494,0.2716049382716049 +2001,Wal,94,M,0.2795275590551181,0.4375 +2001,Wal,94,F,0.2578062449959968,0.2337662337662338 +2001,Wal,95,M,0.3609467455621302,0.3846153846153847 +2001,Wal,95,F,0.2712238147739802,0.3214285714285715 +2001,Wal,96,M,0.3883495145631068,0.2 +2001,Wal,96,F,0.2803149606299213,0.1914893617021277 +2001,Wal,97,M,0.3150684931506849,0.4 +2001,Wal,97,F,0.3037383177570093,0.3333333333333333 +2001,Wal,98,M,0.3333333333333333,0.0 +2001,Wal,98,F,0.3102040816326531,0.2307692307692308 +2001,Wal,99,M,0.3333333333333333,1.0 +2001,Wal,99,F,0.3641025641025641,0.4666666666666667 +2001,Wal,100,M,0.3846153846153847,0.0 +2001,Wal,100,F,0.3818181818181819,0.2 +2001,Wal,101,M,0.3636363636363637,0.0 +2001,Wal,101,F,0.4107142857142857,0.0 +2001,Wal,102,M,0.8,1.0 +2001,Wal,102,F,0.4242424242424243,0.0 +2001,Wal,103,M,0.0,0.0 +2001,Wal,103,F,0.2777777777777778,0.3333333333333333 +2001,Wal,104,M,0.0,0.0 +2001,Wal,104,F,0.4285714285714286,0.0 +2001,Wal,105,M,1.0,0.0 +2001,Wal,105,F,0.375,0.0 +2001,Wal,106,M,0.0,0.0 +2001,Wal,106,F,1.0,0.0 +2001,Wal,107,M,0.0,0.0 +2001,Wal,107,F,0.5,0.0 +2001,Wal,108,M,0.0,0.0 +2001,Wal,108,F,0.5,0.0 +2001,Wal,109,M,0.0,0.0 +2001,Wal,109,F,1.0,0.0 +2001,Wal,110,M,0.0,0.0 +2001,Wal,110,F,0.0,0.0 +2001,Wal,111,M,0.0,0.0 +2001,Wal,111,F,0.0,0.0 +2001,Wal,112,M,0.0,0.0 +2001,Wal,112,F,0.0,0.0 +2001,Wal,113,M,0.0,0.0 +2001,Wal,113,F,0.0,0.0 +2001,Wal,114,M,0.0,0.0 +2001,Wal,114,F,0.0,0.0 +2001,Wal,115,M,0.0,0.0 +2001,Wal,115,F,0.0,0.0 +2001,Wal,116,M,0.0,0.0 +2001,Wal,116,F,0.0,0.0 +2001,Wal,117,M,0.0,0.0 +2001,Wal,117,F,0.0,0.0 +2001,Wal,118,M,0.0,0.0 +2001,Wal,118,F,0.0,0.0 +2001,Wal,119,M,0.0,0.0 +2001,Wal,119,F,0.0,0.0 +2001,Wal,120,M,0.0,0.0 +2001,Wal,120,F,0.0,0.0 +2002,BruCap,0,M,0.001569037656903766,0.0006680026720106881 +2002,BruCap,0,F,0.0005376344086021505,0.0006896551724137933 +2002,BruCap,1,M,0.0001816860465116279,0.0 +2002,BruCap,1,F,0.00019603999215840032,0.0 +2002,BruCap,2,M,0.000192864030858245,0.0 +2002,BruCap,2,F,0.0,0.001508295625942685 +2002,BruCap,3,M,0.0003992812936713915,0.000777000777000777 +2002,BruCap,3,F,0.0,0.0007396449704142013 +2002,BruCap,4,M,0.0006027727546714887,0.0 +2002,BruCap,4,F,0.000432338953739732,0.0 +2002,BruCap,5,M,0.0,0.0 +2002,BruCap,5,F,0.0,0.0 +2002,BruCap,6,M,0.00021920210434020167,0.0 +2002,BruCap,6,F,0.0002255808707421611,0.0 +2002,BruCap,7,M,0.0002179123992155154,0.0 +2002,BruCap,7,F,0.0,0.0 +2002,BruCap,8,M,0.0,0.0 +2002,BruCap,8,F,0.0,0.0 +2002,BruCap,9,M,0.0006685981724983285,0.0 +2002,BruCap,9,F,0.0,0.0 +2002,BruCap,10,M,0.0,0.0 +2002,BruCap,10,F,0.0,0.0 +2002,BruCap,11,M,0.0,0.0007849293563579277 +2002,BruCap,11,F,0.00023507287259050307,0.0 +2002,BruCap,12,M,0.0,0.0 +2002,BruCap,12,F,0.00023523876734885907,0.0 +2002,BruCap,13,M,0.0004559963520291838,0.0008223684210526315 +2002,BruCap,13,F,0.00047846889952153117,0.0008896797153024912 +2002,BruCap,14,M,0.0,0.0008285004142502071 +2002,BruCap,14,F,0.0,0.0 +2002,BruCap,15,M,0.00023929169657812882,0.0 +2002,BruCap,15,F,0.0,0.0 +2002,BruCap,16,M,0.0002437241043139167,0.0 +2002,BruCap,16,F,0.0002687449610319807,0.0 +2002,BruCap,17,M,0.00072992700729927,0.000846740050804403 +2002,BruCap,17,F,0.0002527805864509606,0.0 +2002,BruCap,18,M,0.001261352169525732,0.0 +2002,BruCap,18,F,0.00025746652935118445,0.0 +2002,BruCap,19,M,0.0004909180166912126,0.002066115702479339 +2002,BruCap,19,F,0.0002489419965148121,0.0 +2002,BruCap,20,M,0.0006804264005443411,0.0 +2002,BruCap,20,F,0.0,0.0 +2002,BruCap,21,M,0.0013602357742008616,0.0 +2002,BruCap,21,F,0.0,0.0 +2002,BruCap,22,M,0.001106194690265487,0.0005611672278338945 +2002,BruCap,22,F,0.0004396570674873599,0.0 +2002,BruCap,23,M,0.001330082021724673,0.000996512207274539 +2002,BruCap,23,F,0.0008059641345960105,0.0 +2002,BruCap,24,M,0.0006211180124223603,0.00128589798542649 +2002,BruCap,24,F,0.0003896356906292616,0.0007695267410542518 +2002,BruCap,25,M,0.00125549278091651,0.0003721622627465575 +2002,BruCap,25,F,0.0005640157924421883,0.0003518648838845883 +2002,BruCap,26,M,0.0007780587434351293,0.0 +2002,BruCap,26,F,0.0005763688760806918,0.0 +2002,BruCap,27,M,0.0015530964861192,0.00031989763275751764 +2002,BruCap,27,F,0.0,0.0009469696969696972 +2002,BruCap,28,M,0.0007468259895444362,0.0 +2002,BruCap,28,F,0.0005587632706276774,0.0 +2002,BruCap,29,M,0.001467082339996332,0.0005934718100890207 +2002,BruCap,29,F,0.00018758206715438,0.000299311583358276 +2002,BruCap,30,M,0.0009297136481963556,0.001151410477835349 +2002,BruCap,30,F,0.0,0.0 +2002,BruCap,31,M,0.0009400263207369807,0.001091703056768559 +2002,BruCap,31,F,0.00038767202946307416,0.001246494234964163 +2002,BruCap,32,M,0.0001924557351809084,0.0008650519031141869 +2002,BruCap,32,F,0.0006194507536650836,0.00030413625304136265 +2002,BruCap,33,M,0.0012067578439259859,0.001731102135025967 +2002,BruCap,33,F,0.0002123142250530786,0.0006480881399870382 +2002,BruCap,34,M,0.0008245722531436818,0.0009093664746892998 +2002,BruCap,34,F,0.0004310344827586207,0.00033400133600534416 +2002,BruCap,35,M,0.001844640295142447,0.0003014772384684957 +2002,BruCap,35,F,0.0012728044123886302,0.001022146507666099 +2002,BruCap,36,M,0.001377139484556365,0.0015460729746444028 +2002,BruCap,36,F,0.0016863406408094439,0.0006903693476009665 +2002,BruCap,37,M,0.001209921355111918,0.0009587727708533078 +2002,BruCap,37,F,0.0006310475389145982,0.0006968641114982577 +2002,BruCap,38,M,0.0018386108273748727,0.0017593244194229422 +2002,BruCap,38,F,0.0016956337431114881,0.0007760962359332558 +2002,BruCap,39,M,0.001503759398496241,0.0017605633802816895 +2002,BruCap,39,F,0.0002168256721595837,0.0008084074373484238 +2002,BruCap,40,M,0.001735357917570499,0.0008064516129032258 +2002,BruCap,40,F,0.0012942191544434859,0.0004347826086956522 +2002,BruCap,41,M,0.0023384353741496607,0.001232032854209446 +2002,BruCap,41,F,0.001677852348993289,0.001698513800424629 +2002,BruCap,42,M,0.002798105897546277,0.00044464206313917306 +2002,BruCap,42,F,0.001262360614348833,0.0013869625520110964 +2002,BruCap,43,M,0.003787878787878789,0.00285171102661597 +2002,BruCap,43,F,0.0012853470437018,0.003510531594784353 +2002,BruCap,44,M,0.005184851217312894,0.0020671834625323 +2002,BruCap,44,F,0.002137665669089355,0.001573976915005247 +2002,BruCap,45,M,0.005561993047508691,0.002498750624687657 +2002,BruCap,45,F,0.0025668449197860962,0.0 +2002,BruCap,46,M,0.0036781609195402297,0.004121586810922206 +2002,BruCap,46,F,0.002992092327420389,0.0 +2002,BruCap,47,M,0.005103224309904893,0.002917152858809802 +2002,BruCap,47,F,0.00261437908496732,0.001149425287356322 +2002,BruCap,48,M,0.004378889144964277,0.003603603603603604 +2002,BruCap,48,F,0.0041295370571614864,0.0 +2002,BruCap,49,M,0.005744485294117647,0.0040887850467289715 +2002,BruCap,49,F,0.003881820142333406,0.001769911504424779 +2002,BruCap,50,M,0.0070766227428013685,0.0045662100456621 +2002,BruCap,50,F,0.002956561291789857,0.001360544217687075 +2002,BruCap,51,M,0.0075980392156862735,0.0036697247706422025 +2002,BruCap,51,F,0.0030614476273780893,0.002542911633820725 +2002,BruCap,52,M,0.007155193683691094,0.007417397167902898 +2002,BruCap,52,F,0.00425722608111136,0.00143884892086331 +2002,BruCap,53,M,0.009316008825692572,0.0025657472738935213 +2002,BruCap,53,F,0.004244861483467382,0.002102312543798178 +2002,BruCap,54,M,0.01154507492016704,0.003422313483915127 +2002,BruCap,54,F,0.006466910972192283,0.002212389380530974 +2002,BruCap,55,M,0.009350393700787402,0.006578947368421052 +2002,BruCap,55,F,0.005349977708426215,0.0029739776951672858 +2002,BruCap,56,M,0.0100488084984209,0.002483443708609272 +2002,BruCap,56,F,0.005822784810126582,0.0008718395815170009 +2002,BruCap,57,M,0.01337419894120925,0.006364359586316627 +2002,BruCap,57,F,0.0067747398983789035,0.0025929127052722557 +2002,BruCap,58,M,0.01211771494518177,0.006156552330694811 +2002,BruCap,58,F,0.006624203821656051,0.004672897196261682 +2002,BruCap,59,M,0.014778325123152709,0.00993676603432701 +2002,BruCap,59,F,0.007111111111111111,0.0057361376673040155 +2002,BruCap,60,M,0.01659590891547665,0.007329842931937174 +2002,BruCap,60,F,0.006054490413723511,0.006795016987542469 +2002,BruCap,61,M,0.01709986320109439,0.01076233183856502 +2002,BruCap,61,F,0.012235153685467029,0.008598452278589856 +2002,BruCap,62,M,0.01312247644683715,0.01265822784810127 +2002,BruCap,62,F,0.005823627287853577,0.003076923076923077 +2002,BruCap,63,M,0.018151260504201683,0.011776251226692841 +2002,BruCap,63,F,0.009153318077803205,0.005452562704471101 +2002,BruCap,64,M,0.02339595887982985,0.01388888888888889 +2002,BruCap,64,F,0.012334801762114541,0.0071343638525564815 +2002,BruCap,65,M,0.0193687230989957,0.02159090909090909 +2002,BruCap,65,F,0.014121800529567519,0.006841505131128849 +2002,BruCap,66,M,0.0213156927600147,0.02467532467532468 +2002,BruCap,66,F,0.01085094231867504,0.012987012987012991 +2002,BruCap,67,M,0.0205819730305181,0.02691790040376851 +2002,BruCap,67,F,0.01472711521801906,0.007843137254901959 +2002,BruCap,68,M,0.02780867630700779,0.02127659574468085 +2002,BruCap,68,F,0.01732070365358593,0.01634472511144131 +2002,BruCap,69,M,0.0337861372344131,0.018518518518518517 +2002,BruCap,69,F,0.014713474445018068,0.01179941002949853 +2002,BruCap,70,M,0.0314245810055866,0.02245250431778929 +2002,BruCap,70,F,0.01515930113052415,0.01114649681528662 +2002,BruCap,71,M,0.03463522476050111,0.03181818181818182 +2002,BruCap,71,F,0.01803084223013049,0.01002865329512894 +2002,BruCap,72,M,0.03676752202221372,0.03690036900369004 +2002,BruCap,72,F,0.01883986117997025,0.001988071570576541 +2002,BruCap,73,M,0.04095563139931741,0.03171247357293869 +2002,BruCap,73,F,0.02092788703983863,0.02052238805970149 +2002,BruCap,74,M,0.04577742699289662,0.06205250596658711 +2002,BruCap,74,F,0.02268195413758724,0.030701754385964918 +2002,BruCap,75,M,0.057475884244372985,0.05412371134020619 +2002,BruCap,75,F,0.02732373749695048,0.0477326968973747 +2002,BruCap,76,M,0.05350628293473855,0.07462686567164177 +2002,BruCap,76,F,0.027217496962332933,0.0196078431372549 +2002,BruCap,77,M,0.061607507139942876,0.06130268199233716 +2002,BruCap,77,F,0.03584144315214812,0.029411764705882363 +2002,BruCap,78,M,0.06406810035842292,0.07954545454545454 +2002,BruCap,78,F,0.03590963139120095,0.04057971014492754 +2002,BruCap,79,M,0.0825426944971537,0.04724409448818898 +2002,BruCap,79,F,0.03962818003913893,0.04166666666666667 +2002,BruCap,80,M,0.07591988821611552,0.06451612903225806 +2002,BruCap,80,F,0.05145248645987199,0.046875 +2002,BruCap,81,M,0.09805977975878342,0.04191616766467066 +2002,BruCap,81,F,0.05771643663739021,0.0487012987012987 +2002,BruCap,82,M,0.1019202363367799,0.05 +2002,BruCap,82,F,0.06847308678139875,0.08287292817679558 +2002,BruCap,83,M,0.09923664122137403,0.09782608695652174 +2002,BruCap,83,F,0.07187827911857292,0.05970149253731344 +2002,BruCap,84,M,0.1081830790568655,0.1333333333333333 +2002,BruCap,84,F,0.07900677200902935,0.09420289855072464 +2002,BruCap,85,M,0.1455108359133127,0.08 +2002,BruCap,85,F,0.08918617614269789,0.1047619047619048 +2002,BruCap,86,M,0.1589958158995816,0.08771929824561403 +2002,BruCap,86,F,0.1024752475247525,0.1090909090909091 +2002,BruCap,87,M,0.152258064516129,0.1851851851851852 +2002,BruCap,87,F,0.1171838814265864,0.08403361344537816 +2002,BruCap,88,M,0.1725806451612903,0.2564102564102564 +2002,BruCap,88,F,0.1294307196562836,0.146551724137931 +2002,BruCap,89,M,0.2093023255813954,0.2045454545454546 +2002,BruCap,89,F,0.1506591337099812,0.1333333333333333 +2002,BruCap,90,M,0.1913746630727763,0.16 +2002,BruCap,90,F,0.1616458486407054,0.0945945945945946 +2002,BruCap,91,M,0.2042253521126761,0.24 +2002,BruCap,91,F,0.1819772528433946,0.2027027027027027 +2002,BruCap,92,M,0.1862745098039216,0.25 +2002,BruCap,92,F,0.2116279069767442,0.15 +2002,BruCap,93,M,0.2322580645161291,0.1818181818181818 +2002,BruCap,93,F,0.1978609625668449,0.1842105263157895 +2002,BruCap,94,M,0.3846153846153847,0.1111111111111111 +2002,BruCap,94,F,0.248587570621469,0.25 +2002,BruCap,95,M,0.2666666666666667,0.4 +2002,BruCap,95,F,0.2206235011990408,0.2083333333333334 +2002,BruCap,96,M,0.253968253968254,0.0 +2002,BruCap,96,F,0.2588996763754045,0.125 +2002,BruCap,97,M,0.1515151515151515,0.0 +2002,BruCap,97,F,0.330316742081448,0.25 +2002,BruCap,98,M,0.2222222222222222,0.0 +2002,BruCap,98,F,0.3013698630136986,0.4444444444444444 +2002,BruCap,99,M,0.3076923076923077,0.0 +2002,BruCap,99,F,0.3125,0.09090909090909093 +2002,BruCap,100,M,0.4545454545454545,0.3333333333333333 +2002,BruCap,100,F,0.326923076923077,0.0 +2002,BruCap,101,M,0.0,0.0 +2002,BruCap,101,F,0.5806451612903226,0.0 +2002,BruCap,102,M,0.0,1.0 +2002,BruCap,102,F,0.3333333333333333,0.0 +2002,BruCap,103,M,0.0,0.0 +2002,BruCap,103,F,0.3076923076923077,0.4285714285714286 +2002,BruCap,104,M,0.0,1.0 +2002,BruCap,104,F,0.4285714285714286,0.0 +2002,BruCap,105,M,0.0,0.0 +2002,BruCap,105,F,0.1666666666666667,0.0 +2002,BruCap,106,M,0.0,0.0 +2002,BruCap,106,F,0.0,0.0 +2002,BruCap,107,M,0.0,0.0 +2002,BruCap,107,F,0.0,0.0 +2002,BruCap,108,M,0.0,0.0 +2002,BruCap,108,F,0.0,0.0 +2002,BruCap,109,M,0.0,0.0 +2002,BruCap,109,F,0.0,0.0 +2002,BruCap,110,M,0.0,0.0 +2002,BruCap,110,F,0.0,0.0 +2002,BruCap,111,M,0.0,0.0 +2002,BruCap,111,F,0.0,0.0 +2002,BruCap,112,M,0.0,0.0 +2002,BruCap,112,F,0.0,0.0 +2002,BruCap,113,M,0.0,0.0 +2002,BruCap,113,F,0.0,0.0 +2002,BruCap,114,M,0.0,0.0 +2002,BruCap,114,F,0.0,0.0 +2002,BruCap,115,M,0.0,0.0 +2002,BruCap,115,F,0.0,0.0 +2002,BruCap,116,M,0.0,0.0 +2002,BruCap,116,F,0.0,0.0 +2002,BruCap,117,M,0.0,0.0 +2002,BruCap,117,F,0.0,0.0 +2002,BruCap,118,M,0.0,0.0 +2002,BruCap,118,F,0.0,0.0 +2002,BruCap,119,M,0.0,0.0 +2002,BruCap,119,F,0.0,0.0 +2002,BruCap,120,M,0.0,0.0 +2002,BruCap,120,F,0.0,0.0 +2002,Fla,0,M,0.001428814424221807,0.0014450867052023119 +2002,Fla,0,F,0.0007121239095602634,0.00154320987654321 +2002,Fla,1,M,0.0004959661420447032,0.0006697923643670463 +2002,Fla,1,F,0.0003790750568612585,0.0 +2002,Fla,2,M,0.00023069571235540326,0.0 +2002,Fla,2,F,0.0002041788606819574,0.001490312965722802 +2002,Fla,3,M,0.00022382094324540367,0.0014336917562724019 +2002,Fla,3,F,0.0001680559290131756,0.0 +2002,Fla,4,M,0.00012510164508663292,0.0 +2002,Fla,4,F,0.0001950268161872258,0.0 +2002,Fla,5,M,0.0001551686683424883,0.0 +2002,Fla,5,F,9.711566475672526e-05,0.0 +2002,Fla,6,M,0.00021653725987564568,0.0 +2002,Fla,6,F,0.0001939487975174554,0.0 +2002,Fla,7,M,0.00021383839926683985,0.0 +2002,Fla,7,F,0.0001606683804627249,0.0007501875468867218 +2002,Fla,8,M,8.81057268722467e-05,0.0 +2002,Fla,8,F,0.00015089328826653793,0.0 +2002,Fla,9,M,5.651154248255207e-05,0.0 +2002,Fla,9,F,0.00014734918810597358,0.0 +2002,Fla,10,M,0.0001113554745135158,0.0 +2002,Fla,10,F,0.0,0.0 +2002,Fla,11,M,0.000112726862811408,0.0 +2002,Fla,11,F,8.857657444861082e-05,0.0 +2002,Fla,12,M,0.00017422614553690692,0.0007782101167315176 +2002,Fla,12,F,0.0001219958521410272,0.001589825119236884 +2002,Fla,13,M,0.0002055317399729873,0.0 +2002,Fla,13,F,0.0002152720115631824,0.0 +2002,Fla,14,M,0.0002076843198338526,0.0 +2002,Fla,14,F,9.408222786715589e-05,0.0007830853563038371 +2002,Fla,15,M,0.0003252994233328405,0.0 +2002,Fla,15,F,0.00028264556246466934,0.0 +2002,Fla,16,M,0.0006406931689904508,0.0007886435331230284 +2002,Fla,16,F,6.38895987733197e-05,0.0 +2002,Fla,17,M,0.0005668595978280327,0.0 +2002,Fla,17,F,0.00028196372066794083,0.0 +2002,Fla,18,M,0.001217285453438832,0.0 +2002,Fla,18,F,0.000482843950870628,0.0007017543859649122 +2002,Fla,19,M,0.0006498643761301987,0.0 +2002,Fla,19,F,0.00038777032065622673,0.0 +2002,Fla,20,M,0.0009310222076179523,0.0 +2002,Fla,20,F,0.0004358944554225272,0.0 +2002,Fla,21,M,0.0012198502911006381,0.001191895113230036 +2002,Fla,21,F,0.00034566194262011747,0.001009081735620585 +2002,Fla,22,M,0.001153402537485583,0.0005543237250554324 +2002,Fla,22,F,0.00028967035513585536,0.0 +2002,Fla,23,M,0.001099334761528921,0.0 +2002,Fla,23,F,0.0003799392097264438,0.0008424599831508003 +2002,Fla,24,M,0.0009532062391681107,0.0004688232536333802 +2002,Fla,24,F,0.0004161217453334919,0.0003969829297340213 +2002,Fla,25,M,0.0007687531415392804,0.002266545784224842 +2002,Fla,25,F,0.00046266308873878036,0.000392156862745098 +2002,Fla,26,M,0.000851063829787234,0.0008572653236176596 +2002,Fla,26,F,0.0001588814744200826,0.000384172109104879 +2002,Fla,27,M,0.0009675433195531707,0.00037750094375235937 +2002,Fla,27,F,0.00048462819930334696,0.0 +2002,Fla,28,M,0.0012412547957571661,0.0007361059992638941 +2002,Fla,28,F,0.00026338122969769693,0.0007301935012778386 +2002,Fla,29,M,0.0009467903806097332,0.0006978367062107465 +2002,Fla,29,F,0.0004433361041839845,0.0 +2002,Fla,30,M,0.0011864843951508901,0.0003384094754653132 +2002,Fla,30,F,0.00047268907563025216,0.0 +2002,Fla,31,M,0.0009753657621608103,0.0006489292667099286 +2002,Fla,31,F,0.000412148064192061,0.0003206155819172812 +2002,Fla,32,M,0.001047904191616766,0.0006455777921239509 +2002,Fla,32,F,0.0003334017234304473,0.0003371544167228591 +2002,Fla,33,M,0.0008872677083846799,0.0019144862795149968 +2002,Fla,33,F,0.0005072279989855441,0.0003362474781439138 +2002,Fla,34,M,0.0009022270763094164,0.0006891798759476222 +2002,Fla,34,F,0.0007695936049253991,0.0003505082369435681 +2002,Fla,35,M,0.001266901619330615,0.00122737035900583 +2002,Fla,35,F,0.000757468162666288,0.0 +2002,Fla,36,M,0.001088526046873264,0.0012915724895059741 +2002,Fla,36,F,0.0007119235715598017,0.0003495281370150297 +2002,Fla,37,M,0.001214652545442922,0.002509410288582183 +2002,Fla,37,F,0.0005896999082689032,0.0003554923569143264 +2002,Fla,38,M,0.0011790177710133119,0.0013391362571141619 +2002,Fla,38,F,0.0008372441447991716,0.0 +2002,Fla,39,M,0.001691020248883493,0.0013577732518669384 +2002,Fla,39,F,0.0009152807232950106,0.001620745542949757 +2002,Fla,40,M,0.001309557587794923,0.001072194424588992 +2002,Fla,40,F,0.0009078428767547935,0.0004378283712784589 +2002,Fla,41,M,0.001914557314276809,0.0010826416456153009 +2002,Fla,41,F,0.0009547407424245867,0.000864304235090752 +2002,Fla,42,M,0.001707082202573755,0.0015220700152207 +2002,Fla,42,F,0.001139003037341433,0.0009013068949977466 +2002,Fla,43,M,0.0020958751393534013,0.001514004542013626 +2002,Fla,43,F,0.001262075770439891,0.001987083954297069 +2002,Fla,44,M,0.002420102684730735,0.0007974481658692185 +2002,Fla,44,F,0.0011414727327789039,0.001597444089456869 +2002,Fla,45,M,0.002678093197643278,0.0008193363375665711 +2002,Fla,45,F,0.0013686023738172213,0.002098635886673662 +2002,Fla,46,M,0.003026004728132388,0.002509410288582183 +2002,Fla,46,F,0.0019086245973994988,0.0005530973451327434 +2002,Fla,47,M,0.003370407819346141,0.001731601731601732 +2002,Fla,47,F,0.0022338414708986927,0.001172332942555686 +2002,Fla,48,M,0.0036706740244383134,0.00420757363253857 +2002,Fla,48,F,0.0019033600649680238,0.001217285453438832 +2002,Fla,49,M,0.004148250574088249,0.0018441678192715534 +2002,Fla,49,F,0.002680691363067732,0.0018703241895261847 +2002,Fla,50,M,0.004352331606217617,0.0037470725995316155 +2002,Fla,50,F,0.002600021224663059,0.003949967083607637 +2002,Fla,51,M,0.004866244048715049,0.0019029495718363469 +2002,Fla,51,F,0.0033269455977855853,0.003160556257901391 +2002,Fla,52,M,0.004716733923798543,0.001363636363636364 +2002,Fla,52,F,0.0034867503486750357,0.0018726591760299628 +2002,Fla,53,M,0.005312154841424288,0.004269449715370019 +2002,Fla,53,F,0.003341377390012994,0.0006635700066357001 +2002,Fla,54,M,0.006340699864696363,0.005679129200189304 +2002,Fla,54,F,0.0035978949629470523,0.003287310979618672 +2002,Fla,55,M,0.007046449573845238,0.006175771971496436 +2002,Fla,55,F,0.0038304054946506406,0.0035868005738880922 +2002,Fla,56,M,0.008349690914950341,0.008036739380022962 +2002,Fla,56,F,0.003991898793624703,0.0030911901081916537 +2002,Fla,57,M,0.009023401674506671,0.004681100058513751 +2002,Fla,57,F,0.00443760724217502,0.00362844702467344 +2002,Fla,58,M,0.00887647423960273,0.007155635062611806 +2002,Fla,58,F,0.0047162541228692074,0.0040650406504065045 +2002,Fla,59,M,0.009742345300121334,0.008403361344537815 +2002,Fla,59,F,0.005309546564723372,0.004230118443316414 +2002,Fla,60,M,0.01093157789746659,0.006012024048096192 +2002,Fla,60,F,0.0055097480157201215,0.005514705882352942 +2002,Fla,61,M,0.0118905202102592,0.01026957637997433 +2002,Fla,61,F,0.005494505494505495,0.003965107057890564 +2002,Fla,62,M,0.0120489948076155,0.01648351648351649 +2002,Fla,62,F,0.0066429640718562895,0.005917159763313609 +2002,Fla,63,M,0.01321358188220851,0.01417434443656981 +2002,Fla,63,F,0.006995570490300901,0.0048030739673390966 +2002,Fla,64,M,0.014435343091177659,0.013720742534301859 +2002,Fla,64,F,0.007355738744451491,0.006256517205422315 +2002,Fla,65,M,0.0174922003715778,0.01234567901234568 +2002,Fla,65,F,0.00847567287784679,0.0076335877862595426 +2002,Fla,66,M,0.017692826944256942,0.02142245072836332 +2002,Fla,66,F,0.008710065325489942,0.012077294685990341 +2002,Fla,67,M,0.0208637968543814,0.02425373134328359 +2002,Fla,67,F,0.00966846421391876,0.01169590643274854 +2002,Fla,68,M,0.0233514996210344,0.0297121634168988 +2002,Fla,68,F,0.01055782663276145,0.01794258373205742 +2002,Fla,69,M,0.02531508822470292,0.026946107784431145 +2002,Fla,69,F,0.012011918803153521,0.02010723860589812 +2002,Fla,70,M,0.027748210680858868,0.03917301414581066 +2002,Fla,70,F,0.01374474053295933,0.008077544426494346 +2002,Fla,71,M,0.028199566160520613,0.03472222222222223 +2002,Fla,71,F,0.015087774790447568,0.006868131868131868 +2002,Fla,72,M,0.036934091387660566,0.03026315789473685 +2002,Fla,72,F,0.01675253335153025,0.015 +2002,Fla,73,M,0.0369675025702919,0.03225806451612903 +2002,Fla,73,F,0.01807845768157904,0.02507836990595611 +2002,Fla,74,M,0.044407504155782485,0.06099518459069021 +2002,Fla,74,F,0.02185812560100599,0.01769911504424779 +2002,Fla,75,M,0.04731734298788153,0.0530035335689046 +2002,Fla,75,F,0.0251597886725533,0.0291970802919708 +2002,Fla,76,M,0.05197494434953668,0.04528985507246377 +2002,Fla,76,F,0.02933221591558417,0.04372623574144487 +2002,Fla,77,M,0.060743224364347585,0.06896551724137931 +2002,Fla,77,F,0.03434175003970145,0.02547770700636943 +2002,Fla,78,M,0.06524882515965777,0.07306889352818371 +2002,Fla,78,F,0.03524175106174453,0.02832244008714597 +2002,Fla,79,M,0.07200756552283166,0.06666666666666668 +2002,Fla,79,F,0.04290019500088637,0.02538071065989848 +2002,Fla,80,M,0.07861127422196125,0.0997229916897507 +2002,Fla,80,F,0.04830984618218661,0.048 +2002,Fla,81,M,0.09622718052738337,0.08387096774193549 +2002,Fla,81,F,0.05889025893958076,0.05705705705705705 +2002,Fla,82,M,0.09855313092979127,0.1280788177339902 +2002,Fla,82,F,0.06972477064220184,0.06572769953051644 +2002,Fla,83,M,0.1121182266009852,0.09523809523809523 +2002,Fla,83,F,0.07897181790027873,0.08426966292134831 +2002,Fla,84,M,0.1278350515463918,0.1484375 +2002,Fla,84,F,0.08565647482014388,0.125 +2002,Fla,85,M,0.1297127468581688,0.1637931034482759 +2002,Fla,85,F,0.09650636187189994,0.1164383561643836 +2002,Fla,86,M,0.1495145631067961,0.1359223300970874 +2002,Fla,86,F,0.1118846345101939,0.125 +2002,Fla,87,M,0.1694993109784107,0.1764705882352941 +2002,Fla,87,F,0.1230872226472839,0.1232876712328767 +2002,Fla,88,M,0.1864924958310172,0.1940298507462687 +2002,Fla,88,F,0.1380318285157519,0.1935483870967742 +2002,Fla,89,M,0.2023767913317022,0.2380952380952381 +2002,Fla,89,F,0.1456411588930752,0.2038834951456311 +2002,Fla,90,M,0.2241219963031423,0.2765957446808511 +2002,Fla,90,F,0.1775506945553249,0.09210526315789473 +2002,Fla,91,M,0.2286914765906363,0.1923076923076923 +2002,Fla,91,F,0.1875741986545311,0.2222222222222222 +2002,Fla,92,M,0.2771186440677967,0.1363636363636364 +2002,Fla,92,F,0.2202365970299522,0.2931034482758621 +2002,Fla,93,M,0.3043995243757432,0.2272727272727273 +2002,Fla,93,F,0.2327481840193705,0.1714285714285714 +2002,Fla,94,M,0.3181076672104405,0.1818181818181818 +2002,Fla,94,F,0.2448809026326787,0.2307692307692308 +2002,Fla,95,M,0.3315789473684211,0.25 +2002,Fla,95,F,0.2699822380106572,0.2352941176470588 +2002,Fla,96,M,0.3288590604026846,0.375 +2002,Fla,96,F,0.2866556836902801,0.2857142857142857 +2002,Fla,97,M,0.3611111111111111,0.0 +2002,Fla,97,F,0.2872727272727273,0.2727272727272727 +2002,Fla,98,M,0.4181818181818182,0.0 +2002,Fla,98,F,0.362962962962963,0.3333333333333333 +2002,Fla,99,M,0.3965517241379311,0.0 +2002,Fla,99,F,0.3413978494623656,0.0 +2002,Fla,100,M,0.3333333333333333,0.5 +2002,Fla,100,F,0.3716814159292036,0.0 +2002,Fla,101,M,0.5238095238095238,0.0 +2002,Fla,101,F,0.435483870967742,0.5 +2002,Fla,102,M,0.5454545454545454,0.0 +2002,Fla,102,F,0.3529411764705883,0.0 +2002,Fla,103,M,0.4,0.0 +2002,Fla,103,F,0.3870967741935484,0.0 +2002,Fla,104,M,1.0,0.0 +2002,Fla,104,F,0.4705882352941176,0.3333333333333333 +2002,Fla,105,M,0.0,0.0 +2002,Fla,105,F,0.5,0.0 +2002,Fla,106,M,1.0,0.0 +2002,Fla,106,F,0.2222222222222222,0.0 +2002,Fla,107,M,0.0,0.0 +2002,Fla,107,F,0.0,0.0 +2002,Fla,108,M,0.0,0.0 +2002,Fla,108,F,0.0,0.0 +2002,Fla,109,M,0.0,0.0 +2002,Fla,109,F,0.0,0.0 +2002,Fla,110,M,0.0,0.0 +2002,Fla,110,F,0.0,0.0 +2002,Fla,111,M,0.0,0.0 +2002,Fla,111,F,1.0,0.0 +2002,Fla,112,M,0.0,0.0 +2002,Fla,112,F,0.0,0.0 +2002,Fla,113,M,0.0,0.0 +2002,Fla,113,F,0.0,0.0 +2002,Fla,114,M,0.0,0.0 +2002,Fla,114,F,0.0,0.0 +2002,Fla,115,M,0.0,0.0 +2002,Fla,115,F,0.0,0.0 +2002,Fla,116,M,0.0,0.0 +2002,Fla,116,F,0.0,0.0 +2002,Fla,117,M,0.0,0.0 +2002,Fla,117,F,0.0,0.0 +2002,Fla,118,M,0.0,0.0 +2002,Fla,118,F,0.0,0.0 +2002,Fla,119,M,0.0,0.0 +2002,Fla,119,F,0.0,0.0 +2002,Fla,120,M,0.0,0.0 +2002,Fla,120,F,0.0,0.0 +2002,Wal,0,M,0.001049097775912715,0.0 +2002,Wal,0,F,0.001035817478057024,0.0043604651162790714 +2002,Wal,1,M,0.0004083299305839118,0.0 +2002,Wal,1,F,0.0002666097899114856,0.0 +2002,Wal,2,M,0.00020860495436766615,0.001270648030495553 +2002,Wal,2,F,0.0001638986013986014,0.0 +2002,Wal,3,M,0.00015579559617781468,0.0 +2002,Wal,3,F,5.417998591320366e-05,0.0 +2002,Wal,4,M,0.0002585716502042716,0.0 +2002,Wal,4,F,0.0001609960287646238,0.0 +2002,Wal,5,M,0.0001525320317266626,0.0 +2002,Wal,5,F,0.00010631511800978101,0.0 +2002,Wal,6,M,0.0001565762004175365,0.0 +2002,Wal,6,F,5.4124269322364146e-05,0.0 +2002,Wal,7,M,0.0001030927835051546,0.0 +2002,Wal,7,F,0.0,0.0 +2002,Wal,8,M,0.0003961965134706815,0.0009661835748792268 +2002,Wal,8,F,0.0001047504320955324,0.0 +2002,Wal,9,M,0.0001414227124876255,0.0 +2002,Wal,9,F,9.866311479453404e-05,0.0 +2002,Wal,10,M,0.0001378423083991913,0.0008771929824561404 +2002,Wal,10,F,0.0,0.0 +2002,Wal,11,M,0.0001400102674196108,0.0 +2002,Wal,11,F,0.00019418418369823785,0.0008920606601248885 +2002,Wal,12,M,0.0001392628353913286,0.0 +2002,Wal,12,F,0.0003410308876546819,0.0 +2002,Wal,13,M,9.350163627863488e-05,0.0 +2002,Wal,13,F,0.0,0.0 +2002,Wal,14,M,0.0001938829916145606,0.0 +2002,Wal,14,F,0.0001526018617427133,0.0 +2002,Wal,15,M,0.0004374240583232078,0.0 +2002,Wal,15,F,0.0001538461538461539,0.0008547008547008548 +2002,Wal,16,M,0.0008096756237032539,0.0 +2002,Wal,16,F,0.0002114500185018766,0.0 +2002,Wal,17,M,0.0007187965292396161,0.0 +2002,Wal,17,F,0.00016020506247997442,0.0 +2002,Wal,18,M,0.0010320982557539481,0.002240477968633309 +2002,Wal,18,F,0.000664451827242525,0.0007293946024799418 +2002,Wal,19,M,0.0012785761775686599,0.0007513148009015777 +2002,Wal,19,F,0.0003724592955198468,0.0 +2002,Wal,20,M,0.001221311892524554,0.002693602693602694 +2002,Wal,20,F,0.000261164794985636,0.0 +2002,Wal,21,M,0.0009168704156479216,0.0006246096189881324 +2002,Wal,21,F,0.0003674540682414698,0.0 +2002,Wal,22,M,0.001199353392084268,0.001164144353899884 +2002,Wal,22,F,0.0001659108505696273,0.0005194805194805195 +2002,Wal,23,M,0.0011824778285407153,0.0005518763796909492 +2002,Wal,23,F,0.000336624775583483,0.0 +2002,Wal,24,M,0.001562836818279802,0.0005390835579514825 +2002,Wal,24,F,0.0004525398800769319,0.0 +2002,Wal,25,M,0.001340410701839044,0.001002004008016032 +2002,Wal,25,F,0.0006706158488878954,0.0004962779156327543 +2002,Wal,26,M,0.0018434179136846672,0.0 +2002,Wal,26,F,0.0005576000892160141,0.0 +2002,Wal,27,M,0.001521750537860104,0.0 +2002,Wal,27,F,0.0005978910751168608,0.0 +2002,Wal,28,M,0.001768480622505179,0.0018982536066818527 +2002,Wal,28,F,0.0006204756980351603,0.0 +2002,Wal,29,M,0.00121992875616064,0.0007259528130671506 +2002,Wal,29,F,0.00044845283770990086,0.0 +2002,Wal,30,M,0.001294467350656822,0.0007064641469445424 +2002,Wal,30,F,0.0006775395634709384,0.00037565740045078885 +2002,Wal,31,M,0.001366253537620767,0.0006958942240779402 +2002,Wal,31,F,0.00029753049687592984,0.001111522786217117 +2002,Wal,32,M,0.0009775648858692996,0.001009761023224504 +2002,Wal,32,F,0.0006879944960440316,0.0003539823008849558 +2002,Wal,33,M,0.001491053677932406,0.00033602150537634417 +2002,Wal,33,F,0.0008884501480750248,0.0006870491240123669 +2002,Wal,34,M,0.002034489440031002,0.0006540222367560497 +2002,Wal,34,F,0.001164370269745779,0.001413927182750089 +2002,Wal,35,M,0.0018532598365329789,0.001153070049005477 +2002,Wal,35,F,0.0005200945626477542,0.0 +2002,Wal,36,M,0.001689034967588789,0.001124227093872962 +2002,Wal,36,F,0.000727669637984355,0.0 +2002,Wal,37,M,0.00241270398315494,0.003218256290228204 +2002,Wal,37,F,0.0007869540506273773,0.00032754667540124465 +2002,Wal,38,M,0.001923679148212768,0.0029095141111434393 +2002,Wal,38,F,0.0012296341838303108,0.001019714479945615 +2002,Wal,39,M,0.0030214246475004573,0.002082093991671624 +2002,Wal,39,F,0.001118468146027201,0.001090116279069767 +2002,Wal,40,M,0.0025857072801034288,0.002131546894031669 +2002,Wal,40,F,0.0018694026606382054,0.001402032947774273 +2002,Wal,41,M,0.003404407812220032,0.001946607341490545 +2002,Wal,41,F,0.0014201393511738339,0.0007363770250368187 +2002,Wal,42,M,0.003440571939231457,0.002357795461243737 +2002,Wal,42,F,0.0018010291595197262,0.00149588631264024 +2002,Wal,43,M,0.003139360298466718,0.002040816326530613 +2002,Wal,43,F,0.0019177126917712688,0.0003777861730260674 +2002,Wal,44,M,0.0041817931161251785,0.004752004752004753 +2002,Wal,44,F,0.0017427052147102199,0.001185770750988143 +2002,Wal,45,M,0.005630102280191424,0.003763752171395484 +2002,Wal,45,F,0.002163234034882149,0.002701659590891548 +2002,Wal,46,M,0.005648108595566947,0.0036674816625916866 +2002,Wal,46,F,0.002889260078551758,0.002424242424242424 +2002,Wal,47,M,0.0044935226349251895,0.003700277520814061 +2002,Wal,47,F,0.0022759342710182533,0.001252609603340292 +2002,Wal,48,M,0.006324262169413568,0.005184705119896306 +2002,Wal,48,F,0.003182363250622637,0.0009045680687471732 +2002,Wal,49,M,0.007064402187061498,0.004709048099562731 +2002,Wal,49,F,0.003231244731666199,0.001340482573726542 +2002,Wal,50,M,0.00593203297808164,0.007950224680262703 +2002,Wal,50,F,0.003471066520850174,0.004524886877828055 +2002,Wal,51,M,0.007671153567810103,0.0037389530931339226 +2002,Wal,51,F,0.00330922327802203,0.00177619893428064 +2002,Wal,52,M,0.0077752940033045,0.006064930431680342 +2002,Wal,52,F,0.004503650327107234,0.002430724355858046 +2002,Wal,53,M,0.00928350392763628,0.004609929078014184 +2002,Wal,53,F,0.004264881225350821,0.0018239854081167355 +2002,Wal,54,M,0.009135259230916395,0.0067352002835873795 +2002,Wal,54,F,0.006242774566473989,0.001964636542239686 +2002,Wal,55,M,0.010782728030191641,0.006904487917146146 +2002,Wal,55,F,0.005598059339428998,0.00472193074501574 +2002,Wal,56,M,0.00991014799154334,0.006274131274131275 +2002,Wal,56,F,0.005486801194903372,0.003103662321539417 +2002,Wal,57,M,0.01123371443764956,0.01053639846743295 +2002,Wal,57,F,0.00548423283061199,0.0024464831804281357 +2002,Wal,58,M,0.01328761251607373,0.008108108108108109 +2002,Wal,58,F,0.005340541966110635,0.002697235333782873 +2002,Wal,59,M,0.0126143952510512,0.01378518093049972 +2002,Wal,59,F,0.0062617880045265925,0.006920415224913495 +2002,Wal,60,M,0.0154118689105403,0.01011904761904762 +2002,Wal,60,F,0.00718562874251497,0.00718390804597701 +2002,Wal,61,M,0.01596505162827641,0.009865005192107996 +2002,Wal,61,F,0.0074455899198167235,0.004257907542579075 +2002,Wal,62,M,0.01794513495624035,0.01337047353760446 +2002,Wal,62,F,0.008513127112035352,0.004283965728274174 +2002,Wal,63,M,0.01963090949194912,0.01383042693926639 +2002,Wal,63,F,0.008841053238516241,0.007272727272727274 +2002,Wal,64,M,0.0200877395520665,0.0139778683750728 +2002,Wal,64,F,0.009204737732656516,0.009395973154362415 +2002,Wal,65,M,0.02368189455156413,0.02215384615384615 +2002,Wal,65,F,0.01018122581958868,0.01062416998671979 +2002,Wal,66,M,0.02352360585622636,0.02063789868667917 +2002,Wal,66,F,0.01048735348550278,0.0057544757033248075 +2002,Wal,67,M,0.02579207132622194,0.01901639344262295 +2002,Wal,67,F,0.0130779392338177,0.006397952655150353 +2002,Wal,68,M,0.02821841371064169,0.03129251700680273 +2002,Wal,68,F,0.01426495839387135,0.01150159744408946 +2002,Wal,69,M,0.03214863927222266,0.04139290407358739 +2002,Wal,69,F,0.0143397608005858,0.0175557056043214 +2002,Wal,70,M,0.03476859313838361,0.037956204379562035 +2002,Wal,70,F,0.017781490542395133,0.01547779273216689 +2002,Wal,71,M,0.03686525389844062,0.02541208791208791 +2002,Wal,71,F,0.016610898661567883,0.02327084680025857 +2002,Wal,72,M,0.04362821176064839,0.030769230769230767 +2002,Wal,72,F,0.02076454152908306,0.015818431911966992 +2002,Wal,73,M,0.04455490284681428,0.05304829770387965 +2002,Wal,73,F,0.0249033648057791,0.02560351133869788 +2002,Wal,74,M,0.05155420773313117,0.04612978889757624 +2002,Wal,74,F,0.02597657527972257,0.02567760342368046 +2002,Wal,75,M,0.06189536031589338,0.05090311986863711 +2002,Wal,75,F,0.029173849622066036,0.0341394025604552 +2002,Wal,76,M,0.06504904491481672,0.06753006475485661 +2002,Wal,76,F,0.034213098729227766,0.03172205438066465 +2002,Wal,77,M,0.067747667703243,0.07677165354330709 +2002,Wal,77,F,0.03727935664145028,0.04365400161681488 +2002,Wal,78,M,0.07762501520866286,0.07700534759358289 +2002,Wal,78,F,0.04082070346010866,0.03418054338299737 +2002,Wal,79,M,0.08477944098556102,0.09681528662420384 +2002,Wal,79,F,0.04732677660282482,0.04734848484848485 +2002,Wal,80,M,0.09334473421690184,0.1046875 +2002,Wal,80,F,0.05649887302779865,0.06796116504854369 +2002,Wal,81,M,0.09821572094518566,0.1205936920222635 +2002,Wal,81,F,0.06181439666906877,0.060433295324971485 +2002,Wal,82,M,0.1170134638922889,0.1257861635220126 +2002,Wal,82,F,0.0691104366098529,0.07650273224043716 +2002,Wal,83,M,0.1110220440881764,0.155 +2002,Wal,83,F,0.08157152924594785,0.1003039513677812 +2002,Wal,84,M,0.142122487143525,0.1569767441860465 +2002,Wal,84,F,0.08723110321689362,0.0759493670886076 +2002,Wal,85,M,0.1421200750469043,0.169811320754717 +2002,Wal,85,F,0.1068596352101507,0.1189024390243903 +2002,Wal,86,M,0.1605301914580265,0.2064516129032258 +2002,Wal,86,F,0.118063112078346,0.1129032258064516 +2002,Wal,87,M,0.1766990291262136,0.1958041958041958 +2002,Wal,87,F,0.138153428377461,0.1287671232876712 +2002,Wal,88,M,0.19580838323353306,0.2121212121212121 +2002,Wal,88,F,0.1499899739322238,0.1437908496732026 +2002,Wal,89,M,0.2125100240577386,0.2946428571428572 +2002,Wal,89,F,0.1670555296313579,0.1561181434599156 +2002,Wal,90,M,0.2508178844056707,0.1896551724137931 +2002,Wal,90,F,0.1918052256532067,0.1494845360824742 +2002,Wal,91,M,0.2724795640326976,0.2857142857142857 +2002,Wal,91,F,0.2034322488380408,0.1704545454545455 +2002,Wal,92,M,0.2596348884381339,0.25 +2002,Wal,92,F,0.2148080438756856,0.2720588235294118 +2002,Wal,93,M,0.2756598240469208,0.2857142857142857 +2002,Wal,93,F,0.2528538812785388,0.1926605504587156 +2002,Wal,94,M,0.3692946058091287,0.4 +2002,Wal,94,F,0.2527472527472528,0.328125 +2002,Wal,95,M,0.3480662983425415,0.1111111111111111 +2002,Wal,95,F,0.2909090909090909,0.3114754098360656 +2002,Wal,96,M,0.3119266055045872,0.375 +2002,Wal,96,F,0.2833583208395803,0.368421052631579 +2002,Wal,97,M,0.2857142857142857,0.75 +2002,Wal,97,F,0.3487858719646799,0.325 +2002,Wal,98,M,0.5510204081632653,0.3333333333333333 +2002,Wal,98,F,0.29,0.2142857142857143 +2002,Wal,99,M,0.44,0.6666666666666666 +2002,Wal,99,F,0.3508771929824561,0.3 +2002,Wal,100,M,0.375,0.0 +2002,Wal,100,F,0.4444444444444444,0.25 +2002,Wal,101,M,0.5,0.5 +2002,Wal,101,F,0.4029850746268657,0.4444444444444444 +2002,Wal,102,M,0.5714285714285714,1.0 +2002,Wal,102,F,0.34375,0.5 +2002,Wal,103,M,0.0,0.0 +2002,Wal,103,F,0.5263157894736842,0.0 +2002,Wal,104,M,0.5,0.0 +2002,Wal,104,F,0.5384615384615384,0.0 +2002,Wal,105,M,0.0,0.0 +2002,Wal,105,F,0.75,0.0 +2002,Wal,106,M,0.0,0.0 +2002,Wal,106,F,0.0,0.0 +2002,Wal,107,M,0.0,0.0 +2002,Wal,107,F,0.0,0.0 +2002,Wal,108,M,0.0,0.0 +2002,Wal,108,F,1.0,0.0 +2002,Wal,109,M,0.0,0.0 +2002,Wal,109,F,1.0,0.0 +2002,Wal,110,M,0.0,0.0 +2002,Wal,110,F,0.0,0.0 +2002,Wal,111,M,0.0,0.0 +2002,Wal,111,F,0.0,0.0 +2002,Wal,112,M,0.0,0.0 +2002,Wal,112,F,0.0,0.0 +2002,Wal,113,M,0.0,0.0 +2002,Wal,113,F,0.0,0.0 +2002,Wal,114,M,0.0,0.0 +2002,Wal,114,F,0.0,0.0 +2002,Wal,115,M,0.0,0.0 +2002,Wal,115,F,0.0,0.0 +2002,Wal,116,M,0.0,0.0 +2002,Wal,116,F,0.0,0.0 +2002,Wal,117,M,0.0,0.0 +2002,Wal,117,F,0.0,0.0 +2002,Wal,118,M,0.0,0.0 +2002,Wal,118,F,0.0,0.0 +2002,Wal,119,M,0.0,0.0 +2002,Wal,119,F,0.0,0.0 +2002,Wal,120,M,0.0,0.0 +2002,Wal,120,F,0.0,0.0 +2003,BruCap,0,M,0.001223990208078335,0.0 +2003,BruCap,0,F,0.0003638348189921776,0.0 +2003,BruCap,1,M,0.0003483106931382794,0.0 +2003,BruCap,1,F,0.00035758984444841767,0.0 +2003,BruCap,2,M,0.0003634381246592768,0.0 +2003,BruCap,2,F,0.0003896356906292616,0.0 +2003,BruCap,3,M,0.0,0.0 +2003,BruCap,3,F,0.00020128824476650558,0.0008058017727639 +2003,BruCap,4,M,0.0,0.0 +2003,BruCap,4,F,0.0,0.0 +2003,BruCap,5,M,0.0001985308715505261,0.0 +2003,BruCap,5,F,0.0004276245456489203,0.0 +2003,BruCap,6,M,0.0,0.0 +2003,BruCap,6,F,0.0,0.0 +2003,BruCap,7,M,0.0004324324324324325,0.0 +2003,BruCap,7,F,0.00022396416573348263,0.0 +2003,BruCap,8,M,0.0,0.0 +2003,BruCap,8,F,0.0,0.0009066183136899368 +2003,BruCap,9,M,0.000214041095890411,0.0008223684210526315 +2003,BruCap,9,F,0.0,0.0 +2003,BruCap,10,M,0.0006492101276779918,0.0 +2003,BruCap,10,F,0.0002233139794551139,0.0 +2003,BruCap,11,M,0.0,0.0 +2003,BruCap,11,F,0.0004485310607759588,0.0 +2003,BruCap,12,M,0.0002168256721595837,0.0 +2003,BruCap,12,F,0.00022810218978102192,0.0 +2003,BruCap,13,M,0.0,0.0 +2003,BruCap,13,F,0.0002311070025421771,0.0 +2003,BruCap,14,M,0.0002228163992869875,0.0 +2003,BruCap,14,F,0.0,0.0 +2003,BruCap,15,M,0.00023212627669452182,0.0 +2003,BruCap,15,F,0.0,0.0 +2003,BruCap,16,M,0.00023512814483893726,0.0 +2003,BruCap,16,F,0.0007338551859099804,0.0 +2003,BruCap,17,M,0.0009512485136741976,0.0 +2003,BruCap,17,F,0.0,0.0 +2003,BruCap,18,M,0.000947867298578199,0.0 +2003,BruCap,18,F,0.0,0.0 +2003,BruCap,19,M,0.0,0.000794912559618442 +2003,BruCap,19,F,0.00024050024050024048,0.0 +2003,BruCap,20,M,0.0009354536950420953,0.0006414368184733802 +2003,BruCap,20,F,0.0002356823002592506,0.0 +2003,BruCap,21,M,0.0008760402978537013,0.0 +2003,BruCap,21,F,0.0004373496610540127,0.0 +2003,BruCap,22,M,0.001302083333333333,0.000555247084952804 +2003,BruCap,22,F,0.0006190672719768881,0.0 +2003,BruCap,23,M,0.0002134016218523261,0.0 +2003,BruCap,23,F,0.000406421459053038,0.0 +2003,BruCap,24,M,0.001025220422390814,0.001321585903083701 +2003,BruCap,24,F,0.000942507068803016,0.0003629764065335753 +2003,BruCap,25,M,0.000778816199376947,0.0 +2003,BruCap,25,F,0.0003662332906061161,0.0003449465332873405 +2003,BruCap,26,M,0.0009821253191907287,0.0 +2003,BruCap,26,F,0.0,0.0003254149040026033 +2003,BruCap,27,M,0.0011346444780635401,0.0006828269033799933 +2003,BruCap,27,F,0.00037914691943127966,0.00032247662044501766 +2003,BruCap,28,M,0.001323501607109094,0.0008990110878034162 +2003,BruCap,28,F,0.0,0.0006144393241167435 +2003,BruCap,29,M,0.0005471457231442642,0.00029231218941829884 +2003,BruCap,29,F,0.0005539143279172823,0.000605143721633888 +2003,BruCap,30,M,0.00162016201620162,0.0005717552887364207 +2003,BruCap,30,F,0.0003736222678871661,0.00029394473838918284 +2003,BruCap,31,M,0.001466544454628781,0.0005606952621250352 +2003,BruCap,31,F,0.0005692599620493357,0.0005943536404160475 +2003,BruCap,32,M,0.0011175265412553552,0.0007936507936507938 +2003,BruCap,32,F,0.0007693787266782072,0.0006190034045187249 +2003,BruCap,33,M,0.001697152555157458,0.0005730659025787965 +2003,BruCap,33,F,0.0004061738424045492,0.0 +2003,BruCap,34,M,0.00118413262285376,0.001418842224744609 +2003,BruCap,34,F,0.001257071024512885,0.0009810333551340746 +2003,BruCap,35,M,0.001011326860841424,0.0008995502248875562 +2003,BruCap,35,F,0.001067919692439129,0.0006891798759476222 +2003,BruCap,36,M,0.00121654501216545,0.0018012608826178328 +2003,BruCap,36,F,0.00145288501452885,0.001060820367751061 +2003,BruCap,37,M,0.0007759456838021338,0.0009285051067780873 +2003,BruCap,37,F,0.0008295313148071339,0.0007069635913750442 +2003,BruCap,38,M,0.001960399921584003,0.000982640026203734 +2003,BruCap,38,F,0.001237623762376238,0.0003636363636363636 +2003,BruCap,39,M,0.002609917687211404,0.000725689404934688 +2003,BruCap,39,F,0.001254967580004183,0.0004038772213247173 +2003,BruCap,40,M,0.002532714225411566,0.0007304601899196494 +2003,BruCap,40,F,0.001697432633142372,0.0008399832003359932 +2003,BruCap,41,M,0.001290045151580305,0.002396166134185304 +2003,BruCap,41,F,0.001483050847457627,0.001348920863309353 +2003,BruCap,42,M,0.001679261125104954,0.002079866888519135 +2003,BruCap,42,F,0.0014309076042518401,0.0 +2003,BruCap,43,M,0.0014833651197287562,0.00045475216007276033 +2003,BruCap,43,F,0.0018637399047421828,0.0 +2003,BruCap,44,M,0.004162102957283681,0.001895734597156398 +2003,BruCap,44,F,0.0031302170283806358,0.001630434782608696 +2003,BruCap,45,M,0.004462293618920125,0.002084418968212611 +2003,BruCap,45,F,0.002523659305993691,0.0005361930294906167 +2003,BruCap,46,M,0.005078485687903971,0.002570694087403599 +2003,BruCap,46,F,0.002723083368244659,0.0016411378555798686 +2003,BruCap,47,M,0.005488223187742968,0.004214963119072708 +2003,BruCap,47,F,0.0027460920997042677,0.0005773672055427253 +2003,BruCap,48,M,0.005809900069718801,0.0029940119760479052 +2003,BruCap,48,F,0.003236944324557618,0.002999400119976005 +2003,BruCap,49,M,0.006633119853613907,0.0030693677102516877 +2003,BruCap,49,F,0.003004291845493563,0.0012845215157353893 +2003,BruCap,50,M,0.00570645971239443,0.0024110910186859557 +2003,BruCap,50,F,0.004071137775873152,0.001849568434032059 +2003,BruCap,51,M,0.007033713315546932,0.0041293874741913286 +2003,BruCap,51,F,0.0054237288135593215,0.002158273381294964 +2003,BruCap,52,M,0.007093933463796476,0.003778337531486146 +2003,BruCap,52,F,0.0045563028856584935,0.003298153034300792 +2003,BruCap,53,M,0.007658102766798419,0.004814305364511692 +2003,BruCap,53,F,0.004255319148936171,0.00291970802919708 +2003,BruCap,54,M,0.008114089009097616,0.005952380952380952 +2003,BruCap,54,F,0.004656319290465632,0.002928257686676428 +2003,BruCap,55,M,0.01013096120583148,0.004912280701754386 +2003,BruCap,55,F,0.006282495667244367,0.00303951367781155 +2003,BruCap,56,M,0.01036269430051814,0.003782148260211801 +2003,BruCap,56,F,0.003346720214190094,0.003076923076923077 +2003,BruCap,57,M,0.01125541125541126,0.006914433880726016 +2003,BruCap,57,F,0.005828687278256462,0.004512635379061372 +2003,BruCap,58,M,0.0106711597865768,0.005016722408026756 +2003,BruCap,58,F,0.007043964051493806,0.002654867256637168 +2003,BruCap,59,M,0.01541145681884269,0.006398537477148082 +2003,BruCap,59,F,0.009216589861751152,0.004748338081671415 +2003,BruCap,60,M,0.01635514018691589,0.004775549188156638 +2003,BruCap,60,F,0.008033323415650105,0.0040650406504065045 +2003,BruCap,61,M,0.02216174183514775,0.01018099547511312 +2003,BruCap,61,F,0.01081081081081081,0.005787037037037037 +2003,BruCap,62,M,0.01525658807212205,0.011363636363636373 +2003,BruCap,62,F,0.008083832335329342,0.011754068716094027 +2003,BruCap,63,M,0.01913221728732491,0.013347022587269 +2003,BruCap,63,F,0.0109519797809604,0.007376185458377239 +2003,BruCap,64,M,0.01964104300711141,0.01347150259067358 +2003,BruCap,64,F,0.01230681167716085,0.0033707865168539327 +2003,BruCap,65,M,0.01696750902527076,0.01199040767386091 +2003,BruCap,65,F,0.01124593074874223,0.00997506234413965 +2003,BruCap,66,M,0.02003642987249545,0.02658227848101266 +2003,BruCap,66,F,0.00921796015462385,0.003480278422273782 +2003,BruCap,67,M,0.02455357142857143,0.01955307262569833 +2003,BruCap,67,F,0.013279445727482679,0.00970873786407767 +2003,BruCap,68,M,0.03104693140794224,0.01339285714285714 +2003,BruCap,68,F,0.01458576429404901,0.01345895020188426 +2003,BruCap,69,M,0.02888635499809958,0.02664576802507837 +2003,BruCap,69,F,0.01348747591522158,0.016591251885369532 +2003,BruCap,70,M,0.03384947785379906,0.03030303030303031 +2003,BruCap,70,F,0.01626869588034637,0.01357466063348417 +2003,BruCap,71,M,0.03567567567567568,0.02457466918714556 +2003,BruCap,71,F,0.01983816235969721,0.01827242524916944 +2003,BruCap,72,M,0.03815337657382678,0.03431372549019608 +2003,BruCap,72,F,0.023603082851637768,0.01310043668122271 +2003,BruCap,73,M,0.04320253666270313,0.03441295546558705 +2003,BruCap,73,F,0.022733013387219,0.01807228915662651 +2003,BruCap,74,M,0.05136309758988542,0.0427927927927928 +2003,BruCap,74,F,0.02160493827160494,0.01520912547528517 +2003,BruCap,75,M,0.05161818926669398,0.02956989247311828 +2003,BruCap,75,F,0.02987742594484168,0.01609195402298851 +2003,BruCap,76,M,0.062048448788780276,0.04519774011299435 +2003,BruCap,76,F,0.02905811623246493,0.027027027027027032 +2003,BruCap,77,M,0.06345826235093696,0.04452054794520549 +2003,BruCap,77,F,0.03697227079690233,0.02887139107611549 +2003,BruCap,78,M,0.0629887054735013,0.060240963855421686 +2003,BruCap,78,F,0.04361754558896008,0.02816901408450705 +2003,BruCap,79,M,0.0738255033557047,0.07563025210084033 +2003,BruCap,79,F,0.04404527559055118,0.03048780487804878 +2003,BruCap,80,M,0.07484407484407485,0.0811965811965812 +2003,BruCap,80,F,0.045338114754098366,0.02545454545454546 +2003,BruCap,81,M,0.07610887096774194,0.04433497536945813 +2003,BruCap,81,F,0.05890018243419338,0.04471544715447155 +2003,BruCap,82,M,0.1018518518518518,0.1148648648648649 +2003,BruCap,82,F,0.06136120042872455,0.06968641114982578 +2003,BruCap,83,M,0.1025641025641026,0.09375 +2003,BruCap,83,F,0.07774269928966061,0.06832298136645963 +2003,BruCap,84,M,0.1253561253561254,0.1204819277108434 +2003,BruCap,84,F,0.07411630558722919,0.06106870229007633 +2003,BruCap,85,M,0.1377151799687011,0.09375 +2003,BruCap,85,F,0.09826946847960448,0.06349206349206349 +2003,BruCap,86,M,0.1624087591240876,0.2045454545454546 +2003,BruCap,86,F,0.1031500926497838,0.1134020618556701 +2003,BruCap,87,M,0.1442786069651742,0.1666666666666667 +2003,BruCap,87,F,0.1182375906302287,0.04950495049504952 +2003,BruCap,88,M,0.2064220183486239,0.1818181818181818 +2003,BruCap,88,F,0.1342887473460722,0.09345794392523364 +2003,BruCap,89,M,0.1841584158415842,0.1481481481481482 +2003,BruCap,89,F,0.1616729088639201,0.1188118811881188 +2003,BruCap,90,M,0.1978609625668449,0.08571428571428573 +2003,BruCap,90,F,0.1653015636634401,0.1739130434782609 +2003,BruCap,91,M,0.22297297297297305,0.3 +2003,BruCap,91,F,0.179946284691137,0.196969696969697 +2003,BruCap,92,M,0.2433628318584071,0.3 +2003,BruCap,92,F,0.1688311688311688,0.08064516129032258 +2003,BruCap,93,M,0.2592592592592593,0.1111111111111111 +2003,BruCap,93,F,0.2248520710059172,0.1836734693877551 +2003,BruCap,94,M,0.3070175438596492,0.0 +2003,BruCap,94,F,0.2529711375212224,0.1176470588235294 +2003,BruCap,95,M,0.3880597014925373,0.2857142857142857 +2003,BruCap,95,F,0.2838874680306906,0.2352941176470588 +2003,BruCap,96,M,0.2777777777777778,0.0 +2003,BruCap,96,F,0.2461059190031153,0.3157894736842105 +2003,BruCap,97,M,0.2391304347826087,0.0 +2003,BruCap,97,F,0.3043478260869566,0.4 +2003,BruCap,98,M,0.3703703703703704,0.4 +2003,BruCap,98,F,0.2602739726027397,0.125 +2003,BruCap,99,M,0.3333333333333333,0.0 +2003,BruCap,99,F,0.2871287128712871,0.5 +2003,BruCap,100,M,0.625,0.0 +2003,BruCap,100,F,0.3225806451612903,0.2 +2003,BruCap,101,M,0.8333333333333334,0.5 +2003,BruCap,101,F,0.3529411764705883,0.5 +2003,BruCap,102,M,1.0,0.0 +2003,BruCap,102,F,0.3846153846153847,0.25 +2003,BruCap,103,M,0.0,0.0 +2003,BruCap,103,F,0.375,0.0 +2003,BruCap,104,M,0.0,0.0 +2003,BruCap,104,F,0.5555555555555556,0.25 +2003,BruCap,105,M,0.0,0.0 +2003,BruCap,105,F,0.6666666666666666,0.0 +2003,BruCap,106,M,0.0,0.0 +2003,BruCap,106,F,0.2,0.0 +2003,BruCap,107,M,0.0,0.0 +2003,BruCap,107,F,0.0,0.5 +2003,BruCap,108,M,0.0,0.0 +2003,BruCap,108,F,0.0,0.0 +2003,BruCap,109,M,0.0,0.0 +2003,BruCap,109,F,0.0,0.0 +2003,BruCap,110,M,0.0,0.0 +2003,BruCap,110,F,1.0,0.0 +2003,BruCap,111,M,0.0,0.0 +2003,BruCap,111,F,0.0,0.0 +2003,BruCap,112,M,0.0,0.0 +2003,BruCap,112,F,0.0,0.0 +2003,BruCap,113,M,0.0,0.0 +2003,BruCap,113,F,0.0,0.0 +2003,BruCap,114,M,0.0,0.0 +2003,BruCap,114,F,0.0,0.0 +2003,BruCap,115,M,0.0,0.0 +2003,BruCap,115,F,0.0,0.0 +2003,BruCap,116,M,0.0,0.0 +2003,BruCap,116,F,0.0,0.0 +2003,BruCap,117,M,0.0,0.0 +2003,BruCap,117,F,0.0,0.0 +2003,BruCap,118,M,0.0,0.0 +2003,BruCap,118,F,0.0,0.0 +2003,BruCap,119,M,0.0,0.0 +2003,BruCap,119,F,0.0,0.0 +2003,BruCap,120,M,0.0,0.0 +2003,BruCap,120,F,0.0,0.0 +2003,Fla,0,M,0.00116120218579235,0.001427551748750892 +2003,Fla,0,F,0.0005771797554200786,0.0 +2003,Fla,1,M,0.0002699510713683145,0.0 +2003,Fla,1,F,0.0004927322000492731,0.0007633587786259543 +2003,Fla,2,M,0.000163929051506508,0.0 +2003,Fla,2,F,0.00030741904631780296,0.0 +2003,Fla,3,M,0.0001635643953024306,0.0 +2003,Fla,3,F,0.0001350119823134303,0.0 +2003,Fla,4,M,0.000190554832152952,0.0 +2003,Fla,4,F,0.0001668446342765617,0.0 +2003,Fla,5,M,0.00015535669898086008,0.0007272727272727272 +2003,Fla,5,F,6.461826758424607e-05,0.0 +2003,Fla,6,M,6.184291898577613e-05,0.0 +2003,Fla,6,F,0.0001286008230452675,0.0007633587786259543 +2003,Fla,7,M,0.0001231451265316175,0.0 +2003,Fla,7,F,3.2125417630429196e-05,0.0 +2003,Fla,8,M,6.072014087072682e-05,0.0 +2003,Fla,8,F,3.192032686414709e-05,0.0 +2003,Fla,9,M,5.84095090680763e-05,0.0 +2003,Fla,9,F,9.013339742819372e-05,0.0 +2003,Fla,10,M,8.433362381581536e-05,0.0 +2003,Fla,10,F,2.9308323563892152e-05,0.0 +2003,Fla,11,M,0.0001107879795042238,0.0 +2003,Fla,11,F,0.00014600245284120768,0.0 +2003,Fla,12,M,0.0002518609727430459,0.0 +2003,Fla,12,F,0.0001466318660371272,0.0 +2003,Fla,13,M,0.0001735558705273206,0.0 +2003,Fla,13,F,0.00018226556092226385,0.0 +2003,Fla,14,M,0.00026338122969769693,0.0 +2003,Fla,14,F,6.124823911312549e-05,0.0 +2003,Fla,15,M,0.000147693034796479,0.0007968127490039841 +2003,Fla,15,F,0.0002185451139556666,0.0 +2003,Fla,16,M,0.0004419954621799216,0.001582278481012658 +2003,Fla,16,F,9.388202159286497e-05,0.0 +2003,Fla,17,M,0.0005773847509648402,0.0007739938080495358 +2003,Fla,17,F,0.0001271253774034642,0.0007385524372230429 +2003,Fla,18,M,0.0005935774915415207,0.0 +2003,Fla,18,F,0.0006225874735400322,0.0 +2003,Fla,19,M,0.0008972503617945008,0.0 +2003,Fla,19,F,0.0002706685513217648,0.0 +2003,Fla,20,M,0.000987333916330503,0.0012539184952978062 +2003,Fla,20,F,0.0004160475482912333,0.0 +2003,Fla,21,M,0.001175891489827172,0.001179941002949853 +2003,Fla,21,F,0.0002030692466130951,0.0004899559039686428 +2003,Fla,22,M,0.001082160992258387,0.0 +2003,Fla,22,F,0.0003451052571034166,0.0 +2003,Fla,23,M,0.0006872096539212182,0.001448575567358764 +2003,Fla,23,F,0.00037662601037170086,0.0008503401360544217 +2003,Fla,24,M,0.0008480325644504749,0.0008795074758135447 +2003,Fla,24,F,0.0004971487059511624,0.0 +2003,Fla,25,M,0.001015581928444999,0.0 +2003,Fla,25,F,0.0004170390229371463,0.00037243947858472997 +2003,Fla,26,M,0.0008284268765348088,0.001225490196078432 +2003,Fla,26,F,0.0001540832049306626,0.0 +2003,Fla,27,M,0.0010032834731849689,0.001934984520123839 +2003,Fla,27,F,0.0003163455759071209,0.0007285974499089253 +2003,Fla,28,M,0.0010548523206751052,0.0010611956137247973 +2003,Fla,28,F,0.0005122487721095608,0.0 +2003,Fla,29,M,0.0005914326752471344,0.0003518648838845883 +2003,Fla,29,F,0.0004950927570841951,0.0 +2003,Fla,30,M,0.0008630221958520996,0.000652954619653934 +2003,Fla,30,F,0.0004682550612863242,0.00033101621979477 +2003,Fla,31,M,0.0007727577146978518,0.000985869208018403 +2003,Fla,31,F,0.0002872062663185379,0.0003304692663582287 +2003,Fla,32,M,0.0009223022658723237,0.0006261740763932372 +2003,Fla,32,F,0.0003330173937546431,0.0 +2003,Fla,33,M,0.0007466401194624191,0.0003104625892579944 +2003,Fla,33,F,0.0003824481782718442,0.0006594131223211343 +2003,Fla,34,M,0.001177307399867553,0.0006279434850863422 +2003,Fla,34,F,0.0004036428769646056,0.0006734006734006732 +2003,Fla,35,M,0.001112110169892575,0.0006768189509306263 +2003,Fla,35,F,0.0005933984423290889,0.0003432887058015792 +2003,Fla,36,M,0.001286291804483646,0.0006022282445046673 +2003,Fla,36,F,0.0005427600528601095,0.0 +2003,Fla,37,M,0.001351560942104447,0.0006335128286347799 +2003,Fla,37,F,0.0004803843074459568,0.0010467550593161196 +2003,Fla,38,M,0.0014044644947119786,0.0012292562999385366 +2003,Fla,38,F,0.0006302292730631316,0.0007246376811594202 +2003,Fla,39,M,0.0013037530990852358,0.0006600660066006603 +2003,Fla,39,F,0.0007899240795190241,0.0 +2003,Fla,40,M,0.0014277061521156009,0.0010063737001006366 +2003,Fla,40,F,0.000934475470018912,0.0 +2003,Fla,41,M,0.001679316060368141,0.00177367860943597 +2003,Fla,41,F,0.0011043622308117061,0.0004380201489268507 +2003,Fla,42,M,0.0020884247944901128,0.0014357501794687731 +2003,Fla,42,F,0.0009745925976292467,0.0 +2003,Fla,43,M,0.0018589799667570641,0.002299731697968571 +2003,Fla,43,F,0.001114206128133705,0.00046104195481788836 +2003,Fla,44,M,0.001962883654532477,0.0007465472191116088 +2003,Fla,44,F,0.001694100409789153,0.001013171225937183 +2003,Fla,45,M,0.002578310528101323,0.0008097165991902834 +2003,Fla,45,F,0.001466924348615736,0.001609442060085837 +2003,Fla,46,M,0.002889836631009812,0.002036659877800407 +2003,Fla,46,F,0.001720521341535271,0.002711496746203905 +2003,Fla,47,M,0.003124926019743851,0.001670843776106934 +2003,Fla,47,F,0.001859356376638856,0.00170261066969353 +2003,Fla,48,M,0.003280428385353853,0.0025929127052722557 +2003,Fla,48,F,0.001987339908729575,0.002963841138114997 +2003,Fla,49,M,0.004567224608699945,0.005223171889838557 +2003,Fla,49,F,0.002281715850319441,0.001873828856964397 +2003,Fla,50,M,0.0045575013003740115,0.002807674309780066 +2003,Fla,50,F,0.0022987918571684,0.001910828025477707 +2003,Fla,51,M,0.004131694514460931,0.0019029495718363469 +2003,Fla,51,F,0.00300037172747066,0.004704301075268817 +2003,Fla,52,M,0.004930004481822257,0.005755395683453238 +2003,Fla,52,F,0.0027451293942059108,0.002554278416347382 +2003,Fla,53,M,0.005417488494411571,0.006375227686703097 +2003,Fla,53,F,0.003061882251826386,0.0012730744748567788 +2003,Fla,54,M,0.005801840765842981,0.002386634844868735 +2003,Fla,54,F,0.003507932711472535,0.002640264026402641 +2003,Fla,55,M,0.006930930610721618,0.006262042389210019 +2003,Fla,55,F,0.003418113309110484,0.005225342913128674 +2003,Fla,56,M,0.0075056683432800815,0.008106819265617548 +2003,Fla,56,F,0.0041079190077387895,0.004366812227074236 +2003,Fla,57,M,0.008649957193044608,0.01099537037037037 +2003,Fla,57,F,0.004534479712619987,0.002338269680436477 +2003,Fla,58,M,0.009120715350223548,0.004149377593360996 +2003,Fla,58,F,0.004776597638402658,0.004418262150220913 +2003,Fla,59,M,0.0105352007002626,0.01259748050389922 +2003,Fla,59,F,0.0053833302394653785,0.00732899022801303 +2003,Fla,60,M,0.010870738994276659,0.006016042780748663 +2003,Fla,60,F,0.006397952655150353,0.005952380952380952 +2003,Fla,61,M,0.011148675843194079,0.01304945054945055 +2003,Fla,61,F,0.006153012654309044,0.0045829514207149395 +2003,Fla,62,M,0.01197232087284444,0.014559894109861018 +2003,Fla,62,F,0.005377846067886576,0.006339144215530904 +2003,Fla,63,M,0.0119460241612545,0.01063829787234043 +2003,Fla,63,F,0.006272541947624275,0.014955134596211369 +2003,Fla,64,M,0.01488192581932361,0.01884057971014493 +2003,Fla,64,F,0.007314974182444063,0.00390625 +2003,Fla,65,M,0.01629473397741189,0.0125 +2003,Fla,65,F,0.007657945118059987,0.01049317943336831 +2003,Fla,66,M,0.0165610086188475,0.02329594477998275 +2003,Fla,66,F,0.008441431458183952,0.009836065573770493 +2003,Fla,67,M,0.02026807326854294,0.01697944593386953 +2003,Fla,67,F,0.01034878008842312,0.003685503685503686 +2003,Fla,68,M,0.021893297450630983,0.03300970873786408 +2003,Fla,68,F,0.011271778686676759,0.01158748551564311 +2003,Fla,69,M,0.02407058736663344,0.02318840579710145 +2003,Fla,69,F,0.01182739797244606,0.014888337468982632 +2003,Fla,70,M,0.02677682292627153,0.03590285110876452 +2003,Fla,70,F,0.01355974763803007,0.01092896174863388 +2003,Fla,71,M,0.03126414240458592,0.029345372460496618 +2003,Fla,71,F,0.015193631941373431,0.01765650080256822 +2003,Fla,72,M,0.03227952108928711,0.04227053140096619 +2003,Fla,72,F,0.016532374562614367,0.021887824897400817 +2003,Fla,73,M,0.03769294678385588,0.041265474552957364 +2003,Fla,73,F,0.019918106738843783,0.021666666666666667 +2003,Fla,74,M,0.0419642029119911,0.04532163742690058 +2003,Fla,74,F,0.02249775381850854,0.02750809061488673 +2003,Fla,75,M,0.045815941164778384,0.04421768707482993 +2003,Fla,75,F,0.023654776299879082,0.03610108303249098 +2003,Fla,76,M,0.05504829260568955,0.05597014925373135 +2003,Fla,76,F,0.02911186080891551,0.02425373134328359 +2003,Fla,77,M,0.055834515882545566,0.05725190839694656 +2003,Fla,77,F,0.03319469512673625,0.04382470119521913 +2003,Fla,78,M,0.06600404713724557,0.08 +2003,Fla,78,F,0.03917135928316001,0.04121475054229936 +2003,Fla,79,M,0.07383327969102027,0.09545454545454546 +2003,Fla,79,F,0.0426036505314869,0.0423162583518931 +2003,Fla,80,M,0.08104765369225173,0.09448818897637797 +2003,Fla,80,F,0.05095806720355457,0.07387862796833773 +2003,Fla,81,M,0.08889065732930129,0.0660377358490566 +2003,Fla,81,F,0.05619826709908515,0.07282913165266107 +2003,Fla,82,M,0.1056224178192923,0.1091549295774648 +2003,Fla,82,F,0.06668412781561027,0.06369426751592358 +2003,Fla,83,M,0.1158905551170745,0.06285714285714286 +2003,Fla,83,F,0.07668711656441718,0.1065989847715736 +2003,Fla,84,M,0.1140448191701797,0.09022556390977443 +2003,Fla,84,F,0.08423882603338187,0.0736196319018405 +2003,Fla,85,M,0.1405717282979281,0.1090909090909091 +2003,Fla,85,F,0.1074766355140187,0.06666666666666668 +2003,Fla,86,M,0.1564836298014953,0.1458333333333334 +2003,Fla,86,F,0.1172957477305304,0.1363636363636364 +2003,Fla,87,M,0.1577879249112126,0.1609195402298851 +2003,Fla,87,F,0.13401946526457098,0.1153846153846154 +2003,Fla,88,M,0.1786504424778761,0.1549295774647887 +2003,Fla,88,F,0.1370580532518551,0.1374045801526718 +2003,Fla,89,M,0.2262798634812287,0.2321428571428572 +2003,Fla,89,F,0.1527359437751004,0.1372549019607843 +2003,Fla,90,M,0.2264564169951818,0.25 +2003,Fla,90,F,0.1746273197444478,0.1162790697674419 +2003,Fla,91,M,0.2477665276950566,0.1764705882352941 +2003,Fla,91,F,0.1952260818940423,0.1791044776119403 +2003,Fla,92,M,0.2888368462138954,0.1363636363636364 +2003,Fla,92,F,0.216064453125,0.1886792452830189 +2003,Fla,93,M,0.2932862190812721,0.368421052631579 +2003,Fla,93,F,0.2386658031088083,0.1707317073170732 +2003,Fla,94,M,0.3135593220338983,0.1875 +2003,Fla,94,F,0.2631163708086785,0.2857142857142857 +2003,Fla,95,M,0.3508353221957041,0.125 +2003,Fla,95,F,0.2807991120976693,0.2857142857142857 +2003,Fla,96,M,0.3503937007874016,0.3333333333333333 +2003,Fla,96,F,0.3006482982171799,0.2307692307692308 +2003,Fla,97,M,0.3233830845771145,0.5 +2003,Fla,97,F,0.3186558516801854,0.2 +2003,Fla,98,M,0.4444444444444444,0.0 +2003,Fla,98,F,0.3600682593856656,0.375 +2003,Fla,99,M,0.375,0.0 +2003,Fla,99,F,0.3615160349854228,0.125 +2003,Fla,100,M,0.4,0.0 +2003,Fla,100,F,0.4268292682926829,0.3333333333333333 +2003,Fla,101,M,0.6111111111111112,0.0 +2003,Fla,101,F,0.3943661971830986,0.0 +2003,Fla,102,M,0.5,1.0 +2003,Fla,102,F,0.4714285714285714,1.0 +2003,Fla,103,M,0.4,0.0 +2003,Fla,103,F,0.3863636363636364,0.0 +2003,Fla,104,M,1.0,0.0 +2003,Fla,104,F,0.5789473684210527,0.0 +2003,Fla,105,M,0.0,0.0 +2003,Fla,105,F,0.4444444444444444,0.5 +2003,Fla,106,M,1.0,0.0 +2003,Fla,106,F,0.2,0.0 +2003,Fla,107,M,0.0,0.0 +2003,Fla,107,F,0.5714285714285714,0.0 +2003,Fla,108,M,0.0,0.0 +2003,Fla,108,F,0.0,0.0 +2003,Fla,109,M,0.0,0.0 +2003,Fla,109,F,0.0,0.0 +2003,Fla,110,M,0.0,0.0 +2003,Fla,110,F,0.0,0.0 +2003,Fla,111,M,0.0,0.0 +2003,Fla,111,F,0.0,0.0 +2003,Fla,112,M,0.0,0.0 +2003,Fla,112,F,0.0,0.0 +2003,Fla,113,M,0.0,0.0 +2003,Fla,113,F,0.0,0.0 +2003,Fla,114,M,0.0,0.0 +2003,Fla,114,F,0.0,0.0 +2003,Fla,115,M,0.0,0.0 +2003,Fla,115,F,0.0,0.0 +2003,Fla,116,M,0.0,0.0 +2003,Fla,116,F,0.0,0.0 +2003,Fla,117,M,0.0,0.0 +2003,Fla,117,F,0.0,0.0 +2003,Fla,118,M,0.0,0.0 +2003,Fla,118,F,0.0,0.0 +2003,Fla,119,M,0.0,0.0 +2003,Fla,119,F,0.0,0.0 +2003,Fla,120,M,0.0,0.0 +2003,Fla,120,F,0.0,0.0 +2003,Wal,0,M,0.0010234863176039651,0.002617801047120419 +2003,Wal,0,F,0.0009087294825921508,0.002828854314002829 +2003,Wal,1,M,0.000414443350774491,0.0 +2003,Wal,1,F,0.0003759398496240602,0.0 +2003,Wal,2,M,0.0003027703486905183,0.001237623762376238 +2003,Wal,2,F,0.0001056579851022241,0.0 +2003,Wal,3,M,0.0003097893432465923,0.0 +2003,Wal,3,F,0.0001083012942004657,0.0 +2003,Wal,4,M,0.00010313531353135308,0.0 +2003,Wal,4,F,0.00016144656118824668,0.0 +2003,Wal,5,M,0.000256568144499179,0.0 +2003,Wal,5,F,0.0,0.0 +2003,Wal,6,M,5.060728744939271e-05,0.0 +2003,Wal,6,F,0.00010582570506375999,0.0011834319526627221 +2003,Wal,7,M,0.0,0.0 +2003,Wal,7,F,0.0,0.0 +2003,Wal,8,M,0.0001025115325474116,0.0 +2003,Wal,8,F,5.394616173059287e-05,0.0 +2003,Wal,9,M,9.851731441800895e-05,0.0 +2003,Wal,9,F,0.0,0.0 +2003,Wal,10,M,4.693954187007135e-05,0.0 +2003,Wal,10,F,0.0,0.0 +2003,Wal,11,M,0.00018310826276035714,0.0008944543828264757 +2003,Wal,11,F,0.0001903402331667856,0.0 +2003,Wal,12,M,0.0001854513422040892,0.0 +2003,Wal,12,F,0.0001449555469655972,0.0 +2003,Wal,13,M,0.0001848343422207846,0.0008865248226950351 +2003,Wal,13,F,9.699321047526673e-05,0.0 +2003,Wal,14,M,0.0005587632706276774,0.0008960573476702508 +2003,Wal,14,F,0.0001476450612727005,0.0008710801393728223 +2003,Wal,15,M,0.0003866602223296279,0.0 +2003,Wal,15,F,0.000202500885941376,0.0 +2003,Wal,16,M,0.000725689404934688,0.0 +2003,Wal,16,F,0.000204488523081642,0.0008250825082508251 +2003,Wal,17,M,0.0008076321235677147,0.0008090614886731393 +2003,Wal,17,F,0.00031650577623041634,0.0 +2003,Wal,18,M,0.001684532924961715,0.0007892659826361484 +2003,Wal,18,F,0.0004785197788175245,0.0 +2003,Wal,19,M,0.001335868057339568,0.001524390243902439 +2003,Wal,19,F,0.00016567263088137842,0.000725689404934688 +2003,Wal,20,M,0.0013793808112802699,0.0007107320540156361 +2003,Wal,20,F,0.00037236023192723015,0.0 +2003,Wal,21,M,0.001735667976925826,0.0 +2003,Wal,21,F,0.0004187166335182665,0.0 +2003,Wal,22,M,0.0011762299273805868,0.00178359096313912 +2003,Wal,22,F,0.0004751597064568925,0.0 +2003,Wal,23,M,0.0009431984908824146,0.0005577244841048521 +2003,Wal,23,F,0.0002790801518196026,0.0 +2003,Wal,24,M,0.0012506797172376286,0.001025115325474116 +2003,Wal,24,F,0.0005095974180397486,0.001009081735620585 +2003,Wal,25,M,0.0021208331067486,0.002123142250530786 +2003,Wal,25,F,0.00039865595990660064,0.0 +2003,Wal,26,M,0.0016806722689075633,0.00290838584585555 +2003,Wal,26,F,0.0006162464985994397,0.001505268439538385 +2003,Wal,27,M,0.001415659370576065,0.00046816479400749053 +2003,Wal,27,F,0.0004990296645411699,0.0009483167377904221 +2003,Wal,28,M,0.001102362204724409,0.0 +2003,Wal,28,F,0.000540277702739208,0.0 +2003,Wal,29,M,0.0011593326276526036,0.0003707823507601038 +2003,Wal,29,F,0.0005141652527122217,0.0004016064257028113 +2003,Wal,30,M,0.0017474879860200961,0.0007150518412584912 +2003,Wal,30,F,0.000493339911198816,0.00038226299694189614 +2003,Wal,31,M,0.001331747919143877,0.0003516174402250352 +2003,Wal,31,F,0.0004797773832941515,0.0 +2003,Wal,32,M,0.001308583337372171,0.001049685094471658 +2003,Wal,32,F,0.0004422604422604423,0.0003660322108345535 +2003,Wal,33,M,0.001214535561601244,0.0010148849797023 +2003,Wal,33,F,0.0005857944837686113,0.001052631578947368 +2003,Wal,34,M,0.002072027627035027,0.0006825938566552901 +2003,Wal,34,F,0.0006366307541625857,0.0003449465332873405 +2003,Wal,35,M,0.0018337998262715949,0.0009810333551340746 +2003,Wal,35,F,0.0006741464823999615,0.0 +2003,Wal,36,M,0.001937709721631457,0.001446759259259259 +2003,Wal,36,F,0.0011262318160488026,0.0009702457956015523 +2003,Wal,37,M,0.002045361574473888,0.0011497556769186554 +2003,Wal,37,F,0.0009487237406821775,0.0003387533875338754 +2003,Wal,38,M,0.0019698826825424627,0.001784121320249777 +2003,Wal,38,F,0.00104479561185843,0.0003301419610432486 +2003,Wal,39,M,0.0030290881553744053,0.002092050209205021 +2003,Wal,39,F,0.001357030292418141,0.000682360968952576 +2003,Wal,40,M,0.0024654156964799352,0.0012113870381586919 +2003,Wal,40,F,0.001159420289855073,0.00036873156342182885 +2003,Wal,41,M,0.002845582677515451,0.0021712158808933 +2003,Wal,41,F,0.001604440397207407,0.001061571125265393 +2003,Wal,42,M,0.0042037475962613475,0.001689664883131512 +2003,Wal,42,F,0.002165554426128077,0.001118985453189108 +2003,Wal,43,M,0.003704364902258325,0.002104630186410102 +2003,Wal,43,F,0.001626225018188043,0.0 +2003,Wal,44,M,0.004088678902416864,0.0035492457852706297 +2003,Wal,44,F,0.0023521212649185467,0.0007727975270479134 +2003,Wal,45,M,0.003720887500574211,0.0018359853121175031 +2003,Wal,45,F,0.001873745259870623,0.0020193861066235873 +2003,Wal,46,M,0.005216655700723752,0.0032419687592101392 +2003,Wal,46,F,0.002382772108078946,0.002365930599369085 +2003,Wal,47,M,0.006144905444672034,0.002813379180994061 +2003,Wal,47,F,0.002618273745034309,0.001642710472279261 +2003,Wal,48,M,0.005823389021479714,0.002844500632111252 +2003,Wal,48,F,0.002956292354573157,0.0004230118443316413 +2003,Wal,49,M,0.007268001540238738,0.0042400521852576645 +2003,Wal,49,F,0.003417698134121559,0.0022883295194508014 +2003,Wal,50,M,0.007722570304531546,0.0034059945504087198 +2003,Wal,50,F,0.003560052463931048,0.001814882032667877 +2003,Wal,51,M,0.007464192051644139,0.0063447303489601705 +2003,Wal,51,F,0.004474698909887181,0.002302025782688767 +2003,Wal,52,M,0.008581818181818182,0.005197505197505198 +2003,Wal,52,F,0.004355648139380741,0.001361161524500908 +2003,Wal,53,M,0.008545339127887104,0.0061998541210795035 +2003,Wal,53,F,0.0037992116635798072,0.001966568338249754 +2003,Wal,54,M,0.008015358771298295,0.005391804457225018 +2003,Wal,54,F,0.004280388456758872,0.002306273062730628 +2003,Wal,55,M,0.0107407764184568,0.007962359753890699 +2003,Wal,55,F,0.005106541014808968,0.003479125248508947 +2003,Wal,56,M,0.01094059405940594,0.005462348809988296 +2003,Wal,56,F,0.005154639175257732,0.007419183889772125 +2003,Wal,57,M,0.01336880611905554,0.005865102639296189 +2003,Wal,57,F,0.005804007820136853,0.006887914840325611 +2003,Wal,58,M,0.01187520966118752,0.01517376407244249 +2003,Wal,58,F,0.006812925807862992,0.004329004329004329 +2003,Wal,59,M,0.013060105346706107,0.008849557522123894 +2003,Wal,59,F,0.007671957671957672,0.006821282401091405 +2003,Wal,60,M,0.013487636333361093,0.007058823529411766 +2003,Wal,60,F,0.006815084052703316,0.005513439007580979 +2003,Wal,61,M,0.01544401544401545,0.01329305135951662 +2003,Wal,61,F,0.008355427010524625,0.00510948905109489 +2003,Wal,62,M,0.01723027375201288,0.01583949313621964 +2003,Wal,62,F,0.00843304021911489,0.0067859346082665035 +2003,Wal,63,M,0.01703399327605529,0.0193621867881549 +2003,Wal,63,F,0.009546851500686588,0.006157635467980296 +2003,Wal,64,M,0.01973389146359695,0.011152416356877321 +2003,Wal,64,F,0.009103234553554137,0.006682867557715674 +2003,Wal,65,M,0.019203636933688668,0.01748040988547318 +2003,Wal,65,F,0.011727805809354971,0.005453306066803 +2003,Wal,66,M,0.024076652198837117,0.01468710089399745 +2003,Wal,66,F,0.01007539410555175,0.01412239408204439 +2003,Wal,67,M,0.0273224043715847,0.0231809401159047 +2003,Wal,67,F,0.01308048999930791,0.01096067053513862 +2003,Wal,68,M,0.02795436022819886,0.02298850574712644 +2003,Wal,68,F,0.0137096234869257,0.009026434558349452 +2003,Wal,69,M,0.0294719607040524,0.027659574468085108 +2003,Wal,69,F,0.014985282312014991,0.012995451591942821 +2003,Wal,70,M,0.03491609003420027,0.03053435114503817 +2003,Wal,70,F,0.01644919918372395,0.01788170563961486 +2003,Wal,71,M,0.03684879288437103,0.03179409538228615 +2003,Wal,71,F,0.01676079431590454,0.01496598639455782 +2003,Wal,72,M,0.03876097399370549,0.04647887323943662 +2003,Wal,72,F,0.02027437173728299,0.02262142381902861 +2003,Wal,73,M,0.04770047700477005,0.03948367501898254 +2003,Wal,73,F,0.022655188038060717,0.02036516853932585 +2003,Wal,74,M,0.04977802965901577,0.05733558178752107 +2003,Wal,74,F,0.02612595047767596,0.03435399551904407 +2003,Wal,75,M,0.05474525474525475,0.06219312602291326 +2003,Wal,75,F,0.03054921444877132,0.03350327749453751 +2003,Wal,76,M,0.06100126209507783,0.0738488271068636 +2003,Wal,76,F,0.03399317406143345,0.03752759381898455 +2003,Wal,77,M,0.0650828729281768,0.05982053838484546 +2003,Wal,77,F,0.03803358284442647,0.0421216848673947 +2003,Wal,78,M,0.07547619047619047,0.07311827956989247 +2003,Wal,78,F,0.04461255656108598,0.04159592529711375 +2003,Wal,79,M,0.07895431740163718,0.09291521486643438 +2003,Wal,79,F,0.047736073875484064,0.03981900452488688 +2003,Wal,80,M,0.08744038155802862,0.0829817158931083 +2003,Wal,80,F,0.05570209464701319,0.0550098231827112 +2003,Wal,81,M,0.1065638281127027,0.1099476439790576 +2003,Wal,81,F,0.06797042690197949,0.06148491879350348 +2003,Wal,82,M,0.1128113879003559,0.1320754716981132 +2003,Wal,82,F,0.07547974413646055,0.06900726392251816 +2003,Wal,83,M,0.1169477467514515,0.1516245487364621 +2003,Wal,83,F,0.08482646284926701,0.08704061895551257 +2003,Wal,84,M,0.136036036036036,0.1616766467065868 +2003,Wal,84,F,0.0971264367816092,0.0903010033444816 +2003,Wal,85,M,0.1702011963023382,0.2054794520547945 +2003,Wal,85,F,0.1038793103448276,0.1148648648648649 +2003,Wal,86,M,0.174412247129579,0.143939393939394 +2003,Wal,86,F,0.1158011049723757,0.1335616438356165 +2003,Wal,87,M,0.1868775629759813,0.1428571428571429 +2003,Wal,87,F,0.1266968325791855,0.1190476190476191 +2003,Wal,88,M,0.1788235294117647,0.1794871794871795 +2003,Wal,88,F,0.1457148460482448,0.15625 +2003,Wal,89,M,0.2095451155853841,0.2427184466019418 +2003,Wal,89,F,0.1662735849056604,0.1755725190839695 +2003,Wal,90,M,0.2247191011235955,0.1975308641975309 +2003,Wal,90,F,0.1868715083798883,0.2038834951456311 +2003,Wal,91,M,0.2761627906976744,0.2391304347826087 +2003,Wal,91,F,0.2109689213893967,0.1845238095238095 +2003,Wal,92,M,0.2640449438202247,0.2666666666666667 +2003,Wal,92,F,0.2271307452030344,0.3333333333333333 +2003,Wal,93,M,0.3288409703504044,0.5238095238095238 +2003,Wal,93,F,0.2672463768115942,0.1919191919191919 +2003,Wal,94,M,0.3224489795918367,0.2857142857142857 +2003,Wal,94,F,0.2648401826484018,0.2235294117647059 +2003,Wal,95,M,0.3581081081081081,0.5 +2003,Wal,95,F,0.2859941234084231,0.2173913043478261 +2003,Wal,96,M,0.4017094017094018,0.75 +2003,Wal,96,F,0.2816265060240964,0.4285714285714286 +2003,Wal,97,M,0.2666666666666667,0.3333333333333333 +2003,Wal,97,F,0.3522012578616352,0.2272727272727273 +2003,Wal,98,M,0.5909090909090909,1.0 +2003,Wal,98,F,0.3879598662207358,0.44 +2003,Wal,99,M,0.4285714285714286,0.0 +2003,Wal,99,F,0.3254716981132076,0.2727272727272727 +2003,Wal,100,M,0.5,1.0 +2003,Wal,100,F,0.4324324324324325,0.5 +2003,Wal,101,M,0.7,0.0 +2003,Wal,101,F,0.3943661971830986,0.5 +2003,Wal,102,M,0.25,1.0 +2003,Wal,102,F,0.525,0.0 +2003,Wal,103,M,0.3333333333333333,0.0 +2003,Wal,103,F,0.35,0.0 +2003,Wal,104,M,1.0,0.0 +2003,Wal,104,F,0.2222222222222222,0.0 +2003,Wal,105,M,1.0,0.0 +2003,Wal,105,F,0.1666666666666667,0.0 +2003,Wal,106,M,0.0,0.0 +2003,Wal,106,F,1.0,0.0 +2003,Wal,107,M,0.0,0.0 +2003,Wal,107,F,0.5,0.0 +2003,Wal,108,M,0.0,0.0 +2003,Wal,108,F,0.0,0.0 +2003,Wal,109,M,1.0,0.0 +2003,Wal,109,F,0.0,0.0 +2003,Wal,110,M,0.0,0.0 +2003,Wal,110,F,0.0,0.0 +2003,Wal,111,M,0.0,0.0 +2003,Wal,111,F,0.0,0.0 +2003,Wal,112,M,0.0,0.0 +2003,Wal,112,F,0.0,0.0 +2003,Wal,113,M,0.0,0.0 +2003,Wal,113,F,0.0,0.0 +2003,Wal,114,M,0.0,0.0 +2003,Wal,114,F,0.0,0.0 +2003,Wal,115,M,0.0,0.0 +2003,Wal,115,F,0.0,0.0 +2003,Wal,116,M,0.0,0.0 +2003,Wal,116,F,0.0,0.0 +2003,Wal,117,M,0.0,0.0 +2003,Wal,117,F,0.0,0.0 +2003,Wal,118,M,0.0,0.0 +2003,Wal,118,F,0.0,0.0 +2003,Wal,119,M,0.0,0.0 +2003,Wal,119,F,0.0,0.0 +2003,Wal,120,M,0.0,0.0 +2003,Wal,120,F,0.0,0.0 +2004,BruCap,0,M,0.001192301141202521,0.0 +2004,BruCap,0,F,0.0005229213874847481,0.0 +2004,BruCap,1,M,0.00035523978685612787,0.0 +2004,BruCap,1,F,0.0009219988936013275,0.0 +2004,BruCap,2,M,0.0001779676098949991,0.0 +2004,BruCap,2,F,0.0,0.0 +2004,BruCap,3,M,0.0001853224610822832,0.0 +2004,BruCap,3,F,0.0,0.0 +2004,BruCap,4,M,0.0,0.0008326394671107411 +2004,BruCap,4,F,0.0,0.0 +2004,BruCap,5,M,0.0,0.0 +2004,BruCap,5,F,0.0,0.0016570008285004142 +2004,BruCap,6,M,0.0002005213555243634,0.0 +2004,BruCap,6,F,0.0,0.0 +2004,BruCap,7,M,0.0004222081486172683,0.0 +2004,BruCap,7,F,0.0002137208805300278,0.0 +2004,BruCap,8,M,0.0,0.0 +2004,BruCap,8,F,0.0002243158366980709,0.0 +2004,BruCap,9,M,0.0,0.0 +2004,BruCap,9,F,0.0,0.0 +2004,BruCap,10,M,0.0002147766323024055,0.0 +2004,BruCap,10,F,0.0,0.0 +2004,BruCap,11,M,0.0,0.0 +2004,BruCap,11,F,0.0004486316733961418,0.0 +2004,BruCap,12,M,0.0,0.0 +2004,BruCap,12,F,0.0,0.0 +2004,BruCap,13,M,0.0,0.0 +2004,BruCap,13,F,0.00045840018336007336,0.0 +2004,BruCap,14,M,0.0004444444444444445,0.0 +2004,BruCap,14,F,0.00023020257826887665,0.0 +2004,BruCap,15,M,0.0004430660168365087,0.0 +2004,BruCap,15,F,0.0002334812047630166,0.0009276437847866419 +2004,BruCap,16,M,0.0002305741295826609,0.0 +2004,BruCap,16,F,0.0,0.0 +2004,BruCap,17,M,0.00023153507756425097,0.0 +2004,BruCap,17,F,0.0,0.0 +2004,BruCap,18,M,0.001635896237438654,0.0008904719501335707 +2004,BruCap,18,F,0.0005026388539834129,0.0 +2004,BruCap,19,M,0.0018544274455261941,0.0 +2004,BruCap,19,F,0.00022883295194508008,0.0 +2004,BruCap,20,M,0.0011737089201877939,0.0007380073800738008 +2004,BruCap,20,F,0.0,0.0 +2004,BruCap,21,M,0.00022836263987211696,0.0 +2004,BruCap,21,F,0.0006782726656115759,0.0 +2004,BruCap,22,M,0.0010699764605178687,0.0005494505494505496 +2004,BruCap,22,F,0.0008403361344537818,0.0 +2004,BruCap,23,M,0.0004176237210273544,0.0 +2004,BruCap,23,F,0.0001966181675186787,0.0003777861730260674 +2004,BruCap,24,M,0.0008084074373484238,0.0 +2004,BruCap,24,F,0.0003833620854897451,0.0 +2004,BruCap,25,M,0.001360808709175739,0.0 +2004,BruCap,25,F,0.0001795009872554299,0.00032776138970829236 +2004,BruCap,26,M,0.001124859392575928,0.0013888888888888892 +2004,BruCap,26,F,0.0001781261132882081,0.0 +2004,BruCap,27,M,0.0003803727653100038,0.0009699321047526674 +2004,BruCap,27,F,0.0005322924059616749,0.0 +2004,BruCap,28,M,0.0007507507507507507,0.000315357931251971 +2004,BruCap,28,F,0.0001879345987596317,0.00030721966205837184 +2004,BruCap,29,M,0.0009372071227741332,0.0005770340450086555 +2004,BruCap,29,F,0.0007577192650123129,0.0 +2004,BruCap,30,M,0.001095490231878766,0.0008486562942008486 +2004,BruCap,30,F,0.0005592841163310962,0.0 +2004,BruCap,31,M,0.0003629105425512611,0.001126760563380282 +2004,BruCap,31,F,0.0003793626707132018,0.0 +2004,BruCap,32,M,0.0012865282117257859,0.0005648121999435187 +2004,BruCap,32,F,0.0003852822192255828,0.0005955926146515784 +2004,BruCap,33,M,0.0005558643690939412,0.0013437248051599026 +2004,BruCap,33,F,0.0001940993788819876,0.0003089280197713933 +2004,BruCap,34,M,0.001337920489296636,0.001997146932952925 +2004,BruCap,34,F,0.0006050826946349334,0.0003125 +2004,BruCap,35,M,0.001570783428234832,0.0002896871378910777 +2004,BruCap,35,F,0.000843348091924942,0.0003295978905735003 +2004,BruCap,36,M,0.0004040404040404041,0.0009079903147699758 +2004,BruCap,36,F,0.0008550662676357418,0.0006963788300835657 +2004,BruCap,37,M,0.0012113870381586919,0.0 +2004,BruCap,37,F,0.0008331597583836701,0.0003660322108345535 +2004,BruCap,38,M,0.0007777561734396268,0.0012734797835084366 +2004,BruCap,38,F,0.0004133939644481192,0.001090116279069767 +2004,BruCap,39,M,0.0011794770984863382,0.002027027027027027 +2004,BruCap,39,F,0.0012330456226880401,0.0011342155009451801 +2004,BruCap,40,M,0.001408167370750352,0.0011316484345529991 +2004,BruCap,40,F,0.0004175365344467641,0.0004144218814753419 +2004,BruCap,41,M,0.003199658703071673,0.0007607455306200076 +2004,BruCap,41,F,0.0008479966080135677,0.00043327556325823216 +2004,BruCap,42,M,0.002166847237269772,0.002044153720359771 +2004,BruCap,42,F,0.0008460236886632825,0.0009372071227741332 +2004,BruCap,43,M,0.002518363064008395,0.00258732212160414 +2004,BruCap,43,F,0.0020383204239706482,0.0009229349330872172 +2004,BruCap,44,M,0.00255047821466525,0.002344116268166902 +2004,BruCap,44,F,0.002072538860103627,0.0004997501249375311 +2004,BruCap,45,M,0.003991130820399113,0.001933301111648139 +2004,BruCap,45,F,0.001455604075691412,0.002220988339811216 +2004,BruCap,46,M,0.004287971112615663,0.004253056884635833 +2004,BruCap,46,F,0.0023143277929728607,0.001088731627653783 +2004,BruCap,47,M,0.005051664753157291,0.002090956612650288 +2004,BruCap,47,F,0.002924587424274076,0.0 +2004,BruCap,48,M,0.004855491329479769,0.002666666666666667 +2004,BruCap,48,F,0.002733964248159832,0.002361275088547816 +2004,BruCap,49,M,0.006763059701492537,0.001813784764207981 +2004,BruCap,49,F,0.0030126963632451037,0.003054367745876604 +2004,BruCap,50,M,0.00599354541263255,0.0050125313283208035 +2004,BruCap,50,F,0.003436426116838488,0.003274394237066143 +2004,BruCap,51,M,0.007872192637184533,0.002460024600246003 +2004,BruCap,51,F,0.004077253218884121,0.0006289308176100629 +2004,BruCap,52,M,0.008282582216808769,0.002142857142857143 +2004,BruCap,52,F,0.003858374943259192,0.002173913043478261 +2004,BruCap,53,M,0.008180466038671294,0.003846153846153847 +2004,BruCap,53,F,0.00392841553906591,0.002 +2004,BruCap,54,M,0.009213147410358566,0.0049751243781094535 +2004,BruCap,54,F,0.0054005400540054005,0.002223869532987398 +2004,BruCap,55,M,0.008020050125313283,0.006807351940095303 +2004,BruCap,55,F,0.004706409681757061,0.0029607698001480392 +2004,BruCap,56,M,0.008252063015753939,0.006433166547533953 +2004,BruCap,56,F,0.005882352941176471,0.004548900682335102 +2004,BruCap,57,M,0.01072854291417166,0.008540372670807454 +2004,BruCap,57,F,0.006075607560756075,0.0023771790808240893 +2004,BruCap,58,M,0.01138686131386862,0.01068566340160285 +2004,BruCap,58,F,0.0066428206438426144,0.005371530886302597 +2004,BruCap,59,M,0.01082004555808656,0.007957559681697613 +2004,BruCap,59,F,0.007870142646335464,0.0035587188612099642 +2004,BruCap,60,M,0.01578790586833482,0.008653846153846154 +2004,BruCap,60,F,0.008051948051948052,0.005934718100890208 +2004,BruCap,61,M,0.01527494908350306,0.009930486593843098 +2004,BruCap,61,F,0.004495055439017081,0.004145077720207254 +2004,BruCap,62,M,0.012459807073954993,0.014302741358760432 +2004,BruCap,62,F,0.006816632583503749,0.0035545023696682467 +2004,BruCap,63,M,0.019318580962416586,0.008008008008008008 +2004,BruCap,63,F,0.010265700483091791,0.005576208178438661 +2004,BruCap,64,M,0.01913709116214335,0.009922822491730982 +2004,BruCap,64,F,0.009929078014184398,0.00641025641025641 +2004,BruCap,65,M,0.021085378499827168,0.02106430155210643 +2004,BruCap,65,F,0.01191514094739901,0.007945516458569807 +2004,BruCap,66,M,0.0175374497625137,0.02033036848792885 +2004,BruCap,66,F,0.01016138673042439,0.007585335018963337 +2004,BruCap,67,M,0.02444444444444445,0.030013642564802188 +2004,BruCap,67,F,0.011373840167614491,0.00477326968973747 +2004,BruCap,68,M,0.0258751902587519,0.02670623145400594 +2004,BruCap,68,F,0.0108187134502924,0.010975609756097559 +2004,BruCap,69,M,0.02989536621823617,0.03353658536585366 +2004,BruCap,69,F,0.0144542772861357,0.014824797843665768 +2004,BruCap,70,M,0.02306489444878812,0.02782324058919804 +2004,BruCap,70,F,0.01595298068849706,0.01388888888888889 +2004,BruCap,71,M,0.03367003367003367,0.02229299363057325 +2004,BruCap,71,F,0.0198019801980198,0.01656626506024097 +2004,BruCap,72,M,0.03903903903903904,0.02783300198807157 +2004,BruCap,72,F,0.01706211676886164,0.02551020408163266 +2004,BruCap,73,M,0.04122076892588189,0.03780068728522337 +2004,BruCap,73,F,0.02227722772277228,0.01711840228245364 +2004,BruCap,74,M,0.04302854778651221,0.0292887029288703 +2004,BruCap,74,F,0.01890701890701891,0.022403258655804482 +2004,BruCap,75,M,0.05114345114345115,0.03640776699029126 +2004,BruCap,75,F,0.02639218791237794,0.024482109227871945 +2004,BruCap,76,M,0.052267818574514034,0.04788732394366197 +2004,BruCap,76,F,0.03536553180258644,0.02745995423340961 +2004,BruCap,77,M,0.06037221970040853,0.04790419161676647 +2004,BruCap,77,F,0.03701786176546725,0.027638190954773868 +2004,BruCap,78,M,0.06847426470588236,0.05166051660516605 +2004,BruCap,78,F,0.041449426485922834,0.03723404255319149 +2004,BruCap,79,M,0.06710158434296365,0.06666666666666668 +2004,BruCap,79,F,0.04226804123711341,0.043478260869565216 +2004,BruCap,80,M,0.06953814218993254,0.06481481481481481 +2004,BruCap,80,F,0.04587869362363919,0.05696202531645569 +2004,BruCap,81,M,0.07666290868094701,0.07441860465116279 +2004,BruCap,81,F,0.05173807599029912,0.05597014925373135 +2004,BruCap,82,M,0.09194776931447228,0.09523809523809523 +2004,BruCap,82,F,0.05931495405179615,0.05106382978723404 +2004,BruCap,83,M,0.1034259857789269,0.1085271317829457 +2004,BruCap,83,F,0.07590569292696953,0.06909090909090909 +2004,BruCap,84,M,0.1027777777777778,0.1136363636363637 +2004,BruCap,84,F,0.07629661380197171,0.07643312101910828 +2004,BruCap,85,M,0.1256038647342995,0.09859154929577464 +2004,BruCap,85,F,0.07816377171215881,0.06451612903225806 +2004,BruCap,86,M,0.1311475409836066,0.1206896551724138 +2004,BruCap,86,F,0.100418410041841,0.08264462809917356 +2004,BruCap,87,M,0.18,0.1111111111111111 +2004,BruCap,87,F,0.108408617095205,0.06896551724137931 +2004,BruCap,88,M,0.1754385964912281,0.075 +2004,BruCap,88,F,0.1343187660668381,0.1063829787234043 +2004,BruCap,89,M,0.2191780821917808,0.1081081081081081 +2004,BruCap,89,F,0.1431226765799257,0.15 +2004,BruCap,90,M,0.2142857142857143,0.1304347826086957 +2004,BruCap,90,F,0.1444610778443114,0.2183908045977012 +2004,BruCap,91,M,0.1938775510204082,0.2424242424242425 +2004,BruCap,91,F,0.17101710171017098,0.16 +2004,BruCap,92,M,0.222707423580786,0.2 +2004,BruCap,92,F,0.21864594894561604,0.1923076923076923 +2004,BruCap,93,M,0.2662721893491125,0.2142857142857143 +2004,BruCap,93,F,0.1897233201581028,0.2631578947368421 +2004,BruCap,94,M,0.3189655172413794,0.25 +2004,BruCap,94,F,0.20272904483430804,0.175 +2004,BruCap,95,M,0.3896103896103897,0.4444444444444444 +2004,BruCap,95,F,0.2482915717539864,0.2758620689655173 +2004,BruCap,96,M,0.3414634146341464,0.2 +2004,BruCap,96,F,0.2814814814814815,0.4166666666666667 +2004,BruCap,97,M,0.3076923076923077,0.6666666666666666 +2004,BruCap,97,F,0.2808510638297873,0.2727272727272727 +2004,BruCap,98,M,0.2857142857142857,0.0 +2004,BruCap,98,F,0.3506493506493507,0.4444444444444444 +2004,BruCap,99,M,0.3125,0.0 +2004,BruCap,99,F,0.2870370370370371,0.0 +2004,BruCap,100,M,0.4444444444444444,0.0 +2004,BruCap,100,F,0.3823529411764706,0.0 +2004,BruCap,101,M,0.5,0.0 +2004,BruCap,101,F,0.3421052631578948,0.25 +2004,BruCap,102,M,1.0,0.0 +2004,BruCap,102,F,0.3157894736842105,0.0 +2004,BruCap,103,M,0.0,0.0 +2004,BruCap,103,F,0.2857142857142857,0.3333333333333333 +2004,BruCap,104,M,0.0,0.0 +2004,BruCap,104,F,0.5,0.0 +2004,BruCap,105,M,0.0,0.0 +2004,BruCap,105,F,0.25,0.0 +2004,BruCap,106,M,0.0,0.0 +2004,BruCap,106,F,0.0,0.0 +2004,BruCap,107,M,0.0,0.0 +2004,BruCap,107,F,0.0,0.0 +2004,BruCap,108,M,0.0,0.0 +2004,BruCap,108,F,0.0,1.0 +2004,BruCap,109,M,0.0,0.0 +2004,BruCap,109,F,0.0,0.0 +2004,BruCap,110,M,0.0,0.0 +2004,BruCap,110,F,0.0,0.0 +2004,BruCap,111,M,0.0,0.0 +2004,BruCap,111,F,0.0,0.0 +2004,BruCap,112,M,0.0,0.0 +2004,BruCap,112,F,0.0,0.0 +2004,BruCap,113,M,0.0,0.0 +2004,BruCap,113,F,0.0,0.0 +2004,BruCap,114,M,0.0,0.0 +2004,BruCap,114,F,0.0,0.0 +2004,BruCap,115,M,0.0,0.0 +2004,BruCap,115,F,0.0,0.0 +2004,BruCap,116,M,0.0,0.0 +2004,BruCap,116,F,0.0,0.0 +2004,BruCap,117,M,0.0,0.0 +2004,BruCap,117,F,0.0,0.0 +2004,BruCap,118,M,0.0,0.0 +2004,BruCap,118,F,0.0,0.0 +2004,BruCap,119,M,0.0,0.0 +2004,BruCap,119,F,0.0,0.0 +2004,BruCap,120,M,0.0,0.0 +2004,BruCap,120,F,0.0,0.0 +2004,Fla,0,M,0.0005475139444957738,0.0006583278472679394 +2004,Fla,0,F,0.0007893226176808268,0.0007107320540156361 +2004,Fla,1,M,0.0003387763398604242,0.0 +2004,Fla,1,F,0.00021467673262012948,0.002166064981949459 +2004,Fla,2,M,0.0002011128242944292,0.0006770480704129992 +2004,Fla,2,F,0.00010489510489510492,0.0 +2004,Fla,3,M,0.0001302677001237543,0.0 +2004,Fla,3,F,0.0001355886241144368,0.0006939625260235947 +2004,Fla,4,M,9.759588795992062e-05,0.0 +2004,Fla,4,F,6.72246311048368e-05,0.0 +2004,Fla,5,M,0.0,0.0 +2004,Fla,5,F,3.320935175345377e-05,0.0 +2004,Fla,6,M,9.272137227630972e-05,0.000708215297450425 +2004,Fla,6,F,0.00012882862572063508,0.0 +2004,Fla,7,M,0.0001232247928283171,0.0 +2004,Fla,7,F,6.402458544080927e-05,0.0 +2004,Fla,8,M,0.000153275497378989,0.0007042253521126763 +2004,Fla,8,F,3.199897603276695e-05,0.0 +2004,Fla,9,M,3.025077895755816e-05,0.001342281879194631 +2004,Fla,9,F,6.353845665088795e-05,0.0 +2004,Fla,10,M,2.9064698017787605e-05,0.0 +2004,Fla,10,F,8.983380745620602e-05,0.001490312965722802 +2004,Fla,11,M,0.0001399305944251651,0.0 +2004,Fla,11,F,0.000116795141322121,0.0 +2004,Fla,12,M,8.26901874310915e-05,0.001415428167020524 +2004,Fla,12,F,2.906300860265055e-05,0.0 +2004,Fla,13,M,5.577244841048522e-05,0.0 +2004,Fla,13,F,0.0001168872914292394,0.0 +2004,Fla,14,M,0.0002596428468395696,0.0 +2004,Fla,14,F,0.0001817520901490367,0.0 +2004,Fla,15,M,0.00023365850809042597,0.0007451564828614009 +2004,Fla,15,F,0.0002137078308655167,0.0 +2004,Fla,16,M,0.0004711841446535324,0.0 +2004,Fla,16,F,0.000280365097660509,0.0 +2004,Fla,17,M,0.00044063216027260437,0.002281368821292776 +2004,Fla,17,F,0.00031167212092878286,0.00072992700729927 +2004,Fla,18,M,0.0008781758168549192,0.0 +2004,Fla,18,F,0.0001582128278960858,0.0006451612903225806 +2004,Fla,19,M,0.0012142032161577866,0.000727802037845706 +2004,Fla,19,F,0.00015519756650215718,0.0006317119393556537 +2004,Fla,20,M,0.0010979168472450948,0.0 +2004,Fla,20,F,0.0002402474548785249,0.0010928961748633882 +2004,Fla,21,M,0.001155157354971403,0.001167542323409224 +2004,Fla,21,F,0.00011880717595342758,0.0004940711462450593 +2004,Fla,22,M,0.001065719360568384,0.0 +2004,Fla,22,F,0.0003766587471750594,0.0017376194613379669 +2004,Fla,23,M,0.0009996112622868882,0.001904761904761905 +2004,Fla,23,F,0.000344778049130872,0.0003889537145079736 +2004,Fla,24,M,0.0008541121366579419,0.0008896797153024912 +2004,Fla,24,F,0.0002906723250879284,0.0003909304143862393 +2004,Fla,25,M,0.0008798319804734062,0.0004063388866314506 +2004,Fla,25,F,0.0003514217940082585,0.0007220216606498197 +2004,Fla,26,M,0.001019219569015725,0.0003943217665615142 +2004,Fla,26,F,0.0004755677089525621,0.0 +2004,Fla,27,M,0.0009174040424965226,0.001162790697674419 +2004,Fla,27,F,0.00030760712418099616,0.0 +2004,Fla,28,M,0.0008820756151717005,0.0 +2004,Fla,28,F,0.000189065700330865,0.0 +2004,Fla,29,M,0.0008487473659564504,0.0010316368638239339 +2004,Fla,29,F,0.00048009121733129297,0.0003497726477789437 +2004,Fla,30,M,0.000786561042755211,0.001383125864453666 +2004,Fla,30,F,0.0004643064422518863,0.001040582726326743 +2004,Fla,31,M,0.001130065113275575,0.001280409731113957 +2004,Fla,31,F,0.0001917545541706616,0.0009730781706130393 +2004,Fla,32,M,0.0008740135215033032,0.00032626427406199016 +2004,Fla,32,F,0.0005982416896426156,0.0 +2004,Fla,33,M,0.0008951661030435649,0.001247660636306925 +2004,Fla,33,F,0.0002805478334055957,0.0006082725060827251 +2004,Fla,34,M,0.000817357705454005,0.0006129328838492185 +2004,Fla,34,F,0.0005326029064901468,0.0 +2004,Fla,35,M,0.0006855352071295661,0.0009375 +2004,Fla,35,F,0.0005778313737312832,0.0006611570247933885 +2004,Fla,36,M,0.0006840590649620227,0.0003341129301703976 +2004,Fla,36,F,0.0005666001527356932,0.0010166045408336161 +2004,Fla,37,M,0.0009623536420502717,0.0 +2004,Fla,37,F,0.0009399158775289613,0.0003299241174529858 +2004,Fla,38,M,0.0013484536994053536,0.001580278128950695 +2004,Fla,38,F,0.0006154126683837437,0.0003491620111731844 +2004,Fla,39,M,0.001168323561899907,0.0015192950470981474 +2004,Fla,39,F,0.001192437776428757,0.001076426264800861 +2004,Fla,40,M,0.001430279224660576,0.002968337730870712 +2004,Fla,40,F,0.0009193389515158148,0.0 +2004,Fla,41,M,0.001751881650661822,0.002353732347007398 +2004,Fla,41,F,0.001111135803017845,0.0003976143141153082 +2004,Fla,42,M,0.0017649365930186948,0.0003531073446327684 +2004,Fla,42,F,0.0010366579910891527,0.0004363001745200698 +2004,Fla,43,M,0.002111439557264464,0.0007145409074669522 +2004,Fla,43,F,0.00108535895986433,0.001727861771058316 +2004,Fla,44,M,0.0018353835733170192,0.002295332823259373 +2004,Fla,44,F,0.001425516749821811,0.0004595588235294118 +2004,Fla,45,M,0.002317806997994206,0.0003749531308586427 +2004,Fla,45,F,0.001373406276466684,0.00102827763496144 +2004,Fla,46,M,0.002717699014834107,0.003642250101173614 +2004,Fla,46,F,0.001513704850841853,0.001064962726304579 +2004,Fla,47,M,0.002662182990051843,0.004473363155754372 +2004,Fla,47,F,0.001555173307570867,0.002168021680216802 +2004,Fla,48,M,0.0036027494666982704,0.004212299915754002 +2004,Fla,48,F,0.002192355352206653,0.0005737234652897303 +2004,Fla,49,M,0.003432604912009283,0.0017398869073510222 +2004,Fla,49,F,0.002258444619010212,0.0011848341232227491 +2004,Fla,50,M,0.004458093917178522,0.001425178147268409 +2004,Fla,50,F,0.0028412694385956012,0.001246882793017457 +2004,Fla,51,M,0.004495777446597119,0.003269500233535731 +2004,Fla,51,F,0.002657671470918941,0.003162555344718533 +2004,Fla,52,M,0.0047985395749119844,0.007170172084130019 +2004,Fla,52,F,0.0029242097987611988,0.004005340453938585 +2004,Fla,53,M,0.0048686264652184254,0.005859375 +2004,Fla,53,F,0.003413879554061983,0.001291155584247902 +2004,Fla,54,M,0.005678216775829283,0.005938784833257195 +2004,Fla,54,F,0.003929061600150704,0.005060088551549652 +2004,Fla,55,M,0.006567100942696747,0.00430622009569378 +2004,Fla,55,F,0.003302879364994806,0.0006501950585175553 +2004,Fla,56,M,0.006839578360110506,0.0033964095099466283 +2004,Fla,56,F,0.003804435810263882,0.003926701570680628 +2004,Fla,57,M,0.007939211319271585,0.00621414913957935 +2004,Fla,57,F,0.004198442856004039,0.002130681818181818 +2004,Fla,58,M,0.008030933967876264,0.005793742757821553 +2004,Fla,58,F,0.004784971644612476,0.0046801872074883 +2004,Fla,59,M,0.008976552883605032,0.010125074449076827 +2004,Fla,59,F,0.0049434187016081,0.004411764705882353 +2004,Fla,60,M,0.0102591622210297,0.008567931456548347 +2004,Fla,60,F,0.005625660471187914,0.004058441558441558 +2004,Fla,61,M,0.01075503233776615,0.009395973154362415 +2004,Fla,61,F,0.0045,0.0051369863013698645 +2004,Fla,62,M,0.01190960084545972,0.0105708245243129 +2004,Fla,62,F,0.005756962813132099,0.005607476635514018 +2004,Fla,63,M,0.01479563528759016,0.01577503429355281 +2004,Fla,63,F,0.007082003996774533,0.00474308300395257 +2004,Fla,64,M,0.0140696686491079,0.013678905687545 +2004,Fla,64,F,0.00697094912153424,0.00897308075772682 +2004,Fla,65,M,0.014883813438525541,0.01654135338345865 +2004,Fla,65,F,0.007298818581060185,0.009784735812133072 +2004,Fla,66,M,0.015818194377288108,0.01449275362318841 +2004,Fla,66,F,0.007842128945169377,0.0010427528675703858 +2004,Fla,67,M,0.01686633609613088,0.023049645390070917 +2004,Fla,67,F,0.008939722605666207,0.010764262648008607 +2004,Fla,68,M,0.02005308168681805,0.01471941122355106 +2004,Fla,68,F,0.01035155604061249,0.009937888198757764 +2004,Fla,69,M,0.021550122612766592,0.026104417670682733 +2004,Fla,69,F,0.009963207762185393,0.01046511627906977 +2004,Fla,70,M,0.025778651345630482,0.02574257425742574 +2004,Fla,70,F,0.01219993423216048,0.01608910891089109 +2004,Fla,71,M,0.02672926210578125,0.02669632925472748 +2004,Fla,71,F,0.014243474390360219,0.02068965517241379 +2004,Fla,72,M,0.03124027388733272,0.029103608847497086 +2004,Fla,72,F,0.0161295494628828,0.01916932907348243 +2004,Fla,73,M,0.037224153261660335,0.04089219330855018 +2004,Fla,73,F,0.0177435663263642,0.01754385964912281 +2004,Fla,74,M,0.039478466291113935,0.04674220963172804 +2004,Fla,74,F,0.01938793560941093,0.015126050420168069 +2004,Fla,75,M,0.04433473694400078,0.04024767801857585 +2004,Fla,75,F,0.023090782071552008,0.01990049751243781 +2004,Fla,76,M,0.047567004944054116,0.048300536672629686 +2004,Fla,76,F,0.0276326483223035,0.020332717190388167 +2004,Fla,77,M,0.0555772775512484,0.08333333333333333 +2004,Fla,77,F,0.031764614063841415,0.02772643253234751 +2004,Fla,78,M,0.060574533263973177,0.04208416833667335 +2004,Fla,78,F,0.03619836052268485,0.03340292275574113 +2004,Fla,79,M,0.06984895800140208,0.06896551724137931 +2004,Fla,79,F,0.03910327714554633,0.03579418344519016 +2004,Fla,80,M,0.07924921793534932,0.09774436090225563 +2004,Fla,80,F,0.045782279824833017,0.05080831408775981 +2004,Fla,81,M,0.08323433911459571,0.07917888563049852 +2004,Fla,81,F,0.05450109782873872,0.05397727272727273 +2004,Fla,82,M,0.09636554254761487,0.06643356643356642 +2004,Fla,82,F,0.06508237951034235,0.06606606606606606 +2004,Fla,83,M,0.1068917018284107,0.1019607843137255 +2004,Fla,83,F,0.07078254030672435,0.07142857142857142 +2004,Fla,84,M,0.1155966036049456,0.08588957055214724 +2004,Fla,84,F,0.07896404245208301,0.04 +2004,Fla,85,M,0.1394472361809045,0.128 +2004,Fla,85,F,0.0910091743119266,0.05960264900662252 +2004,Fla,86,M,0.1483063777845591,0.2105263157894737 +2004,Fla,86,F,0.106365389914577,0.1111111111111111 +2004,Fla,87,M,0.15927850810149802,0.1829268292682927 +2004,Fla,87,F,0.1155513410999729,0.08928571428571429 +2004,Fla,88,M,0.1768072289156627,0.1690140845070423 +2004,Fla,88,F,0.1315075571631572,0.1724137931034483 +2004,Fla,89,M,0.1862579993263725,0.18032786885245894 +2004,Fla,89,F,0.1517687333586915,0.1071428571428571 +2004,Fla,90,M,0.2116402116402116,0.2727272727272727 +2004,Fla,90,F,0.1629113548769641,0.2307692307692308 +2004,Fla,91,M,0.2362606232294618,0.1538461538461539 +2004,Fla,91,F,0.1812984138694209,0.16 +2004,Fla,92,M,0.2709984152139462,0.2692307692307692 +2004,Fla,92,F,0.2138030888030888,0.3518518518518519 +2004,Fla,93,M,0.2626373626373627,0.1666666666666667 +2004,Fla,93,F,0.2260380892912894,0.15 +2004,Fla,94,M,0.2892976588628763,0.3636363636363637 +2004,Fla,94,F,0.2536231884057971,0.125 +2004,Fla,95,M,0.3160493827160494,0.4615384615384616 +2004,Fla,95,F,0.260096930533118,0.1904761904761905 +2004,Fla,96,M,0.3136531365313654,0.3333333333333333 +2004,Fla,96,F,0.2783346183500386,0.2666666666666667 +2004,Fla,97,M,0.355421686746988,0.3333333333333333 +2004,Fla,97,F,0.3050058207217695,0.3 +2004,Fla,98,M,0.3777777777777778,0.3333333333333333 +2004,Fla,98,F,0.3140916808149406,0.08333333333333333 +2004,Fla,99,M,0.2615384615384616,0.3333333333333333 +2004,Fla,99,F,0.2930107526881721,0.6 +2004,Fla,100,M,0.5128205128205128,0.0 +2004,Fla,100,F,0.3333333333333333,0.2857142857142857 +2004,Fla,101,M,0.4090909090909091,0.0 +2004,Fla,101,F,0.3546099290780142,0.0 +2004,Fla,102,M,0.8571428571428571,0.0 +2004,Fla,102,F,0.4235294117647059,0.5 +2004,Fla,103,M,0.4,0.0 +2004,Fla,103,F,0.4054054054054055,0.0 +2004,Fla,104,M,0.3333333333333333,0.0 +2004,Fla,104,F,0.4074074074074074,0.5 +2004,Fla,105,M,0.0,0.0 +2004,Fla,105,F,0.375,0.0 +2004,Fla,106,M,0.0,0.0 +2004,Fla,106,F,0.6,1.0 +2004,Fla,107,M,0.0,0.0 +2004,Fla,107,F,0.5,0.0 +2004,Fla,108,M,0.0,0.0 +2004,Fla,108,F,1.0,0.0 +2004,Fla,109,M,0.0,0.0 +2004,Fla,109,F,0.0,0.0 +2004,Fla,110,M,0.0,0.0 +2004,Fla,110,F,0.0,0.0 +2004,Fla,111,M,0.0,0.0 +2004,Fla,111,F,0.0,0.0 +2004,Fla,112,M,0.0,0.0 +2004,Fla,112,F,0.0,0.0 +2004,Fla,113,M,0.0,0.0 +2004,Fla,113,F,0.0,0.0 +2004,Fla,114,M,0.0,0.0 +2004,Fla,114,F,0.0,0.0 +2004,Fla,115,M,0.0,0.0 +2004,Fla,115,F,0.0,0.0 +2004,Fla,116,M,0.0,0.0 +2004,Fla,116,F,0.0,0.0 +2004,Fla,117,M,0.0,0.0 +2004,Fla,117,F,0.0,0.0 +2004,Fla,118,M,0.0,0.0 +2004,Fla,118,F,0.0,0.0 +2004,Fla,119,M,0.0,0.0 +2004,Fla,119,F,0.0,0.0 +2004,Fla,120,M,0.0,0.0 +2004,Fla,120,F,0.0,0.0 +2004,Wal,0,M,0.0006494912318683698,0.001360544217687075 +2004,Wal,0,F,0.0005618608832453085,0.001517450682852808 +2004,Wal,1,M,0.0003727568028116513,0.0012903225806451606 +2004,Wal,1,F,0.0001677852348993289,0.0 +2004,Wal,2,M,0.00015357051446122352,0.0 +2004,Wal,2,F,0.0002664393051262921,0.0 +2004,Wal,3,M,0.0003005259203606312,0.0 +2004,Wal,3,F,5.248241838983941e-05,0.0 +2004,Wal,4,M,0.0001537988311288834,0.0 +2004,Wal,4,F,0.0001613250161325016,0.0 +2004,Wal,5,M,0.0001023541453428864,0.0 +2004,Wal,5,F,0.0001072788714262726,0.0 +2004,Wal,6,M,5.103342689461598e-05,0.0 +2004,Wal,6,F,0.0001062078487600234,0.0 +2004,Wal,7,M,0.0002015316404675534,0.0 +2004,Wal,7,F,0.0,0.0 +2004,Wal,8,M,5.166089786640492e-05,0.0 +2004,Wal,8,F,0.0002141786249732277,0.0 +2004,Wal,9,M,0.000101993982355041,0.0 +2004,Wal,9,F,5.374032674118659e-05,0.0 +2004,Wal,10,M,9.810654370646524e-05,0.0 +2004,Wal,10,F,0.0001555774516413421,0.0 +2004,Wal,11,M,0.00014014762216201066,0.0 +2004,Wal,11,F,4.8830509302212015e-05,0.0 +2004,Wal,12,M,0.0002733609731650645,0.0 +2004,Wal,12,F,0.0001418238547723727,0.0 +2004,Wal,13,M,0.0001385233411829894,0.0 +2004,Wal,13,F,0.00019243721735783703,0.0 +2004,Wal,14,M,0.0005063524212852145,0.0 +2004,Wal,14,F,0.0001933674949241033,0.0 +2004,Wal,15,M,0.0005101330983629366,0.0 +2004,Wal,15,F,4.905086574778045e-05,0.0 +2004,Wal,16,M,0.0003853564547206166,0.0 +2004,Wal,16,F,0.0002018367140982945,0.0008665511265164642 +2004,Wal,17,M,0.0007233098659465715,0.0 +2004,Wal,17,F,0.0002037905033625433,0.0007733952049497294 +2004,Wal,18,M,0.0013045005268175214,0.0016570008285004142 +2004,Wal,18,F,0.0005244938634217978,0.0 +2004,Wal,19,M,0.0007636308099577457,0.0016406890894175561 +2004,Wal,19,F,5.298574683410163e-05,0.0 +2004,Wal,20,M,0.0008735419557062843,0.0007336757153338225 +2004,Wal,20,F,0.0002203007104697913,0.0 +2004,Wal,21,M,0.0009719664415797012,0.0006583278472679394 +2004,Wal,21,F,0.0002661131513119378,0.0 +2004,Wal,22,M,0.001433324801638086,0.0006138735420503376 +2004,Wal,22,F,0.00031420192710515286,0.001047668936616029 +2004,Wal,23,M,0.001698317122124441,0.0005577244841048521 +2004,Wal,23,F,0.0002654209576388152,0.0004796163069544365 +2004,Wal,24,M,0.0009522801819913238,0.0005165289256198346 +2004,Wal,24,F,0.00028091465812686106,0.0 +2004,Wal,25,M,0.001151126459463904,0.0009828009828009828 +2004,Wal,25,F,0.000400297363755933,0.0004761904761904762 +2004,Wal,26,M,0.001533070521243978,0.0005017561465127947 +2004,Wal,26,F,0.0005144326950557302,0.0004653327128897162 +2004,Wal,27,M,0.0011427327637808134,0.0009315323707498836 +2004,Wal,27,F,0.0002795951462282616,0.0009699321047526674 +2004,Wal,28,M,0.001681766397222373,0.0004533091568449684 +2004,Wal,28,F,0.000275846849828975,0.0 +2004,Wal,29,M,0.001567725752508361,0.0008136696501220504 +2004,Wal,29,F,0.0005351600128438404,0.0004063388866314506 +2004,Wal,30,M,0.001253887049854549,0.0018301610541727675 +2004,Wal,30,F,0.0006109979633401223,0.0 +2004,Wal,31,M,0.0013001396446284974,0.001749475157452764 +2004,Wal,31,F,0.0006838608831574832,0.0 +2004,Wal,32,M,0.0012289076901262,0.001392272885485555 +2004,Wal,32,F,0.0005697194131890044,0.0007476635514018691 +2004,Wal,33,M,0.001299701550014441,0.001049317943336831 +2004,Wal,33,F,0.00038973059872363233,0.0007209805335255948 +2004,Wal,34,M,0.00187788906009245,0.00066711140760507 +2004,Wal,34,F,0.0006782617121263505,0.0010552233556102714 +2004,Wal,35,M,0.0014241516475961302,0.001005361930294906 +2004,Wal,35,F,0.0009714868606402095,0.0 +2004,Wal,36,M,0.002018163471241171,0.001625487646293888 +2004,Wal,36,F,0.0004302514580743857,0.001451905626134301 +2004,Wal,37,M,0.001550606146038906,0.0008764241893076249 +2004,Wal,37,F,0.001401410753491849,0.000643707756678468 +2004,Wal,38,M,0.002173519289983699,0.0008678044547295343 +2004,Wal,38,F,0.0009896981420666696,0.0006772773450728076 +2004,Wal,39,M,0.003094625811794447,0.001211020284589767 +2004,Wal,39,F,0.0006928806513078123,0.002004008016032064 +2004,Wal,40,M,0.002311111111111111,0.001516990291262136 +2004,Wal,40,F,0.001657289894892931,0.0006913238852402348 +2004,Wal,41,M,0.0030902067711883674,0.0018726591760299628 +2004,Wal,41,F,0.0010661928031985778,0.0007415647015202076 +2004,Wal,42,M,0.0032339520666282732,0.0037890748342279757 +2004,Wal,42,F,0.001686194820355398,0.0 +2004,Wal,43,M,0.002904119381645966,0.001717721156598912 +2004,Wal,43,F,0.00176444640494045,0.0007535795026375283 +2004,Wal,44,M,0.0047201318074542465,0.0027881040892193307 +2004,Wal,44,F,0.0014506357197713118,0.00038431975403535736 +2004,Wal,45,M,0.0039051857233675423,0.004539951573849879 +2004,Wal,45,F,0.0019115474845772871,0.0027624309392265192 +2004,Wal,46,M,0.0044030637985598324,0.003433208489388265 +2004,Wal,46,F,0.002310700319943121,0.00207210940737671 +2004,Wal,47,M,0.005783880372425468,0.0030184123151222463 +2004,Wal,47,F,0.003138450502152081,0.000814000814000814 +2004,Wal,48,M,0.005432969546775961,0.003492063492063492 +2004,Wal,48,F,0.002931625473570269,0.002085940759282437 +2004,Wal,49,M,0.006319720400248959,0.004516129032258065 +2004,Wal,49,F,0.00336210813266697,0.002579535683576957 +2004,Wal,50,M,0.006938421509106678,0.002346630908481395 +2004,Wal,50,F,0.003280961182994455,0.0046360686138154856 +2004,Wal,51,M,0.006815968841285297,0.0037813681677552414 +2004,Wal,51,F,0.004546519803140379,0.002323420074349443 +2004,Wal,52,M,0.0075995541594893095,0.005345687811831789 +2004,Wal,52,F,0.004060186290900407,0.004215456674473068 +2004,Wal,53,M,0.009256552664912793,0.007104795737122558 +2004,Wal,53,F,0.004792180679445815,0.004102096627164996 +2004,Wal,54,M,0.008685411452966288,0.00662739322533137 +2004,Wal,54,F,0.004136750511150207,0.0009940357852882703 +2004,Wal,55,M,0.009461285962541031,0.007272727272727274 +2004,Wal,55,F,0.00433059983414724,0.001851851851851852 +2004,Wal,56,M,0.01088012434427822,0.005895357406042741 +2004,Wal,56,F,0.0055457172150247,0.004527162977867203 +2004,Wal,57,M,0.01073818799320747,0.01262825572217838 +2004,Wal,57,F,0.005121699088431539,0.001618996222342148 +2004,Wal,58,M,0.012368916375369729,0.01443504230960677 +2004,Wal,58,F,0.005337423312883435,0.005066497783407221 +2004,Wal,59,M,0.01204900832600014,0.01540755467196819 +2004,Wal,59,F,0.006022962544701675,0.0056568196103079825 +2004,Wal,60,M,0.014789450677546268,0.01015801354401806 +2004,Wal,60,F,0.007660027975754345,0.004140786749482402 +2004,Wal,61,M,0.01582092064293529,0.01189060642092747 +2004,Wal,61,F,0.00770110560426992,0.0055286800276434 +2004,Wal,62,M,0.01580381471389646,0.011713933415536379 +2004,Wal,62,F,0.007934580195935553,0.01098901098901099 +2004,Wal,63,M,0.01934851824638746,0.01457883369330454 +2004,Wal,63,F,0.006968641114982578,0.002484472049689441 +2004,Wal,64,M,0.01739460691226738,0.01570680628272251 +2004,Wal,64,F,0.009039920818211807,0.004329004329004329 +2004,Wal,65,M,0.02347024308466052,0.01841269841269841 +2004,Wal,65,F,0.009573428850537285,0.005461165048543689 +2004,Wal,66,M,0.02158273381294964,0.021210230817217717 +2004,Wal,66,F,0.010275862068965521,0.009608785175017159 +2004,Wal,67,M,0.02382750230724054,0.02232435981615233 +2004,Wal,67,F,0.012185833968012193,0.01442307692307693 +2004,Wal,68,M,0.027108693775360442,0.02254641909814324 +2004,Wal,68,F,0.012824106517168893,0.007817589576547232 +2004,Wal,69,M,0.02949061662198392,0.025034770514603615 +2004,Wal,69,F,0.01382769606181794,0.01371652514696277 +2004,Wal,70,M,0.031171019376579606,0.02347762289068232 +2004,Wal,70,F,0.01498203511626331,0.009823182711198428 +2004,Wal,71,M,0.03565253190613421,0.03463203463203463 +2004,Wal,71,F,0.01722837022132797,0.0118632240055827 +2004,Wal,72,M,0.039588477366255134,0.03622047244094488 +2004,Wal,72,F,0.02198616600790514,0.01722949689869056 +2004,Wal,73,M,0.04485578992681877,0.0576923076923077 +2004,Wal,73,F,0.02198278531178401,0.020270270270270268 +2004,Wal,74,M,0.0472411186696901,0.05450236966824645 +2004,Wal,74,F,0.02376696458126449,0.022808267997148968 +2004,Wal,75,M,0.05662064170060594,0.048171275646743984 +2004,Wal,75,F,0.028403787171622882,0.02152190622598002 +2004,Wal,76,M,0.06185240008458447,0.06625980819529206 +2004,Wal,76,F,0.03099916966509826,0.03255109765329296 +2004,Wal,77,M,0.061151481274455,0.07822808671065032 +2004,Wal,77,F,0.03251802629718648,0.03495440729483283 +2004,Wal,78,M,0.06894923258559622,0.09711846318036288 +2004,Wal,78,F,0.04187968345122208,0.03793381759483455 +2004,Wal,79,M,0.0766061542423072,0.08786127167630058 +2004,Wal,79,F,0.04524284763805722,0.05030891438658429 +2004,Wal,80,M,0.08789790650989389,0.08774193548387096 +2004,Wal,80,F,0.052282481467030816,0.04957904583723106 +2004,Wal,81,M,0.09644268774703556,0.10906298003072197 +2004,Wal,81,F,0.05910359546872435,0.06095041322314049 +2004,Wal,82,M,0.1017605633802817,0.1050583657587549 +2004,Wal,82,F,0.0654356705241661,0.07169344870210136 +2004,Wal,83,M,0.1107550570799119,0.1081730769230769 +2004,Wal,83,F,0.0770292655991165,0.07298335467349552 +2004,Wal,84,M,0.13310366426558098,0.1186440677966102 +2004,Wal,84,F,0.08450704225352113,0.06736842105263158 +2004,Wal,85,M,0.14859228362878,0.1438848920863309 +2004,Wal,85,F,0.09877066553624417,0.07971014492753623 +2004,Wal,86,M,0.1337704918032787,0.1982758620689655 +2004,Wal,86,F,0.1170416467209191,0.1022727272727273 +2004,Wal,87,M,0.1837409120951752,0.2 +2004,Wal,87,F,0.1246882793017457,0.1220472440944882 +2004,Wal,88,M,0.1935018050541516,0.2115384615384615 +2004,Wal,88,F,0.1332707648991084,0.1721854304635762 +2004,Wal,89,M,0.1905781584582441,0.1237113402061856 +2004,Wal,89,F,0.1462857142857143,0.1753731343283582 +2004,Wal,90,M,0.2132075471698113,0.2307692307692308 +2004,Wal,90,F,0.1776520509193777,0.1612903225806452 +2004,Wal,91,M,0.2529488859764089,0.1587301587301587 +2004,Wal,91,F,0.1910304690174598,0.2155688622754491 +2004,Wal,92,M,0.2716297786720322,0.2647058823529412 +2004,Wal,92,F,0.1979695431472081,0.2411347517730497 +2004,Wal,93,M,0.2817258883248731,0.3181818181818182 +2004,Wal,93,F,0.2327188940092166,0.1530612244897959 +2004,Wal,94,M,0.2637795275590551,0.5454545454545454 +2004,Wal,94,F,0.2322274881516588,0.1547619047619048 +2004,Wal,95,M,0.3030303030303031,0.5294117647058824 +2004,Wal,95,F,0.2494866529774128,0.3142857142857143 +2004,Wal,96,M,0.3829787234042553,0.0 +2004,Wal,96,F,0.2763337893296854,0.2777777777777778 +2004,Wal,97,M,0.39130434782608703,1.0 +2004,Wal,97,F,0.3284518828451883,0.2916666666666667 +2004,Wal,98,M,0.4074074074074074,0.0 +2004,Wal,98,F,0.2893890675241158,0.25 +2004,Wal,99,M,0.3888888888888889,0.0 +2004,Wal,99,F,0.3128491620111732,0.2142857142857143 +2004,Wal,100,M,0.2307692307692308,0.0 +2004,Wal,100,F,0.3404255319148936,0.25 +2004,Wal,101,M,0.1666666666666667,0.0 +2004,Wal,101,F,0.4126984126984127,0.3333333333333333 +2004,Wal,102,M,0.3333333333333333,0.0 +2004,Wal,102,F,0.4523809523809524,0.5 +2004,Wal,103,M,0.3333333333333333,0.0 +2004,Wal,103,F,0.4736842105263158,0.5 +2004,Wal,104,M,1.0,0.0 +2004,Wal,104,F,0.3076923076923077,1.0 +2004,Wal,105,M,0.0,0.0 +2004,Wal,105,F,0.2857142857142857,0.0 +2004,Wal,106,M,0.0,0.0 +2004,Wal,106,F,0.8,0.0 +2004,Wal,107,M,0.0,0.0 +2004,Wal,107,F,0.0,0.0 +2004,Wal,108,M,0.0,0.0 +2004,Wal,108,F,0.5,0.0 +2004,Wal,109,M,0.0,0.0 +2004,Wal,109,F,0.0,0.0 +2004,Wal,110,M,0.0,0.0 +2004,Wal,110,F,0.0,0.0 +2004,Wal,111,M,0.0,0.0 +2004,Wal,111,F,0.0,0.0 +2004,Wal,112,M,0.0,0.0 +2004,Wal,112,F,0.0,0.0 +2004,Wal,113,M,0.0,0.0 +2004,Wal,113,F,0.0,0.0 +2004,Wal,114,M,0.0,0.0 +2004,Wal,114,F,0.0,0.0 +2004,Wal,115,M,0.0,0.0 +2004,Wal,115,F,0.0,0.0 +2004,Wal,116,M,0.0,0.0 +2004,Wal,116,F,0.0,0.0 +2004,Wal,117,M,0.0,0.0 +2004,Wal,117,F,0.0,0.0 +2004,Wal,118,M,0.0,0.0 +2004,Wal,118,F,0.0,0.0 +2004,Wal,119,M,0.0,0.0 +2004,Wal,119,F,0.0,0.0 +2004,Wal,120,M,0.0,0.0 +2004,Wal,120,F,0.0,0.0 +2005,BruCap,0,M,0.0004866969500324465,0.001249219237976265 +2005,BruCap,0,F,0.0003408316291751875,0.001328021248339974 +2005,BruCap,1,M,0.0005210142410559222,0.0006657789613848202 +2005,BruCap,1,F,0.001231960577261528,0.0 +2005,BruCap,2,M,0.0,0.0007968127490039841 +2005,BruCap,2,F,0.0001885014137606032,0.0 +2005,BruCap,3,M,0.00018244845831052726,0.0 +2005,BruCap,3,F,0.0005508630187293427,0.0 +2005,BruCap,4,M,0.0,0.0 +2005,BruCap,4,F,0.0,0.0 +2005,BruCap,5,M,0.0001948937828883259,0.0 +2005,BruCap,5,F,0.0,0.0 +2005,BruCap,6,M,0.0,0.0 +2005,BruCap,6,F,0.0,0.0 +2005,BruCap,7,M,0.0002007226013649137,0.0 +2005,BruCap,7,F,0.0,0.0 +2005,BruCap,8,M,0.0002129471890971039,0.0017421602787456448 +2005,BruCap,8,F,0.0,0.0009250693802035154 +2005,BruCap,9,M,0.0006433626420759168,0.0 +2005,BruCap,9,F,0.0002252759630547421,0.0 +2005,BruCap,10,M,0.0,0.0 +2005,BruCap,10,F,0.0,0.0 +2005,BruCap,11,M,0.0,0.0 +2005,BruCap,11,F,0.0,0.0 +2005,BruCap,12,M,0.0,0.0 +2005,BruCap,12,F,0.0,0.0 +2005,BruCap,13,M,0.0,0.0 +2005,BruCap,13,F,0.0,0.0 +2005,BruCap,14,M,0.0002155636990730761,0.0 +2005,BruCap,14,F,0.0,0.0009372071227741332 +2005,BruCap,15,M,0.0,0.0 +2005,BruCap,15,F,0.0,0.0 +2005,BruCap,16,M,0.0,0.0 +2005,BruCap,16,F,0.0,0.0 +2005,BruCap,17,M,0.0006850879196163508,0.0 +2005,BruCap,17,F,0.0,0.0 +2005,BruCap,18,M,0.0,0.0008417508417508418 +2005,BruCap,18,F,0.00023518344308560683,0.0 +2005,BruCap,19,M,0.000691085003455425,0.0 +2005,BruCap,19,F,0.00048590864917395527,0.0 +2005,BruCap,20,M,0.00022972662531587406,0.0 +2005,BruCap,20,F,0.0,0.0 +2005,BruCap,21,M,0.0009119927040583676,0.0 +2005,BruCap,21,F,0.0002236636099306643,0.0 +2005,BruCap,22,M,0.0006730984967466907,0.001660210293303819 +2005,BruCap,22,F,0.0,0.0008445945945945946 +2005,BruCap,23,M,0.0004151961801951424,0.00048828125 +2005,BruCap,23,F,0.0,0.0 +2005,BruCap,24,M,0.001186708860759494,0.0008798944126704797 +2005,BruCap,24,F,0.00036879955744053113,0.0 +2005,BruCap,25,M,0.001139817629179331,0.0007905138339920951 +2005,BruCap,25,F,0.0001820167455405897,0.0 +2005,BruCap,26,M,0.000556689552792726,0.0007117437722419928 +2005,BruCap,26,F,0.0001723246596587972,0.0 +2005,BruCap,27,M,0.0007339449541284404,0.0009715025906735752 +2005,BruCap,27,F,0.0003522987493394399,0.0 +2005,BruCap,28,M,0.0009386146048432514,0.0009165902841429883 +2005,BruCap,28,F,0.00035880875493362035,0.00029446407538280333 +2005,BruCap,29,M,0.000751597143930853,0.0003031221582297666 +2005,BruCap,29,F,0.0005743825387708214,0.0002932551319648094 +2005,BruCap,30,M,0.0005633802816901409,0.0002849002849002849 +2005,BruCap,30,F,0.0005764796310530362,0.0 +2005,BruCap,31,M,0.0003683241252302026,0.0005662514156285391 +2005,BruCap,31,F,0.0005647590361445782,0.0005859947260474656 +2005,BruCap,32,M,0.0009081002542680713,0.0 +2005,BruCap,32,F,0.000192975685063682,0.00029455081001472747 +2005,BruCap,33,M,0.0016759776536312847,0.0002857959416976279 +2005,BruCap,33,F,0.0007814026176987692,0.0006029544769369913 +2005,BruCap,34,M,0.001667902149740549,0.000546000546000546 +2005,BruCap,34,F,0.0005853658536585367,0.0 +2005,BruCap,35,M,0.001154734411085451,0.0017584994138335288 +2005,BruCap,35,F,0.0002037905033625433,0.0 +2005,BruCap,36,M,0.0013674545809728464,0.0008960573476702508 +2005,BruCap,36,F,0.001268767181222246,0.0009973404255319148 +2005,BruCap,37,M,0.001825557809330629,0.00220125786163522 +2005,BruCap,37,F,0.0006443298969072165,0.00036127167630057796 +2005,BruCap,38,M,0.001631654089333062,0.00032733224222585933 +2005,BruCap,38,F,0.0004161464835622138,0.0007527286413248022 +2005,BruCap,39,M,0.002136752136752137,0.0003342245989304813 +2005,BruCap,39,F,0.0002061855670103093,0.001145475372279496 +2005,BruCap,40,M,0.002357100766057749,0.0027624309392265192 +2005,BruCap,40,F,0.001021450459652707,0.0003935458480913026 +2005,BruCap,41,M,0.00364741641337386,0.001963864886095837 +2005,BruCap,41,F,0.001041883725776203,0.000423728813559322 +2005,BruCap,42,M,0.0019202048218476641,0.001196172248803828 +2005,BruCap,42,F,0.001890756302521009,0.0009086778736937756 +2005,BruCap,43,M,0.0039079461571862786,0.001685630004214075 +2005,BruCap,43,F,0.000843348091924942,0.0004819277108433735 +2005,BruCap,44,M,0.004349627174813586,0.00178491744756805 +2005,BruCap,44,F,0.002435559163791354,0.0 +2005,BruCap,45,M,0.002763605442176871,0.002872187649593107 +2005,BruCap,45,F,0.0024824162184526287,0.001011633788568538 +2005,BruCap,46,M,0.002896613190730838,0.0035228988424760954 +2005,BruCap,46,F,0.001861042183622829,0.001148765077541643 +2005,BruCap,47,M,0.0045136538027533285,0.001648351648351649 +2005,BruCap,47,F,0.001899134838573539,0.00281214848143982 +2005,BruCap,48,M,0.00345383375546857,0.003763440860215054 +2005,BruCap,48,F,0.00377200335289187,0.0005934718100890207 +2005,BruCap,49,M,0.004861111111111111,0.0028153153153153147 +2005,BruCap,49,F,0.003134796238244514,0.0006142506142506142 +2005,BruCap,50,M,0.006528328281650735,0.003142677561282213 +2005,BruCap,50,F,0.003218193520703712,0.0025252525252525268 +2005,BruCap,51,M,0.006270320483046911,0.0025756600128783 +2005,BruCap,51,F,0.003003003003003003,0.0027045300878972287 +2005,BruCap,52,M,0.006510113926993723,0.0032383419689119173 +2005,BruCap,52,F,0.004948364888123925,0.003217503217503218 +2005,BruCap,53,M,0.008126077320856932,0.009544787077826723 +2005,BruCap,53,F,0.0036546368204659657,0.005891016200294551 +2005,BruCap,54,M,0.005005005005005005,0.004005340453938585 +2005,BruCap,54,F,0.005285179475886369,0.0006697923643670463 +2005,BruCap,55,M,0.008318628686664987,0.00812407680945347 +2005,BruCap,55,F,0.003655471784327165,0.003009781790820166 +2005,BruCap,56,M,0.009338717819283191,0.002156721782890007 +2005,BruCap,56,F,0.0040779338468509285,0.001525553012967201 +2005,BruCap,57,M,0.010395537525354971,0.006671608598962194 +2005,BruCap,57,F,0.00572057205720572,0.00390015600624025 +2005,BruCap,58,M,0.01319796954314721,0.007936507936507936 +2005,BruCap,58,F,0.006172839506172839,0.002401921537229784 +2005,BruCap,59,M,0.01693907875185736,0.008506616257088847 +2005,BruCap,59,F,0.005415162454873646,0.004595588235294118 +2005,BruCap,60,M,0.01069982648930017,0.011090573012939 +2005,BruCap,60,F,0.009036144578313251,0.003663003663003664 +2005,BruCap,61,M,0.01745788667687596,0.01026694045174538 +2005,BruCap,61,F,0.009778012684989429,0.005076142131979695 +2005,BruCap,62,M,0.01587301587301587,0.01355578727841502 +2005,BruCap,62,F,0.007557436517533253,0.004324324324324325 +2005,BruCap,63,M,0.0196319018404908,0.007453416149068324 +2005,BruCap,63,F,0.01143451143451144,0.00847457627118644 +2005,BruCap,64,M,0.020647917408330368,0.01248699271592092 +2005,BruCap,64,F,0.013824884792626729,0.012104283054003729 +2005,BruCap,65,M,0.02139800285306705,0.009259259259259257 +2005,BruCap,65,F,0.01122948459545062,0.005747126436781609 +2005,BruCap,66,M,0.02484913028044019,0.012077294685990341 +2005,BruCap,66,F,0.0088339222614841,0.009280742459396751 +2005,BruCap,67,M,0.02616822429906542,0.021887824897400817 +2005,BruCap,67,F,0.014203686914475669,0.00648508430609598 +2005,BruCap,68,M,0.02601377199693956,0.01862464183381089 +2005,BruCap,68,F,0.01148730350665055,0.014457831325301209 +2005,BruCap,69,M,0.02752654345261502,0.02476780185758514 +2005,BruCap,69,F,0.01754385964912281,0.00620347394540943 +2005,BruCap,70,M,0.02923076923076923,0.02572347266881029 +2005,BruCap,70,F,0.01765938341813828,0.01508916323731139 +2005,BruCap,71,M,0.03495379670550422,0.02910958904109589 +2005,BruCap,71,F,0.01651010532308568,0.0143312101910828 +2005,BruCap,72,M,0.03725261932479628,0.03859060402684564 +2005,BruCap,72,F,0.02184598580010923,0.0107197549770291 +2005,BruCap,73,M,0.03985932004689332,0.029598308668076112 +2005,BruCap,73,F,0.02645935624659029,0.02397260273972603 +2005,BruCap,74,M,0.03927242662257132,0.031135531135531136 +2005,BruCap,74,F,0.02563451776649746,0.02186588921282799 +2005,BruCap,75,M,0.04774305555555555,0.046357615894039736 +2005,BruCap,75,F,0.02593965060878772,0.022821576763485483 +2005,BruCap,76,M,0.04916593503072871,0.03535353535353535 +2005,BruCap,76,F,0.023965141612200442,0.02111324376199616 +2005,BruCap,77,M,0.058688674919761576,0.05740181268882175 +2005,BruCap,77,F,0.0291128810766273,0.014084507042253518 +2005,BruCap,78,M,0.054642166344294016,0.03525641025641026 +2005,BruCap,78,F,0.03290183387270766,0.03617571059431525 +2005,BruCap,79,M,0.07832512315270937,0.0931174089068826 +2005,BruCap,79,F,0.03787047200878156,0.036414565826330535 +2005,BruCap,80,M,0.07746126936531735,0.05829596412556054 +2005,BruCap,80,F,0.04527081649151172,0.05089820359281437 +2005,BruCap,81,M,0.08537946428571429,0.08121827411167512 +2005,BruCap,81,F,0.05156889495225103,0.04377104377104378 +2005,BruCap,82,M,0.0855222968845449,0.04663212435233161 +2005,BruCap,82,F,0.06061468412066021,0.0642570281124498 +2005,BruCap,83,M,0.1036769138034961,0.125 +2005,BruCap,83,F,0.06662700773349196,0.04186046511627907 +2005,BruCap,84,M,0.1029731689630167,0.07758620689655173 +2005,BruCap,84,F,0.07646505797555625,0.0398406374501992 +2005,BruCap,85,M,0.1216216216216216,0.0641025641025641 +2005,BruCap,85,F,0.08061509785647716,0.0945945945945946 +2005,BruCap,86,M,0.1574074074074074,0.061538461538461535 +2005,BruCap,86,F,0.1050847457627119,0.1061946902654867 +2005,BruCap,87,M,0.1247357293868922,0.3 +2005,BruCap,87,F,0.1236306729264476,0.1081081081081081 +2005,BruCap,88,M,0.1666666666666667,0.1515151515151515 +2005,BruCap,88,F,0.1233307148468186,0.05952380952380953 +2005,BruCap,89,M,0.17339667458432298,0.0625 +2005,BruCap,89,F,0.1249059443190369,0.125 +2005,BruCap,90,M,0.1806615776081425,0.0625 +2005,BruCap,90,F,0.1588235294117647,0.1162790697674419 +2005,BruCap,91,M,0.2523659305993691,0.1176470588235294 +2005,BruCap,91,F,0.1742222222222222,0.164179104477612 +2005,BruCap,92,M,0.2447257383966245,0.2800000000000001 +2005,BruCap,92,F,0.1766004415011038,0.1147540983606558 +2005,BruCap,93,M,0.2727272727272727,0.09090909090909093 +2005,BruCap,93,F,0.2302158273381295,0.1707317073170732 +2005,BruCap,94,M,0.2416666666666667,0.2727272727272727 +2005,BruCap,94,F,0.2245901639344263,0.2195121951219512 +2005,BruCap,95,M,0.35897435897435903,0.1666666666666667 +2005,BruCap,95,F,0.2531328320802005,0.1612903225806452 +2005,BruCap,96,M,0.3555555555555556,0.0 +2005,BruCap,96,F,0.3159509202453988,0.2380952380952381 +2005,BruCap,97,M,0.4814814814814815,0.0 +2005,BruCap,97,F,0.3036649214659686,0.7142857142857143 +2005,BruCap,98,M,0.3333333333333333,0.0 +2005,BruCap,98,F,0.2727272727272727,0.2222222222222222 +2005,BruCap,99,M,0.32,1.0 +2005,BruCap,99,F,0.26,0.0 +2005,BruCap,100,M,0.2727272727272727,0.3333333333333333 +2005,BruCap,100,F,0.32,0.25 +2005,BruCap,101,M,0.75,0.0 +2005,BruCap,101,F,0.325,0.5 +2005,BruCap,102,M,1.0,1.0 +2005,BruCap,102,F,0.5,0.1666666666666667 +2005,BruCap,103,M,0.0,0.0 +2005,BruCap,103,F,0.3636363636363637,0.5 +2005,BruCap,104,M,0.0,0.5 +2005,BruCap,104,F,0.6,0.5 +2005,BruCap,105,M,0.0,0.0 +2005,BruCap,105,F,0.6666666666666666,0.0 +2005,BruCap,106,M,0.0,0.0 +2005,BruCap,106,F,0.0,0.0 +2005,BruCap,107,M,0.0,0.0 +2005,BruCap,107,F,1.0,0.0 +2005,BruCap,108,M,0.0,0.0 +2005,BruCap,108,F,0.0,0.0 +2005,BruCap,109,M,0.0,0.0 +2005,BruCap,109,F,0.0,0.0 +2005,BruCap,110,M,0.0,0.0 +2005,BruCap,110,F,0.0,0.0 +2005,BruCap,111,M,0.0,0.0 +2005,BruCap,111,F,0.0,0.0 +2005,BruCap,112,M,0.0,0.0 +2005,BruCap,112,F,0.0,0.0 +2005,BruCap,113,M,0.0,0.0 +2005,BruCap,113,F,0.0,0.0 +2005,BruCap,114,M,0.0,0.0 +2005,BruCap,114,F,0.0,0.0 +2005,BruCap,115,M,0.0,0.0 +2005,BruCap,115,F,0.0,0.0 +2005,BruCap,116,M,0.0,0.0 +2005,BruCap,116,F,0.0,0.0 +2005,BruCap,117,M,0.0,0.0 +2005,BruCap,117,F,0.0,0.0 +2005,BruCap,118,M,0.0,0.0 +2005,BruCap,118,F,0.0,0.0 +2005,BruCap,119,M,0.0,0.0 +2005,BruCap,119,F,0.0,0.0 +2005,BruCap,120,M,0.0,0.0 +2005,BruCap,120,F,0.0,0.0 +2005,Fla,0,M,0.0009520995436488397,0.0 +2005,Fla,0,F,0.0004864489228630994,0.0 +2005,Fla,1,M,0.0004739336492890995,0.0 +2005,Fla,1,F,0.000212457065967919,0.0006784260515603799 +2005,Fla,2,M,0.000235587116750244,0.0 +2005,Fla,2,F,0.0001773301177471982,0.0 +2005,Fla,3,M,0.000266435755678412,0.0006675567423230972 +2005,Fla,3,F,6.951202558042541e-05,0.0 +2005,Fla,4,M,6.468723720809884e-05,0.0 +2005,Fla,4,F,0.0001688219603606037,0.0 +2005,Fla,5,M,9.705282908996798e-05,0.0 +2005,Fla,5,F,0.000200662185211197,0.0 +2005,Fla,6,M,0.0001884481296523132,0.0 +2005,Fla,6,F,3.304692663582287e-05,0.0 +2005,Fla,7,M,0.0001848030307697046,0.0 +2005,Fla,7,F,9.619084263178146e-05,0.0 +2005,Fla,8,M,6.133276089423167e-05,0.0 +2005,Fla,8,F,9.551402464261836e-05,0.0 +2005,Fla,9,M,3.0561413159744516e-05,0.0 +2005,Fla,9,F,6.369223910066559e-05,0.0 +2005,Fla,10,M,0.0001807446680322931,0.001311475409836066 +2005,Fla,10,F,6.33813975598162e-05,0.0007530120481927711 +2005,Fla,11,M,0.0001737267278570808,0.0 +2005,Fla,11,F,5.971040453799075e-05,0.0 +2005,Fla,12,M,0.0002787922718782236,0.0 +2005,Fla,12,F,0.0001163805644457376,0.0 +2005,Fla,13,M,0.00016495752343771486,0.0 +2005,Fla,13,F,5.789549862498191e-05,0.0 +2005,Fla,14,M,0.0003058869330663775,0.0007142857142857143 +2005,Fla,14,F,0.000145734355416946,0.0 +2005,Fla,15,M,0.0002589928057553957,0.0007496251874062968 +2005,Fla,15,F,6.0443047538456885e-05,0.0 +2005,Fla,16,M,0.0002328085440735675,0.0 +2005,Fla,16,F,0.0002737059789550514,0.0 +2005,Fla,17,M,0.0005578554860682934,0.0007230657989877079 +2005,Fla,17,F,0.0003106168851338758,0.0006958942240779402 +2005,Fla,18,M,0.000701959637320854,0.0 +2005,Fla,18,F,0.00024836236068423835,0.0 +2005,Fla,19,M,0.0007567960283344433,0.002132196162046908 +2005,Fla,19,F,0.00025245353277162416,0.0005910165484633572 +2005,Fla,20,M,0.0008285494466473337,0.0 +2005,Fla,20,F,0.00030973177228520095,0.001062699256110521 +2005,Fla,21,M,0.0008961091518760476,0.0 +2005,Fla,21,F,0.0002399232245681382,0.0 +2005,Fla,22,M,0.0005628570624489911,0.002201430930104568 +2005,Fla,22,F,0.00023721275018532246,0.0004142502071251036 +2005,Fla,23,M,0.0008753214070791619,0.0 +2005,Fla,23,F,0.0002024994214302245,0.0003972983710766786 +2005,Fla,24,M,0.001030353661932609,0.0008684324793747286 +2005,Fla,24,F,0.0002588587206626784,0.0 +2005,Fla,25,M,0.0008015256626406125,0.0 +2005,Fla,25,F,0.00031977673769586335,0.0003586800573888092 +2005,Fla,26,M,0.0007966087228655154,0.0003802281368821293 +2005,Fla,26,F,0.0002339523322123118,0.0 +2005,Fla,27,M,0.0007853860026761298,0.00075046904315197 +2005,Fla,27,F,0.00029640168356156267,0.0 +2005,Fla,28,M,0.0007387488549392749,0.0 +2005,Fla,28,F,0.0002450980392156863,0.000671366230278617 +2005,Fla,29,M,0.001091736163760425,0.0010725777618877366 +2005,Fla,29,F,0.0003133912062427529,0.0 +2005,Fla,30,M,0.001021748649832141,0.0003316749585406302 +2005,Fla,30,F,0.0004772273093327768,0.0006731740154830024 +2005,Fla,31,M,0.0007276390910108588,0.0006653359946773121 +2005,Fla,31,F,0.0005481348988835359,0.0003350083752093803 +2005,Fla,32,M,0.0008306983225253229,0.0003097893432465923 +2005,Fla,32,F,0.0005721291377196567,0.00031515915537346363 +2005,Fla,33,M,0.0009222020134743961,0.0003189792663476873 +2005,Fla,33,F,0.0003620377553659168,0.0009551098376313276 +2005,Fla,34,M,0.0007185153985282822,0.00030367446097783184 +2005,Fla,34,F,0.0006088434511276287,0.0002998500749625187 +2005,Fla,35,M,0.000864282892137495,0.0009006304413089162 +2005,Fla,35,F,0.000505356781888013,0.0006275494195167869 +2005,Fla,36,M,0.001146145779988783,0.0 +2005,Fla,36,F,0.0006754728309816872,0.000970873786407767 +2005,Fla,37,M,0.00110538817940215,0.0019678583142013783 +2005,Fla,37,F,0.0006622841444270018,0.0003387533875338754 +2005,Fla,38,M,0.001074212054030581,0.000297707651086633 +2005,Fla,38,F,0.0006794910846083553,0.0006607201850016518 +2005,Fla,39,M,0.001346310887461652,0.0018662519440124426 +2005,Fla,39,F,0.0008635186110984867,0.0 +2005,Fla,40,M,0.0016772467675845526,0.0023880597014925373 +2005,Fla,40,F,0.0010172279456324132,0.001055594651653765 +2005,Fla,41,M,0.001300390117035111,0.0013227513227513233 +2005,Fla,41,F,0.0008312370119216888,0.0007776049766718508 +2005,Fla,42,M,0.0014252089226716187,0.003370407819346141 +2005,Fla,42,F,0.001176287813214373,0.001193317422434368 +2005,Fla,43,M,0.002308814880965346,0.0007017543859649122 +2005,Fla,43,F,0.00116786391080164,0.0 +2005,Fla,44,M,0.002668326958996709,0.0035714285714285718 +2005,Fla,44,F,0.001445054076633024,0.003015941404566997 +2005,Fla,45,M,0.002754820936639119,0.001922337562475971 +2005,Fla,45,F,0.001401962747846986,0.0009195402298850574 +2005,Fla,46,M,0.002630933535484159,0.001870557426112982 +2005,Fla,46,F,0.001510401171705152,0.0015440041173443134 +2005,Fla,47,M,0.002993740361063232,0.002036659877800407 +2005,Fla,47,F,0.001605659367509832,0.003188097768331562 +2005,Fla,48,M,0.003039940136563465,0.002071251035625518 +2005,Fla,48,F,0.002142991710625471,0.0016429353778751367 +2005,Fla,49,M,0.003751187084520418,0.0025295109612141647 +2005,Fla,49,F,0.002361472222884813,0.004029936672423719 +2005,Fla,50,M,0.004335925199234553,0.003458711629917856 +2005,Fla,50,F,0.002235487753948952,0.004144464179988159 +2005,Fla,51,M,0.0038241867395083185,0.0033175355450236967 +2005,Fla,51,F,0.003049322796229005,0.001236093943139679 +2005,Fla,52,M,0.004810448393609332,0.0037400654511453952 +2005,Fla,52,F,0.003045191667946159,0.004361370716510904 +2005,Fla,53,M,0.004345094754475971,0.003360537686029765 +2005,Fla,53,F,0.003408515964104066,0.0006476683937823834 +2005,Fla,54,M,0.005869698015988951,0.005879470847623714 +2005,Fla,54,F,0.0037151868284599353,0.0019218449711723266 +2005,Fla,55,M,0.006686833306798281,0.007336084364970197 +2005,Fla,55,F,0.003589452945780369,0.005089058524173028 +2005,Fla,56,M,0.00607854115012397,0.006746987951807229 +2005,Fla,56,F,0.003818220655772723,0.0032679738562091517 +2005,Fla,57,M,0.00782240444528363,0.00935960591133005 +2005,Fla,57,F,0.0037345745832431257,0.0019280205655526988 +2005,Fla,58,M,0.008654353562005276,0.0067829457364341076 +2005,Fla,58,F,0.004184658030811878,0.005007153075822604 +2005,Fla,59,M,0.008833128724136899,0.008771929824561403 +2005,Fla,59,F,0.00486156400071145,0.005520504731861199 +2005,Fla,60,M,0.01077579683385295,0.009129640900791236 +2005,Fla,60,F,0.005769460719837379,0.005818181818181818 +2005,Fla,61,M,0.01197833705001593,0.01047443006777572 +2005,Fla,61,F,0.005120839318054082,0.009053497942386829 +2005,Fla,62,M,0.0109704641350211,0.008191126279863481 +2005,Fla,62,F,0.0052305377422706256,0.009353741496598641 +2005,Fla,63,M,0.01359342915811088,0.01076040172166428 +2005,Fla,63,F,0.006682820071908707,0.004734848484848485 +2005,Fla,64,M,0.01462865716429108,0.01198871650211566 +2005,Fla,64,F,0.007301844862252637,0.006329113924050633 +2005,Fla,65,M,0.014165087023953131,0.02247191011235955 +2005,Fla,65,F,0.007107049939716987,0.01192842942345925 +2005,Fla,66,M,0.01607803565422133,0.0162037037037037 +2005,Fla,66,F,0.007936754956581282,0.01884920634920635 +2005,Fla,67,M,0.0179472798653954,0.021739130434782608 +2005,Fla,67,F,0.009292235964514669,0.007352941176470587 +2005,Fla,68,M,0.019532112116530567,0.02370100273473109 +2005,Fla,68,F,0.011035991250745673,0.01050420168067227 +2005,Fla,69,M,0.02239675322235166,0.02242990654205607 +2005,Fla,69,F,0.0105889033637305,0.00997506234413965 +2005,Fla,70,M,0.024436518175609014,0.02198952879581152 +2005,Fla,70,F,0.013286414312493841,0.01405152224824356 +2005,Fla,71,M,0.029233870967741937,0.02666666666666667 +2005,Fla,71,F,0.01390968686566171,0.02005012531328321 +2005,Fla,72,M,0.03212257913976823,0.02625570776255708 +2005,Fla,72,F,0.01512074023922365,0.01675977653631285 +2005,Fla,73,M,0.032760558856592265,0.02771084337349398 +2005,Fla,73,F,0.01782571856872841,0.014586709886547809 +2005,Fla,74,M,0.03773505708529215,0.02196382428940568 +2005,Fla,74,F,0.02031130729149381,0.029126213592233014 +2005,Fla,75,M,0.0415583187556144,0.047619047619047616 +2005,Fla,75,F,0.02244272054843947,0.028716216216216218 +2005,Fla,76,M,0.046632911392405066,0.03921568627450981 +2005,Fla,76,F,0.02551654058936435,0.03344481605351171 +2005,Fla,77,M,0.05402895383774925,0.0583804143126177 +2005,Fla,77,F,0.0300823683896383,0.02651515151515152 +2005,Fla,78,M,0.058917480035492464,0.060606060606060615 +2005,Fla,78,F,0.035838103684592434,0.02884615384615385 +2005,Fla,79,M,0.06899735335754294,0.07322175732217573 +2005,Fla,79,F,0.04041084357635966,0.02564102564102564 +2005,Fla,80,M,0.07155095606880954,0.061576354679802964 +2005,Fla,80,F,0.04615110477548112,0.04367816091954023 +2005,Fla,81,M,0.0827544548474781,0.05882352941176471 +2005,Fla,81,F,0.05287058060330847,0.04275534441805226 +2005,Fla,82,M,0.08922093625842115,0.07886435331230282 +2005,Fla,82,F,0.05981626754748143,0.0712166172106825 +2005,Fla,83,M,0.1071808253600077,0.09398496240601503 +2005,Fla,83,F,0.06952370500438981,0.07051282051282051 +2005,Fla,84,M,0.1181297066426886,0.09523809523809523 +2005,Fla,84,F,0.07906667472647043,0.06691449814126392 +2005,Fla,85,M,0.1315833753996298,0.1398601398601399 +2005,Fla,85,F,0.09175417455672233,0.12209302325581403 +2005,Fla,86,M,0.1482778750729714,0.1272727272727273 +2005,Fla,86,F,0.1049872294663261,0.1205673758865248 +2005,Fla,87,M,0.1584797418429545,0.1621621621621622 +2005,Fla,87,F,0.1203703703703704,0.1101694915254237 +2005,Fla,88,M,0.1808935706501998,0.18032786885245894 +2005,Fla,88,F,0.129868138607789,0.1538461538461539 +2005,Fla,89,M,0.1864220183486239,0.2542372881355932 +2005,Fla,89,F,0.1509827278141751,0.1770833333333334 +2005,Fla,90,M,0.2118573797678275,0.22 +2005,Fla,90,F,0.1775617053103964,0.2121212121212121 +2005,Fla,91,M,0.2459474566797094,0.2352941176470588 +2005,Fla,91,F,0.18,0.1232876712328767 +2005,Fla,92,M,0.262416604892513,0.1818181818181818 +2005,Fla,92,F,0.1950450450450451,0.07462686567164177 +2005,Fla,93,M,0.2706521739130435,0.2105263157894737 +2005,Fla,93,F,0.2228711958192438,0.2777777777777778 +2005,Fla,94,M,0.2823179791976226,0.2666666666666667 +2005,Fla,94,F,0.2324171382376718,0.1764705882352941 +2005,Fla,95,M,0.3459715639810427,0.1428571428571429 +2005,Fla,95,F,0.2595550484883058,0.2758620689655173 +2005,Fla,96,M,0.3285198555956679,0.25 +2005,Fla,96,F,0.2774945375091042,0.2777777777777778 +2005,Fla,97,M,0.3135135135135136,0.5 +2005,Fla,97,F,0.2812834224598931,0.2 +2005,Fla,98,M,0.4537037037037037,0.0 +2005,Fla,98,F,0.3477537437603994,0.1428571428571429 +2005,Fla,99,M,0.38095238095238093,0.0 +2005,Fla,99,F,0.315136476426799,0.0 +2005,Fla,100,M,0.4791666666666667,0.5 +2005,Fla,100,F,0.375,0.6666666666666666 +2005,Fla,101,M,0.4736842105263158,0.0 +2005,Fla,101,F,0.4761904761904762,0.4 +2005,Fla,102,M,0.7692307692307693,1.0 +2005,Fla,102,F,0.4269662921348315,0.0 +2005,Fla,103,M,1.0,1.0 +2005,Fla,103,F,0.3673469387755102,0.0 +2005,Fla,104,M,0.3333333333333333,0.0 +2005,Fla,104,F,0.45,0.0 +2005,Fla,105,M,0.5,0.0 +2005,Fla,105,F,0.6,1.0 +2005,Fla,106,M,0.0,0.0 +2005,Fla,106,F,0.2,0.0 +2005,Fla,107,M,0.0,0.0 +2005,Fla,107,F,0.0,0.0 +2005,Fla,108,M,0.0,0.0 +2005,Fla,108,F,1.0,0.0 +2005,Fla,109,M,0.0,0.0 +2005,Fla,109,F,0.0,0.0 +2005,Fla,110,M,0.0,0.0 +2005,Fla,110,F,0.0,0.0 +2005,Fla,111,M,0.0,0.0 +2005,Fla,111,F,0.0,0.0 +2005,Fla,112,M,0.0,0.0 +2005,Fla,112,F,0.0,0.0 +2005,Fla,113,M,0.0,0.0 +2005,Fla,113,F,0.0,0.0 +2005,Fla,114,M,0.0,0.0 +2005,Fla,114,F,0.0,0.0 +2005,Fla,115,M,0.0,0.0 +2005,Fla,115,F,0.0,0.0 +2005,Fla,116,M,0.0,0.0 +2005,Fla,116,F,0.0,0.0 +2005,Fla,117,M,0.0,0.0 +2005,Fla,117,F,0.0,0.0 +2005,Fla,118,M,0.0,0.0 +2005,Fla,118,F,0.0,0.0 +2005,Fla,119,M,0.0,0.0 +2005,Fla,119,F,0.0,0.0 +2005,Fla,120,M,0.0,0.0 +2005,Fla,120,F,0.0,0.0 +2005,Wal,0,M,0.001002268291396318,0.001364256480218281 +2005,Wal,0,F,0.0006166956326736559,0.0 +2005,Wal,1,M,0.0005335325188070213,0.0 +2005,Wal,1,F,0.0004412819239891887,0.0 +2005,Wal,2,M,0.0001576789656259855,0.0 +2005,Wal,2,F,0.0002761820592134335,0.0 +2005,Wal,3,M,0.0001521761184944709,0.0 +2005,Wal,3,F,0.00015819447373971741,0.0 +2005,Wal,4,M,9.910802775024775e-05,0.0 +2005,Wal,4,F,0.0002605795288722118,0.0 +2005,Wal,5,M,0.0001527572687000357,0.0 +2005,Wal,5,F,0.0,0.0 +2005,Wal,6,M,0.00015247776365946632,0.0 +2005,Wal,6,F,0.0002666240068255746,0.0 +2005,Wal,7,M,0.0001015640869388584,0.0 +2005,Wal,7,F,0.00047581284694686756,0.0 +2005,Wal,8,M,0.0001501501501501502,0.0 +2005,Wal,8,F,0.00010490977759127148,0.0 +2005,Wal,9,M,5.137954066690644e-05,0.0 +2005,Wal,9,F,0.00010675776662752208,0.0 +2005,Wal,10,M,0.0,0.0 +2005,Wal,10,F,0.0,0.0 +2005,Wal,11,M,0.0001951886009857024,0.0 +2005,Wal,11,F,5.1570316126037846e-05,0.0 +2005,Wal,12,M,0.00018558901313042267,0.0 +2005,Wal,12,F,0.000194325689856199,0.0 +2005,Wal,13,M,0.00013624596939007216,0.0 +2005,Wal,13,F,4.708984742889433e-05,0.0 +2005,Wal,14,M,0.0004140405759764457,0.0 +2005,Wal,14,F,0.0001437401178668967,0.0009354536950420953 +2005,Wal,15,M,0.00045936882723138407,0.0 +2005,Wal,15,F,0.0001445783132530121,0.0008865248226950351 +2005,Wal,16,M,0.0005092356835331699,0.0 +2005,Wal,16,F,9.776604585227552e-05,0.0 +2005,Wal,17,M,0.00043198617644235387,0.0008143322475570032 +2005,Wal,17,F,0.0003524672708962738,0.0008097165991902834 +2005,Wal,18,M,0.001153402537485583,0.0015444015444015448 +2005,Wal,18,F,0.0001520141879908792,0.0007530120481927711 +2005,Wal,19,M,0.0014009806864805358,0.0008517887563884157 +2005,Wal,19,F,0.0003667417614082884,0.0007385524372230429 +2005,Wal,20,M,0.0009673641871595133,0.001533742331288344 +2005,Wal,20,F,0.0002115506663845991,0.0006816632583503749 +2005,Wal,21,M,0.0008229606007612388,0.0013908205841446446 +2005,Wal,21,F,0.00044130626654898496,0.0 +2005,Wal,22,M,0.001385610181668891,0.0 +2005,Wal,22,F,0.0,0.0005235602094240838 +2005,Wal,23,M,0.0012885269559839187,0.0005763688760806918 +2005,Wal,23,F,0.0003169739553066724,0.0 +2005,Wal,24,M,0.0007793017456359103,0.001564129301355579 +2005,Wal,24,F,0.0001072558588512898,0.00047036688617121367 +2005,Wal,25,M,0.001122214503286485,0.0019540791402051787 +2005,Wal,25,F,0.0004521817770743839,0.0 +2005,Wal,26,M,0.001048507256773909,0.0004777830864787387 +2005,Wal,26,F,0.0005741846577859437,0.0 +2005,Wal,27,M,0.001591570166291642,0.0004816955684007707 +2005,Wal,27,F,0.00022741486156120297,0.0004553734061930783 +2005,Wal,28,M,0.000979538528515455,0.001353179972936401 +2005,Wal,28,F,0.0006100266193433898,0.000473260766682442 +2005,Wal,29,M,0.0012993340912782199,0.0031083481349911193 +2005,Wal,29,F,0.0006015202056105433,0.0008748906386701663 +2005,Wal,30,M,0.0013513513513513519,0.001199040767386091 +2005,Wal,30,F,0.000211864406779661,0.0004025764895330113 +2005,Wal,31,M,0.001294369492706726,0.001089324618736384 +2005,Wal,31,F,0.0006548788474132286,0.00038431975403535736 +2005,Wal,32,M,0.001292113323124043,0.002409638554216868 +2005,Wal,32,F,0.0007255139056831923,0.0 +2005,Wal,33,M,0.001551262163305599,0.0006870491240123669 +2005,Wal,33,F,0.0006584516978647353,0.00036818851251840936 +2005,Wal,34,M,0.001430683389765845,0.001389854065323141 +2005,Wal,34,F,0.0004836291531653528,0.0 +2005,Wal,35,M,0.002059485607548254,0.001351808043257857 +2005,Wal,35,F,0.0006714950357331287,0.0003524850193866761 +2005,Wal,36,M,0.001659103108378471,0.0003334444814938313 +2005,Wal,36,F,0.001204761216326924,0.0006863417982155112 +2005,Wal,37,M,0.001337920489296636,0.0003299241174529858 +2005,Wal,37,F,0.001233747746037772,0.00108735048930772 +2005,Wal,38,M,0.001914009616731245,0.001178897730621869 +2005,Wal,38,F,0.0009289795160016725,0.0003233107015842225 +2005,Wal,39,M,0.002250832808139011,0.0029120559114735 +2005,Wal,39,F,0.0009395973154362416,0.002045687009887487 +2005,Wal,40,M,0.002651482222029036,0.0006142506142506142 +2005,Wal,40,F,0.001636731705216006,0.0013610071452875134 +2005,Wal,41,M,0.002701745061564355,0.001528117359413203 +2005,Wal,41,F,0.001346772091406725,0.0006944444444444446 +2005,Wal,42,M,0.00285649512582181,0.001597444089456869 +2005,Wal,42,F,0.0015042916556056991,0.0003742514970059882 +2005,Wal,43,M,0.002922940655447299,0.002242152466367713 +2005,Wal,43,F,0.001853687976893564,0.00072992700729927 +2005,Wal,44,M,0.003210559172389191,0.001733603004911875 +2005,Wal,44,F,0.002286317270488921,0.0007674597083653107 +2005,Wal,45,M,0.0039269936186353705,0.002176616915422886 +2005,Wal,45,F,0.002171506429362173,0.003139717425431712 +2005,Wal,46,M,0.004574896951578565,0.001237623762376238 +2005,Wal,46,F,0.0026419507124604787,0.0 +2005,Wal,47,M,0.005551986785353767,0.003460207612456748 +2005,Wal,47,F,0.002481719477066253,0.00170940170940171 +2005,Wal,48,M,0.005283268078682957,0.0033639143730886853 +2005,Wal,48,F,0.002957386745530313,0.002870028700287003 +2005,Wal,49,M,0.005344021376085505,0.0038722168441432717 +2005,Wal,49,F,0.002884312046509532,0.001275510204081633 +2005,Wal,50,M,0.006331542594013815,0.005570117955439056 +2005,Wal,50,F,0.003406922867266285,0.002597402597402598 +2005,Wal,51,M,0.006379585326953748,0.004765146358066711 +2005,Wal,51,F,0.003929000647129519,0.001395998138669149 +2005,Wal,52,M,0.007869012707722386,0.004889975550122249 +2005,Wal,52,F,0.003945143715949653,0.003255813953488372 +2005,Wal,53,M,0.008243435782617546,0.008270406328658756 +2005,Wal,53,F,0.004064846253168189,0.0018752930145335208 +2005,Wal,54,M,0.00939978458826985,0.00792221822110191 +2005,Wal,54,F,0.004514994534480301,0.002759889604415824 +2005,Wal,55,M,0.01061885711463427,0.0051813471502590676 +2005,Wal,55,F,0.004951437821367358,0.00301659125188537 +2005,Wal,56,M,0.010533469249065579,0.01179506081828235 +2005,Wal,56,F,0.00516795865633075,0.004197761194029851 +2005,Wal,57,M,0.01087329186462262,0.008938547486033519 +2005,Wal,57,F,0.005804699934463065,0.0010167768174885608 +2005,Wal,58,M,0.0135985897758751,0.007661290322580646 +2005,Wal,58,F,0.005747667954395553,0.002176278563656148 +2005,Wal,59,M,0.01400598313842807,0.009077155824508321 +2005,Wal,59,F,0.007329391475732939,0.003201024327784891 +2005,Wal,60,M,0.01396017244918908,0.008171603677221655 +2005,Wal,60,F,0.005855685681904042,0.0069974554707379144 +2005,Wal,61,M,0.01646728695909024,0.013808975834292293 +2005,Wal,61,F,0.0075046904315197,0.004837595024187975 +2005,Wal,62,M,0.01670359638656895,0.01695941853422169 +2005,Wal,62,F,0.008362743593678073,0.009824561403508772 +2005,Wal,63,M,0.01788018433179724,0.01069182389937107 +2005,Wal,63,F,0.00904571754543232,0.008245877061469266 +2005,Wal,64,M,0.01727718249024005,0.01274238227146815 +2005,Wal,64,F,0.009266014883992412,0.005635566687539136 +2005,Wal,65,M,0.02132756355768488,0.015457788347205709 +2005,Wal,65,F,0.009646730091144971,0.006802721088435374 +2005,Wal,66,M,0.02289006540018686,0.01962066710268149 +2005,Wal,66,F,0.01030251328827351,0.01040391676866585 +2005,Wal,67,M,0.022338170552747432,0.01796023091725465 +2005,Wal,67,F,0.0128,0.007570543702684102 +2005,Wal,68,M,0.02342141386410433,0.02843601895734597 +2005,Wal,68,F,0.01309890725693472,0.012517385257301807 +2005,Wal,69,M,0.0309177888022679,0.030075187969924814 +2005,Wal,69,F,0.014243197278911568,0.015779092702169633 +2005,Wal,70,M,0.03069230106043625,0.025899280575539568 +2005,Wal,70,F,0.01655447176810002,0.012599469496021221 +2005,Wal,71,M,0.03438992618323925,0.0406015037593985 +2005,Wal,71,F,0.01588611512275634,0.01845748187211602 +2005,Wal,72,M,0.03938618925831202,0.04051012753188297 +2005,Wal,72,F,0.017262323380858,0.015703069236259817 +2005,Wal,73,M,0.042451215337213286,0.0439469320066335 +2005,Wal,73,F,0.02320302648171501,0.02239328201539538 +2005,Wal,74,M,0.04760616716256424,0.04634721131186174 +2005,Wal,74,F,0.02277472006073259,0.026512576478586 +2005,Wal,75,M,0.05355375173233023,0.057724957555178265 +2005,Wal,75,F,0.028643011917659805,0.02419354838709678 +2005,Wal,76,M,0.056373580143037436,0.06009389671361502 +2005,Wal,76,F,0.028592978606692267,0.02421875 +2005,Wal,77,M,0.06174783488921382,0.06578947368421052 +2005,Wal,77,F,0.03498001142204455,0.03755868544600939 +2005,Wal,78,M,0.07402999285884314,0.07244897959183673 +2005,Wal,78,F,0.03807717557808739,0.03622047244094488 +2005,Wal,79,M,0.07680608365019011,0.08066429418742586 +2005,Wal,79,F,0.04574972637723459,0.03657522859517872 +2005,Wal,80,M,0.08333333333333333,0.08928571428571429 +2005,Wal,80,F,0.053633619688878566,0.05307262569832402 +2005,Wal,81,M,0.09852294154619737,0.1045197740112994 +2005,Wal,81,F,0.05869278893645045,0.05923000987166833 +2005,Wal,82,M,0.1021514780479272,0.08885017421602788 +2005,Wal,82,F,0.06485921018219859,0.06284454244762955 +2005,Wal,83,M,0.1159647404505387,0.1195652173913044 +2005,Wal,83,F,0.07518660112870927,0.06763925729442971 +2005,Wal,84,M,0.1279279279279279,0.1181318681318681 +2005,Wal,84,F,0.08931594145175745,0.1013698630136986 +2005,Wal,85,M,0.1413121845710166,0.1435406698564593 +2005,Wal,85,F,0.1030266885343671,0.09534368070953436 +2005,Wal,86,M,0.1699266503667482,0.1694915254237288 +2005,Wal,86,F,0.1107974594213126,0.1284046692607004 +2005,Wal,87,M,0.1749622926093514,0.1720430107526882 +2005,Wal,87,F,0.1229352829677769,0.1476793248945148 +2005,Wal,88,M,0.1878542510121458,0.1847826086956522 +2005,Wal,88,F,0.1501706484641638,0.1524663677130045 +2005,Wal,89,M,0.1834372217275156,0.2891566265060241 +2005,Wal,89,F,0.1578947368421053,0.1807228915662651 +2005,Wal,90,M,0.2223198594024605,0.1744186046511628 +2005,Wal,90,F,0.1653333333333333,0.1441048034934498 +2005,Wal,91,M,0.2431466030989273,0.253968253968254 +2005,Wal,91,F,0.2019263845889233,0.2216216216216216 +2005,Wal,92,M,0.2676056338028169,0.2115384615384615 +2005,Wal,92,F,0.2135922330097087,0.1567164179104478 +2005,Wal,93,M,0.32506887052341604,0.2692307692307692 +2005,Wal,93,F,0.2394933793897525,0.2342342342342343 +2005,Wal,94,M,0.2756183745583039,0.2666666666666667 +2005,Wal,94,F,0.262406015037594,0.1590909090909091 +2005,Wal,95,M,0.3118279569892473,0.2 +2005,Wal,95,F,0.3023735810113519,0.2253521126760564 +2005,Wal,96,M,0.4608695652173913,0.125 +2005,Wal,96,F,0.3146374829001368,0.3829787234042553 +2005,Wal,97,M,0.2758620689655173,0.5 +2005,Wal,97,F,0.3352272727272727,0.3076923076923077 +2005,Wal,98,M,0.4,0.0 +2005,Wal,98,F,0.328125,0.375 +2005,Wal,99,M,0.5,0.25 +2005,Wal,99,F,0.3761467889908257,0.1538461538461539 +2005,Wal,100,M,0.6363636363636364,0.0 +2005,Wal,100,F,0.4180327868852459,0.4444444444444444 +2005,Wal,101,M,0.6666666666666666,0.0 +2005,Wal,101,F,0.4623655913978494,0.3333333333333333 +2005,Wal,102,M,0.75,0.0 +2005,Wal,102,F,0.4736842105263158,0.0 +2005,Wal,103,M,1.0,0.0 +2005,Wal,103,F,0.3478260869565218,0.5 +2005,Wal,104,M,1.0,0.0 +2005,Wal,104,F,0.6,0.0 +2005,Wal,105,M,0.0,0.0 +2005,Wal,105,F,0.125,0.0 +2005,Wal,106,M,0.0,0.0 +2005,Wal,106,F,0.6,0.0 +2005,Wal,107,M,0.0,0.0 +2005,Wal,107,F,1.0,1.0 +2005,Wal,108,M,0.0,0.0 +2005,Wal,108,F,0.0,0.0 +2005,Wal,109,M,0.0,0.0 +2005,Wal,109,F,0.0,0.0 +2005,Wal,110,M,0.0,0.0 +2005,Wal,110,F,0.0,0.0 +2005,Wal,111,M,0.0,0.0 +2005,Wal,111,F,0.0,0.0 +2005,Wal,112,M,0.0,0.0 +2005,Wal,112,F,0.0,0.0 +2005,Wal,113,M,0.0,0.0 +2005,Wal,113,F,0.0,0.0 +2005,Wal,114,M,0.0,0.0 +2005,Wal,114,F,0.0,0.0 +2005,Wal,115,M,0.0,0.0 +2005,Wal,115,F,0.0,0.0 +2005,Wal,116,M,0.0,0.0 +2005,Wal,116,F,0.0,0.0 +2005,Wal,117,M,0.0,0.0 +2005,Wal,117,F,0.0,0.0 +2005,Wal,118,M,0.0,0.0 +2005,Wal,118,F,0.0,0.0 +2005,Wal,119,M,0.0,0.0 +2005,Wal,119,F,0.0,0.0 +2005,Wal,120,M,0.0,0.0 +2005,Wal,120,F,0.0,0.0 +2006,BruCap,0,M,0.001296386323124291,0.000580046403712297 +2006,BruCap,0,F,0.0006657789613848202,0.0006277463904582549 +2006,BruCap,1,M,0.0001647446457990115,0.0018393623543838144 +2006,BruCap,1,F,0.0006879944960440316,0.0006680026720106881 +2006,BruCap,2,M,0.00035486160397445,0.0 +2006,BruCap,2,F,0.0003604253018561903,0.001391788448155881 +2006,BruCap,3,M,0.0,0.0 +2006,BruCap,3,F,0.0003820439350525311,0.0007479431563201198 +2006,BruCap,4,M,0.0,0.0 +2006,BruCap,4,F,0.0001870907390084191,0.0 +2006,BruCap,5,M,0.0,0.0 +2006,BruCap,5,F,0.0,0.0008665511265164642 +2006,BruCap,6,M,0.0,0.0 +2006,BruCap,6,F,0.0,0.0 +2006,BruCap,7,M,0.0002047082906857728,0.0 +2006,BruCap,7,F,0.0002134471718249733,0.0 +2006,BruCap,8,M,0.0,0.0 +2006,BruCap,8,F,0.0002164502164502165,0.0 +2006,BruCap,9,M,0.0,0.0 +2006,BruCap,9,F,0.0,0.0 +2006,BruCap,10,M,0.0002150075252633842,0.0 +2006,BruCap,10,F,0.0,0.0 +2006,BruCap,11,M,0.0,0.0 +2006,BruCap,11,F,0.0,0.0 +2006,BruCap,12,M,0.00021394950791613182,0.0 +2006,BruCap,12,F,0.0,0.0 +2006,BruCap,13,M,0.0004302000430200044,0.0 +2006,BruCap,13,F,0.00022271714922048998,0.0 +2006,BruCap,14,M,0.0,0.0009082652134423252 +2006,BruCap,14,F,0.0,0.0 +2006,BruCap,15,M,0.0006475285991797972,0.0 +2006,BruCap,15,F,0.0002263980076975324,0.0009267840593141797 +2006,BruCap,16,M,0.0002201673271686482,0.0 +2006,BruCap,16,F,0.0006770480704129992,0.0 +2006,BruCap,17,M,0.0006543075245365322,0.0 +2006,BruCap,17,F,0.0,0.0 +2006,BruCap,18,M,0.00022547914317925591,0.0 +2006,BruCap,18,F,0.000451365380275333,0.0007390983000739097 +2006,BruCap,19,M,0.0006718924972004478,0.0 +2006,BruCap,19,F,0.0011340440009072349,0.0 +2006,BruCap,20,M,0.0006796556411418215,0.00145985401459854 +2006,BruCap,20,F,0.0,0.0005274261603375527 +2006,BruCap,21,M,0.00022456770716370992,0.0006329113924050633 +2006,BruCap,21,F,0.0,0.00046425255338904364 +2006,BruCap,22,M,0.00044395116537180907,0.0006006006006006006 +2006,BruCap,22,F,0.0,0.0 +2006,BruCap,23,M,0.0008652390222799048,0.0004970178926441351 +2006,BruCap,23,F,0.0002059732234809475,0.0 +2006,BruCap,24,M,0.001389716100853683,0.0008654262224145391 +2006,BruCap,24,F,0.00038015586390420086,0.0 +2006,BruCap,25,M,0.0009428625306430324,0.0003874467260751647 +2006,BruCap,25,F,0.00017689722271360342,0.0002946375957572186 +2006,BruCap,26,M,0.001096491228070175,0.0003496503496503497 +2006,BruCap,26,F,0.0008907892392659896,0.0002887669650591973 +2006,BruCap,27,M,0.0003665017408832692,0.0 +2006,BruCap,27,F,0.0008628127696289905,0.0002849002849002849 +2006,BruCap,28,M,0.0005523844595838704,0.0003023888720895071 +2006,BruCap,28,F,0.0003570153516601214,0.0 +2006,BruCap,29,M,0.0005633802816901409,0.0005649717514124294 +2006,BruCap,29,F,0.0007218913553510198,0.0008431703204047218 +2006,BruCap,30,M,0.0009428625306430324,0.00028587764436821035 +2006,BruCap,30,F,0.000777302759424796,0.0 +2006,BruCap,31,M,0.0005690440060698028,0.001658833287254631 +2006,BruCap,31,F,0.0005896226415094339,0.0 +2006,BruCap,32,M,0.0001861850679575498,0.0005543237250554324 +2006,BruCap,32,F,0.00038160656363289447,0.0014359563469270539 +2006,BruCap,33,M,0.0009214891264283082,0.001116694584031267 +2006,BruCap,33,F,0.0001952362358453729,0.0014590020426028599 +2006,BruCap,34,M,0.00150065653723504,0.0005636978579481398 +2006,BruCap,34,F,0.0005918327086210298,0.0006150061500615006 +2006,BruCap,35,M,0.001684762261325347,0.000273000273000273 +2006,BruCap,35,F,0.00039346842415896116,0.0006161429451632777 +2006,BruCap,36,M,0.0001920860545524395,0.001166180758017493 +2006,BruCap,36,F,0.0004079135223332654,0.00128122998078155 +2006,BruCap,37,M,0.0013776815587482779,0.001778304682868998 +2006,BruCap,37,F,0.001707941929974381,0.0003415300546448088 +2006,BruCap,38,M,0.001204577394097571,0.0009526833915528741 +2006,BruCap,38,F,0.0006487889273356401,0.0 +2006,BruCap,39,M,0.001628996131134189,0.001973684210526316 +2006,BruCap,39,F,0.0008369951872776733,0.001886080724254998 +2006,BruCap,40,M,0.001358168412883198,0.0027027027027027037 +2006,BruCap,40,F,0.001239413344350341,0.001167315175097276 +2006,BruCap,41,M,0.001179941002949853,0.001389854065323141 +2006,BruCap,41,F,0.0008225375282747275,0.001190948789202064 +2006,BruCap,42,M,0.0028583095140873828,0.002764612954186414 +2006,BruCap,42,F,0.001453488372093023,0.0004338394793926247 +2006,BruCap,43,M,0.003404979782932539,0.0008019246190858058 +2006,BruCap,43,F,0.0010528532322594231,0.0009358914365933552 +2006,BruCap,44,M,0.003492687186203886,0.001676445934618609 +2006,BruCap,44,F,0.001473994525163192,0.001446480231436837 +2006,BruCap,45,M,0.003964941569282137,0.0032095369096744623 +2006,BruCap,45,F,0.003241491085899514,0.002420135527589545 +2006,BruCap,46,M,0.003007518796992482,0.002902757619738752 +2006,BruCap,46,F,0.002694300518134715,0.0005165289256198346 +2006,BruCap,47,M,0.005587840858292357,0.002031488065007618 +2006,BruCap,47,F,0.002688728024819028,0.0011702750146284381 +2006,BruCap,48,M,0.004101161995898838,0.001108647450110865 +2006,BruCap,48,F,0.0035880118193330523,0.00113960113960114 +2006,BruCap,49,M,0.003473026163463765,0.003818876159301692 +2006,BruCap,49,F,0.004011824324324324,0.0 +2006,BruCap,50,M,0.005074971164936564,0.005110732538330494 +2006,BruCap,50,F,0.004392386530014642,0.001265822784810127 +2006,BruCap,51,M,0.005660377358490566,0.003201024327784891 +2006,BruCap,51,F,0.003437164339419979,0.001939237233354881 +2006,BruCap,52,M,0.006298110566829951,0.0026437541308658307 +2006,BruCap,52,F,0.004287245444801715,0.0027835768963117608 +2006,BruCap,53,M,0.010727611940298507,0.005312084993359893 +2006,BruCap,53,F,0.006266205704407953,0.003963011889035667 +2006,BruCap,54,M,0.007208550832711907,0.006051437216338882 +2006,BruCap,54,F,0.004810996563573882,0.0030007501875468877 +2006,BruCap,55,M,0.0076374745417515265,0.007529089664613278 +2006,BruCap,55,F,0.005966850828729282,0.002070393374741201 +2006,BruCap,56,M,0.0066326530612244895,0.0038402457757296467 +2006,BruCap,56,F,0.005276439550355586,0.001564945226917058 +2006,BruCap,57,M,0.01183431952662722,0.0052316890881913295 +2006,BruCap,57,F,0.005495763682161667,0.0007830853563038371 +2006,BruCap,58,M,0.01139306059036769,0.001532567049808429 +2006,BruCap,58,F,0.005793226381461676,0.002429149797570851 +2006,BruCap,59,M,0.01526915113871636,0.00903861955628595 +2006,BruCap,59,F,0.00487012987012987,0.003233629749393695 +2006,BruCap,60,M,0.01497555012224939,0.007866273352999017 +2006,BruCap,60,F,0.0070569785676947204,0.0018867924528301887 +2006,BruCap,61,M,0.017595307917888568,0.01379310344827586 +2006,BruCap,61,F,0.008651399491094147,0.005639097744360902 +2006,BruCap,62,M,0.01827923101166089,0.007494646680942184 +2006,BruCap,62,F,0.00862533692722372,0.004171011470281543 +2006,BruCap,63,M,0.01834215167548501,0.011013215859030841 +2006,BruCap,63,F,0.01170311056359717,0.00447427293064877 +2006,BruCap,64,M,0.017161992465466718,0.01251564455569462 +2006,BruCap,64,F,0.0120652945351313,0.005031446540880503 +2006,BruCap,65,M,0.023306627822286968,0.02064220183486239 +2006,BruCap,65,F,0.009633312616532008,0.006862745098039216 +2006,BruCap,66,M,0.02094818081587652,0.0186799501867995 +2006,BruCap,66,F,0.011347105033459409,0.0108433734939759 +2006,BruCap,67,M,0.02091743119266055,0.0154241645244216 +2006,BruCap,67,F,0.00920974450386215,0.01694915254237288 +2006,BruCap,68,M,0.02187260168841136,0.012912482065997127 +2006,BruCap,68,F,0.01850138760407031,0.01303780964797914 +2006,BruCap,69,M,0.03113914071738274,0.01654135338345865 +2006,BruCap,69,F,0.01679389312977099,0.01111111111111111 +2006,BruCap,70,M,0.02547513141932875,0.02159468438538206 +2006,BruCap,70,F,0.015133171912832932,0.01269035532994924 +2006,BruCap,71,M,0.030891089108910887,0.030769230769230767 +2006,BruCap,71,F,0.01459410155062329,0.013986013986013993 +2006,BruCap,72,M,0.029546400332917187,0.02935779816513762 +2006,BruCap,72,F,0.0210799884493214,0.01475409836065574 +2006,BruCap,73,M,0.04193548387096775,0.02333931777378815 +2006,BruCap,73,F,0.01896263245956498,0.040880503144654086 +2006,BruCap,74,M,0.04135954135954136,0.04615384615384616 +2006,BruCap,74,F,0.02328190743338009,0.02086956521739131 +2006,BruCap,75,M,0.04480827229642397,0.03846153846153847 +2006,BruCap,75,F,0.02708333333333334,0.0245398773006135 +2006,BruCap,76,M,0.05145719489981785,0.04502369668246446 +2006,BruCap,76,F,0.02540983606557377,0.017278617710583158 +2006,BruCap,77,M,0.0543778801843318,0.046961325966850834 +2006,BruCap,77,F,0.03009194761772082,0.042510121457489884 +2006,BruCap,78,M,0.0635386119257087,0.07792207792207792 +2006,BruCap,78,F,0.0379133409350057,0.04018912529550829 +2006,BruCap,79,M,0.06868272680676576,0.0711864406779661 +2006,BruCap,79,F,0.03778337531486147,0.04383561643835617 +2006,BruCap,80,M,0.07927155865024102,0.04867256637168142 +2006,BruCap,80,F,0.0398166714408479,0.060240963855421686 +2006,BruCap,81,M,0.08002177463255307,0.03500000000000001 +2006,BruCap,81,F,0.04968767745599091,0.028753993610223638 +2006,BruCap,82,M,0.09616555082166768,0.05681818181818182 +2006,BruCap,82,F,0.054703328509406665,0.06382978723404255 +2006,BruCap,83,M,0.09170013386880856,0.101123595505618 +2006,BruCap,83,F,0.06682941714983216,0.08333333333333333 +2006,BruCap,84,M,0.1072874493927125,0.06428571428571428 +2006,BruCap,84,F,0.07694773966014748,0.07960199004975124 +2006,BruCap,85,M,0.1247974068071313,0.0970873786407767 +2006,BruCap,85,F,0.08746156474205671,0.06837606837606837 +2006,BruCap,86,M,0.1324582338902148,0.1095890410958904 +2006,BruCap,86,F,0.09933774834437087,0.07575757575757576 +2006,BruCap,87,M,0.1167400881057269,0.1851851851851852 +2006,BruCap,87,F,0.1079847908745247,0.060606060606060615 +2006,BruCap,88,M,0.1811594202898551,0.08823529411764706 +2006,BruCap,88,F,0.1026102610261026,0.1134020618556701 +2006,BruCap,89,M,0.1639344262295082,0.04166666666666667 +2006,BruCap,89,F,0.1183378500451671,0.06578947368421052 +2006,BruCap,90,M,0.2144927536231884,0.1666666666666667 +2006,BruCap,90,F,0.1603119584055459,0.0945945945945946 +2006,BruCap,91,M,0.2085889570552147,0.1333333333333333 +2006,BruCap,91,F,0.1483126110124334,0.1168831168831169 +2006,BruCap,92,M,0.2372881355932204,0.3571428571428572 +2006,BruCap,92,F,0.2026002166847237,0.1851851851851852 +2006,BruCap,93,M,0.2386363636363637,0.1176470588235294 +2006,BruCap,93,F,0.2078272604588394,0.1764705882352941 +2006,BruCap,94,M,0.2063492063492064,0.0 +2006,BruCap,94,F,0.2362948960302458,0.09090909090909093 +2006,BruCap,95,M,0.2696629213483146,0.2857142857142857 +2006,BruCap,95,F,0.2650862068965517,0.2258064516129032 +2006,BruCap,96,M,0.25,0.4 +2006,BruCap,96,F,0.2736842105263158,0.12 +2006,BruCap,97,M,0.2758620689655173,0.6 +2006,BruCap,97,F,0.2648401826484018,0.2 +2006,BruCap,98,M,0.3571428571428572,0.0 +2006,BruCap,98,F,0.2556390977443609,0.0 +2006,BruCap,99,M,0.4375,1.0 +2006,BruCap,99,F,0.2542372881355932,0.2857142857142857 +2006,BruCap,100,M,0.4666666666666667,0.0 +2006,BruCap,100,F,0.4411764705882353,0.5 +2006,BruCap,101,M,0.1666666666666667,0.0 +2006,BruCap,101,F,0.2244897959183674,0.0 +2006,BruCap,102,M,0.0,0.0 +2006,BruCap,102,F,0.4615384615384616,0.0 +2006,BruCap,103,M,0.0,0.0 +2006,BruCap,103,F,0.4,0.4 +2006,BruCap,104,M,0.0,0.0 +2006,BruCap,104,F,0.1666666666666667,0.0 +2006,BruCap,105,M,0.0,0.0 +2006,BruCap,105,F,0.5,1.0 +2006,BruCap,106,M,0.0,0.0 +2006,BruCap,106,F,0.0,0.0 +2006,BruCap,107,M,0.0,0.0 +2006,BruCap,107,F,0.0,0.0 +2006,BruCap,108,M,0.0,0.0 +2006,BruCap,108,F,0.0,0.0 +2006,BruCap,109,M,0.0,0.0 +2006,BruCap,109,F,0.0,0.0 +2006,BruCap,110,M,0.0,0.0 +2006,BruCap,110,F,0.0,0.0 +2006,BruCap,111,M,0.0,0.0 +2006,BruCap,111,F,0.0,0.0 +2006,BruCap,112,M,0.0,0.0 +2006,BruCap,112,F,0.0,0.0 +2006,BruCap,113,M,0.0,0.0 +2006,BruCap,113,F,0.0,0.0 +2006,BruCap,114,M,0.0,0.0 +2006,BruCap,114,F,0.0,0.0 +2006,BruCap,115,M,0.0,0.0 +2006,BruCap,115,F,0.0,0.0 +2006,BruCap,116,M,0.0,0.0 +2006,BruCap,116,F,0.0,0.0 +2006,BruCap,117,M,0.0,0.0 +2006,BruCap,117,F,0.0,0.0 +2006,BruCap,118,M,0.0,0.0 +2006,BruCap,118,F,0.0,0.0 +2006,BruCap,119,M,0.0,0.0 +2006,BruCap,119,F,0.0,0.0 +2006,BruCap,120,M,0.0,0.0 +2006,BruCap,120,F,0.0,0.0 +2006,Fla,0,M,0.000928089096553269,0.002250984805852561 +2006,Fla,0,F,0.0006465883954398503,0.001763668430335097 +2006,Fla,1,M,0.0003576770501398192,0.0 +2006,Fla,1,F,0.0001030042918454936,0.0005834305717619603 +2006,Fla,2,M,0.0001680276909634708,0.0 +2006,Fla,2,F,0.0002108370229812355,0.0 +2006,Fla,3,M,0.0001672408602869853,0.0 +2006,Fla,3,F,0.0001055260473460199,0.0006464124111182935 +2006,Fla,4,M,0.0001322620110438779,0.0 +2006,Fla,4,F,6.905362013603563e-05,0.0 +2006,Fla,5,M,0.00016083376222336592,0.0 +2006,Fla,5,F,6.708707902857911e-05,0.0 +2006,Fla,6,M,0.0001289573795860468,0.0 +2006,Fla,6,F,3.326126725428239e-05,0.0 +2006,Fla,7,M,0.0001874765654293214,0.0 +2006,Fla,7,F,0.00019728405616019468,0.0 +2006,Fla,8,M,9.208951100469658e-05,0.0 +2006,Fla,8,F,6.387939570091667e-05,0.0 +2006,Fla,9,M,0.0,0.0 +2006,Fla,9,F,0.0,0.0 +2006,Fla,10,M,3.044047365377005e-05,0.0 +2006,Fla,10,F,6.34236062662523e-05,0.0 +2006,Fla,11,M,5.9988002399520106e-05,0.0 +2006,Fla,11,F,6.313729204154434e-05,0.0 +2006,Fla,12,M,8.644038494784764e-05,0.0 +2006,Fla,12,F,8.92299455697332e-05,0.0 +2006,Fla,13,M,0.0001667222407469156,0.0 +2006,Fla,13,F,0.00011601601020940892,0.0007002801120448178 +2006,Fla,14,M,0.0001096551346016777,0.0 +2006,Fla,14,F,0.0001442210620439009,0.0 +2006,Fla,15,M,0.00022189554267328657,0.0 +2006,Fla,15,F,0.00017428181369274118,0.0 +2006,Fla,16,M,0.00022923292931029541,0.0006872852233676976 +2006,Fla,16,F,0.00018077734257306415,0.0 +2006,Fla,17,M,0.0004639429350189927,0.0 +2006,Fla,17,F,0.0001819394748013828,0.0 +2006,Fla,18,M,0.0003804284209294159,0.0006830601092896175 +2006,Fla,18,F,0.0003716896391513087,0.001223241590214067 +2006,Fla,19,M,0.0009942974119023249,0.0 +2006,Fla,19,F,0.00021681895617159668,0.0 +2006,Fla,20,M,0.000937944388974615,0.0006313131313131314 +2006,Fla,20,F,0.00022063922334993375,0.0 +2006,Fla,21,M,0.0007113007913221303,0.0005698005698005698 +2006,Fla,21,F,0.0002783189535207348,0.0 +2006,Fla,22,M,0.0008683319343541058,0.0005473453749315818 +2006,Fla,22,F,0.00014960205852432531,0.0 +2006,Fla,23,M,0.0008169934640522876,0.0004675081813931744 +2006,Fla,23,F,0.0002074996294649474,0.0003536067892503536 +2006,Fla,24,M,0.0006849690393994193,0.0004206983592763989 +2006,Fla,24,F,0.0003183423047982868,0.0 +2006,Fla,25,M,0.0008666480290746433,0.0007686395080707147 +2006,Fla,25,F,0.0003735202850247098,0.0009526833915528741 +2006,Fla,26,M,0.000802523798981625,0.0 +2006,Fla,26,F,0.0002031163856889998,0.0 +2006,Fla,27,M,0.0008529269610212379,0.001757469244288225 +2006,Fla,27,F,0.00014567491186667832,0.0 +2006,Fla,28,M,0.0006686046511627907,0.001025641025641026 +2006,Fla,28,F,0.0004431052818149593,0.0 +2006,Fla,29,M,0.0005308638334267262,0.001339584728734093 +2006,Fla,29,F,0.0003658090476771127,0.0006220839813374805 +2006,Fla,30,M,0.0009975213106825462,0.001317957166392092 +2006,Fla,30,F,0.00046755189826070683,0.0 +2006,Fla,31,M,0.0009596928982725527,0.0006224712107065049 +2006,Fla,31,F,0.0005925750348137832,0.0 +2006,Fla,32,M,0.001200714844186306,0.00031007751937984503 +2006,Fla,32,F,0.0005169888272970101,0.0 +2006,Fla,33,M,0.0009352287302265926,0.0011816838995568687 +2006,Fla,33,F,0.0002713262426741915,0.0006053268765133173 +2006,Fla,34,M,0.001121933805905452,0.0006079027355623103 +2006,Fla,34,F,0.0002571818018157035,0.0 +2006,Fla,35,M,0.001134178213915874,0.0008663008951775916 +2006,Fla,35,F,0.0006309307490409853,0.0008708272859216256 +2006,Fla,36,M,0.001107855929491125,0.0005765350245027388 +2006,Fla,36,F,0.0005791408571284688,0.0006047777441790142 +2006,Fla,37,M,0.001143329765495767,0.0005878894767783657 +2006,Fla,37,F,0.0005227781926811051,0.0 +2006,Fla,38,M,0.0013146157096577313,0.0 +2006,Fla,38,F,0.0008560387418676317,0.0009702457956015523 +2006,Fla,39,M,0.0014135886912904699,0.001146460303811981 +2006,Fla,39,F,0.0007709379745356853,0.0009658725048293627 +2006,Fla,40,M,0.0011466625504421267,0.001493875112040634 +2006,Fla,40,F,0.0007703811120677934,0.0003363605785401951 +2006,Fla,41,M,0.001336359586789131,0.00231548480463097 +2006,Fla,41,F,0.0009073822023462312,0.0006942034015966678 +2006,Fla,42,M,0.0013622818220519366,0.001296176279974077 +2006,Fla,42,F,0.0009612233752048062,0.0007648183556405354 +2006,Fla,43,M,0.001943592622986222,0.002286834367853643 +2006,Fla,43,F,0.001329993571697737,0.00038986354775828464 +2006,Fla,44,M,0.002288878231678075,0.002061855670103093 +2006,Fla,44,F,0.001320771330456987,0.0004177109440267335 +2006,Fla,45,M,0.0019789651568719014,0.0027894002789400282 +2006,Fla,45,F,0.001511187297004692,0.00042390843577787203 +2006,Fla,46,M,0.002540294323756132,0.002276176024279211 +2006,Fla,46,F,0.001779399007985053,0.001347708894878706 +2006,Fla,47,M,0.0026353403609076288,0.002552881108679796 +2006,Fla,47,F,0.001625048637019066,0.001003512293025589 +2006,Fla,48,M,0.003089504770558837,0.0032206119162640893 +2006,Fla,48,F,0.001815600195526175,0.0031201248049922 +2006,Fla,49,M,0.003209408016492141,0.005691056910569106 +2006,Fla,49,F,0.002168226061134548,0.0021917808219178076 +2006,Fla,50,M,0.003547703516750399,0.002079002079002079 +2006,Fla,50,F,0.002531766504251457,0.001695873374788016 +2006,Fla,51,M,0.0038421321401648717,0.005145797598627789 +2006,Fla,51,F,0.002164874904671702,0.004653868528214078 +2006,Fla,52,M,0.004509330077979022,0.0046296296296296285 +2006,Fla,52,F,0.0033874993632519988,0.003680981595092025 +2006,Fla,53,M,0.004304412022322881,0.005591798695246971 +2006,Fla,53,F,0.0032574960884397372,0.003683241252302026 +2006,Fla,54,M,0.006383984867591425,0.004789272030651341 +2006,Fla,54,F,0.0034701831188938127,0.00319693094629156 +2006,Fla,55,M,0.006005284650492433,0.004385964912280702 +2006,Fla,55,F,0.0034836669614384877,0.0018703241895261847 +2006,Fla,56,M,0.005820473113686122,0.005507113354749885 +2006,Fla,56,F,0.003871037600498092,0.003182686187141948 +2006,Fla,57,M,0.007532098533787225,0.007733204446592556 +2006,Fla,57,F,0.004149821959251425,0.005870841487279843 +2006,Fla,58,M,0.008417965567805354,0.007905138339920948 +2006,Fla,58,F,0.004233148811462064,0.0057915057915057895 +2006,Fla,59,M,0.009468588754720996,0.010199125789218073 +2006,Fla,59,F,0.004521255250274218,0.007719298245614035 +2006,Fla,60,M,0.010566037735849059,0.01191185229303157 +2006,Fla,60,F,0.005713775555753951,0.006309148264984227 +2006,Fla,61,M,0.01116037303164654,0.013197360527894421 +2006,Fla,61,F,0.00495629449400739,0.006574141709276843 +2006,Fla,62,M,0.011500177173597907,0.012232415902140671 +2006,Fla,62,F,0.005896004516088566,0.008210180623973728 +2006,Fla,63,M,0.01257092001334965,0.009635237439779766 +2006,Fla,63,F,0.005037239592703199,0.008628127696289905 +2006,Fla,64,M,0.01471811076001996,0.016081871345029242 +2006,Fla,64,F,0.0077827129436735965,0.006685768863419293 +2006,Fla,65,M,0.01578486934692481,0.01724137931034483 +2006,Fla,65,F,0.007277245296414625,0.00641025641025641 +2006,Fla,66,M,0.01509433962264151,0.014797507788162 +2006,Fla,66,F,0.007634807053411704,0.005934718100890208 +2006,Fla,67,M,0.018001093045498018,0.01811023622047244 +2006,Fla,67,F,0.008969734985102713,0.011 +2006,Fla,68,M,0.01773669747689233,0.01962533452274755 +2006,Fla,68,F,0.008853894406691059,0.009404388714733545 +2006,Fla,69,M,0.020516090315805268,0.01789077212806026 +2006,Fla,69,F,0.01078618564298395,0.008611410118406888 +2006,Fla,70,M,0.02401260181343169,0.01825168107588857 +2006,Fla,70,F,0.01167380815816998,0.007471980074719802 +2006,Fla,71,M,0.0269765995490943,0.02023429179978701 +2006,Fla,71,F,0.01329734053189362,0.017751479289940832 +2006,Fla,72,M,0.03000917833911968,0.01904761904761905 +2006,Fla,72,F,0.01407214929301792,0.015018773466833541 +2006,Fla,73,M,0.03194734307272435,0.027027027027027032 +2006,Fla,73,F,0.01760759286532483,0.02127659574468085 +2006,Fla,74,M,0.036754335020326885,0.034610630407911014 +2006,Fla,74,F,0.01885226857844602,0.02631578947368421 +2006,Fla,75,M,0.04236586322625637,0.03753351206434316 +2006,Fla,75,F,0.0222545897974392,0.028694404591104738 +2006,Fla,76,M,0.04478200828565792,0.051643192488262914 +2006,Fla,76,F,0.0250239905514136,0.017301038062283742 +2006,Fla,77,M,0.05207559188873554,0.04861111111111111 +2006,Fla,77,F,0.02676709154113558,0.025906735751295342 +2006,Fla,78,M,0.0589253765799042,0.06237424547283703 +2006,Fla,78,F,0.03428337092474882,0.03333333333333334 +2006,Fla,79,M,0.06404374332222991,0.06864988558352403 +2006,Fla,79,F,0.03949513102352991,0.034 +2006,Fla,80,M,0.0708099173553719,0.06053811659192825 +2006,Fla,80,F,0.04143828107871081,0.03355704697986577 +2006,Fla,81,M,0.07850081156854065,0.096 +2006,Fla,81,F,0.05185462019994394,0.0488997555012225 +2006,Fla,82,M,0.09132081686429512,0.1130952380952381 +2006,Fla,82,F,0.057531431926031024,0.05303030303030303 +2006,Fla,83,M,0.09785700739616916,0.1030927835051546 +2006,Fla,83,F,0.06562054208273893,0.09646302250803858 +2006,Fla,84,M,0.1148516995020567,0.1106382978723404 +2006,Fla,84,F,0.0761741798442294,0.06228373702422145 +2006,Fla,85,M,0.1233906947100064,0.1262135922330097 +2006,Fla,85,F,0.09030012477835424,0.08433734939759037 +2006,Fla,86,M,0.1384794414274632,0.1311475409836066 +2006,Fla,86,F,0.1052132701421801,0.1320754716981132 +2006,Fla,87,M,0.1556393555022283,0.1318681318681319 +2006,Fla,87,F,0.1156390977443609,0.1031746031746032 +2006,Fla,88,M,0.1578498293515358,0.1166666666666667 +2006,Fla,88,F,0.1340929009640666,0.0761904761904762 +2006,Fla,89,M,0.1952846975088968,0.1 +2006,Fla,89,F,0.14494540331102498,0.1264367816091954 +2006,Fla,90,M,0.199097065462754,0.1111111111111111 +2006,Fla,90,F,0.1534679543459175,0.1375 +2006,Fla,91,M,0.23,0.2105263157894737 +2006,Fla,91,F,0.17135596296968605,0.15 +2006,Fla,92,M,0.2362555720653789,0.32 +2006,Fla,92,F,0.1965405405405406,0.1774193548387097 +2006,Fla,93,M,0.2520161290322581,0.4117647058823529 +2006,Fla,93,F,0.2179882319977585,0.18032786885245894 +2006,Fla,94,M,0.2682563338301044,0.1333333333333333 +2006,Fla,94,F,0.2300990099009901,0.1481481481481482 +2006,Fla,95,M,0.3091286307053942,0.09090909090909093 +2006,Fla,95,F,0.2759347024749869,0.3448275862068966 +2006,Fla,96,M,0.3345323741007194,0.1428571428571429 +2006,Fla,96,F,0.2703533026113672,0.2380952380952381 +2006,Fla,97,M,0.2972972972972973,0.4285714285714286 +2006,Fla,97,F,0.3118062563067609,0.2857142857142857 +2006,Fla,98,M,0.3464566929133858,0.0 +2006,Fla,98,F,0.34626865671641804,0.25 +2006,Fla,99,M,0.423728813559322,1.0 +2006,Fla,99,F,0.340153452685422,0.0 +2006,Fla,100,M,0.4423076923076923,0.0 +2006,Fla,100,F,0.3503649635036497,0.4166666666666667 +2006,Fla,101,M,0.2,0.0 +2006,Fla,101,F,0.4242424242424243,0.0 +2006,Fla,102,M,0.4,0.0 +2006,Fla,102,F,0.4545454545454545,0.3333333333333333 +2006,Fla,103,M,0.3333333333333333,0.0 +2006,Fla,103,F,0.4509803921568628,0.5 +2006,Fla,104,M,0.0,0.0 +2006,Fla,104,F,0.4838709677419355,1.0 +2006,Fla,105,M,0.0,0.0 +2006,Fla,105,F,0.5454545454545454,0.0 +2006,Fla,106,M,1.0,0.0 +2006,Fla,106,F,0.3333333333333333,0.0 +2006,Fla,107,M,0.0,0.0 +2006,Fla,107,F,0.25,0.0 +2006,Fla,108,M,0.0,0.0 +2006,Fla,108,F,0.5,0.0 +2006,Fla,109,M,0.0,0.0 +2006,Fla,109,F,0.0,0.0 +2006,Fla,110,M,0.0,0.0 +2006,Fla,110,F,0.0,0.0 +2006,Fla,111,M,0.0,0.0 +2006,Fla,111,F,0.0,0.0 +2006,Fla,112,M,0.0,0.0 +2006,Fla,112,F,0.0,0.0 +2006,Fla,113,M,0.0,0.0 +2006,Fla,113,F,0.0,0.0 +2006,Fla,114,M,0.0,0.0 +2006,Fla,114,F,0.0,0.0 +2006,Fla,115,M,0.0,0.0 +2006,Fla,115,F,0.0,0.0 +2006,Fla,116,M,0.0,0.0 +2006,Fla,116,F,0.0,0.0 +2006,Fla,117,M,0.0,0.0 +2006,Fla,117,F,0.0,0.0 +2006,Fla,118,M,0.0,0.0 +2006,Fla,118,F,0.0,0.0 +2006,Fla,119,M,0.0,0.0 +2006,Fla,119,F,0.0,0.0 +2006,Fla,120,M,0.0,0.0 +2006,Fla,120,F,0.0,0.0 +2006,Wal,0,M,0.0008925290071927338,0.001280409731113957 +2006,Wal,0,F,0.0006059604473089848,0.001283697047496791 +2006,Wal,1,M,0.0002605387942264603,0.0 +2006,Wal,1,F,0.0002213736233327799,0.001165501165501166 +2006,Wal,2,M,0.0002111040743086342,0.0 +2006,Wal,2,F,0.0002178411937697419,0.0 +2006,Wal,3,M,0.00020865936358894108,0.0 +2006,Wal,3,F,0.0,0.0 +2006,Wal,4,M,0.00010066945185483459,0.0 +2006,Wal,4,F,0.0001044604617152408,0.0 +2006,Wal,5,M,0.0001479217001134067,0.0 +2006,Wal,5,F,0.00015550487248600458,0.001145475372279496 +2006,Wal,6,M,0.0003034901365705615,0.0 +2006,Wal,6,F,0.0001595574938836294,0.0 +2006,Wal,7,M,0.00010124019235636551,0.0 +2006,Wal,7,F,0.0001061683830555261,0.0 +2006,Wal,8,M,0.0001010356150543066,0.0 +2006,Wal,8,F,5.260112566408921e-05,0.0 +2006,Wal,9,M,0.0001992825827022718,0.0 +2006,Wal,9,F,5.224387440572593e-05,0.0 +2006,Wal,10,M,0.0003579281075829627,0.0009910802775024775 +2006,Wal,10,F,0.0001063603488619443,0.0 +2006,Wal,11,M,0.0002021835826930853,0.0 +2006,Wal,11,F,5.317734645041213e-05,0.00102880658436214 +2006,Wal,12,M,0.00029163021289005554,0.0 +2006,Wal,12,F,0.000256647161482394,0.0 +2006,Wal,13,M,9.249838127832763e-05,0.0 +2006,Wal,13,F,0.0003387533875338754,0.0 +2006,Wal,14,M,4.525501199257818e-05,0.0 +2006,Wal,14,F,9.388349058818007e-05,0.0 +2006,Wal,15,M,0.0004584632312488538,0.0008203445447087777 +2006,Wal,15,F,0.00014340344168260042,0.0008944543828264757 +2006,Wal,16,M,0.0003663842454774445,0.0 +2006,Wal,16,F,0.0002876732032411181,0.0 +2006,Wal,17,M,0.001109416169740674,0.0008097165991902834 +2006,Wal,17,F,0.0002920845097848311,0.0 +2006,Wal,18,M,0.0007654037504783774,0.000782472613458529 +2006,Wal,18,F,0.00025095362377032727,0.0 +2006,Wal,19,M,0.0006719462443004557,0.002235469448584203 +2006,Wal,19,F,0.0004044080477201497,0.0 +2006,Wal,20,M,0.001201622189956441,0.001609010458567981 +2006,Wal,20,F,0.0001570598397989634,0.0 +2006,Wal,21,M,0.0009170572651314448,0.0007127583749109052 +2006,Wal,21,F,0.0002118307472329609,0.0 +2006,Wal,22,M,0.0014958477330169696,0.001265022137887413 +2006,Wal,22,F,0.0003878975950349108,0.0 +2006,Wal,23,M,0.001188630490956073,0.0 +2006,Wal,23,F,0.00010744600838078873,0.00048590864917395527 +2006,Wal,24,M,0.001352827930693585,0.0005512679162072766 +2006,Wal,24,F,0.0005333617792948957,0.0004568296025582458 +2006,Wal,25,M,0.001418961530376288,0.0004878048780487805 +2006,Wal,25,F,0.0003249214773096502,0.0 +2006,Wal,26,M,0.001506834571090303,0.0 +2006,Wal,26,F,0.0002825177986213132,0.0 +2006,Wal,27,M,0.001216007074950254,0.0009021199819576004 +2006,Wal,27,F,0.0004558924093913836,0.0004438526409232135 +2006,Wal,28,M,0.001535845537820197,0.0004508566275924256 +2006,Wal,28,F,0.000676056338028169,0.0 +2006,Wal,29,M,0.0008143322475570032,0.0004315925766076824 +2006,Wal,29,F,0.0004392949316347263,0.0004512635379061372 +2006,Wal,30,M,0.001132624993258185,0.0008665511265164642 +2006,Wal,30,F,0.000487752005202688,0.000423190859077444 +2006,Wal,31,M,0.0013943400123941339,0.00038431975403535736 +2006,Wal,31,F,0.0007852580881583081,0.000390015600624025 +2006,Wal,32,M,0.001479946721918011,0.0003534817956875221 +2006,Wal,32,F,0.0005984440454817472,0.0 +2006,Wal,33,M,0.0019059417734788207,0.001338688085676038 +2006,Wal,33,F,0.0005752636625119846,0.0 +2006,Wal,34,M,0.001593550806149232,0.0003317850033178501 +2006,Wal,34,F,0.0008397872538956798,0.0 +2006,Wal,35,M,0.00166042032354476,0.001700102006120367 +2006,Wal,35,F,0.0008170327293699236,0.0003494060097833683 +2006,Wal,36,M,0.002048301814890678,0.001660026560424967 +2006,Wal,36,F,0.001094091903719912,0.0006995452955578874 +2006,Wal,37,M,0.002187971021539359,0.002306425041186162 +2006,Wal,37,F,0.0005740802755585322,0.0003385240352064997 +2006,Wal,38,M,0.0021378687823649573,0.000976880494952784 +2006,Wal,38,F,0.0009909867396536264,0.0003561253561253562 +2006,Wal,39,M,0.002048894062863795,0.0008896797153024912 +2006,Wal,39,F,0.001155535012710885,0.0009538950715421305 +2006,Wal,40,M,0.002336658578233127,0.002030162412993039 +2006,Wal,40,F,0.001289576663109214,0.001021102791014295 +2006,Wal,41,M,0.003037798897712971,0.0039767513000917715 +2006,Wal,41,F,0.001160292221744736,0.001013856032443393 +2006,Wal,42,M,0.003138676451085275,0.0018348623853211008 +2006,Wal,42,F,0.001169894709476147,0.001727712508638563 +2006,Wal,43,M,0.002496368917937546,0.002547770700636943 +2006,Wal,43,F,0.0014110591762942061,0.0018539117538005192 +2006,Wal,44,M,0.0050011064394777606,0.002578150177247825 +2006,Wal,44,F,0.002151462994836489,0.001100513573000734 +2006,Wal,45,M,0.004145493447445841,0.004118858487790527 +2006,Wal,45,F,0.00175561797752809,0.001534330648254699 +2006,Wal,46,M,0.004857181052537764,0.0027976375505129013 +2006,Wal,46,F,0.002168828407399532,0.002370604504148557 +2006,Wal,47,M,0.005302515295717199,0.003745318352059925 +2006,Wal,47,F,0.002726800554016621,0.001620745542949757 +2006,Wal,48,M,0.00538847694929305,0.002553463134375998 +2006,Wal,48,F,0.002881333392437609,0.001281503630926955 +2006,Wal,49,M,0.005484892902737718,0.0049367479173094714 +2006,Wal,49,F,0.002777155655095185,0.0020669698222405947 +2006,Wal,50,M,0.006989993776032939,0.00293446364525595 +2006,Wal,50,F,0.0036049026676279743,0.001713796058269066 +2006,Wal,51,M,0.006340057636887607,0.002659574468085107 +2006,Wal,51,F,0.0036834924965893604,0.0008756567425569178 +2006,Wal,52,M,0.00810994560994561,0.002401372212692968 +2006,Wal,52,F,0.003513151204178801,0.005137786081270434 +2006,Wal,53,M,0.008813826382392044,0.0049382716049382715 +2006,Wal,53,F,0.0038080015043956564,0.0013999066728884741 +2006,Wal,54,M,0.007716680294358136,0.005852231163130944 +2006,Wal,54,F,0.004169062679700977,0.0009372071227741332 +2006,Wal,55,M,0.009213184214415924,0.006590992310508971 +2006,Wal,55,F,0.00466911239220544,0.004189944134078211 +2006,Wal,56,M,0.009660873462476969,0.008270676691729324 +2006,Wal,56,F,0.004437022900763359,0.004529441368897836 +2006,Wal,57,M,0.009874370631079826,0.00561377245508982 +2006,Wal,57,F,0.0064844835572024076,0.00326644890340644 +2006,Wal,58,M,0.0119994074366698,0.011278195488721807 +2006,Wal,58,F,0.005594208349003385,0.0020387359836901123 +2006,Wal,59,M,0.01385351940511358,0.006565449322938038 +2006,Wal,59,F,0.0061488979282943905,0.0021893814997263287 +2006,Wal,60,M,0.013293842127014741,0.01129363449691992 +2006,Wal,60,F,0.006313443921762813,0.004510309278350515 +2006,Wal,61,M,0.014750692520775632,0.00932642487046632 +2006,Wal,61,F,0.009047769693135085,0.006361323155216286 +2006,Wal,62,M,0.016421715656868632,0.009340338587273787 +2006,Wal,62,F,0.008286176232821341,0.006997900629811057 +2006,Wal,63,M,0.01748614958448754,0.01109741060419235 +2006,Wal,63,F,0.009115488605639243,0.007874015748031496 +2006,Wal,64,M,0.017157322332645792,0.02044728434504793 +2006,Wal,64,F,0.00902601132354148,0.009737827715355809 +2006,Wal,65,M,0.01962766405526072,0.01943967981703831 +2006,Wal,65,F,0.009187798603454613,0.006853582554517134 +2006,Wal,66,M,0.021607128775333183,0.01833740831295844 +2006,Wal,66,F,0.009330111424352262,0.00438871473354232 +2006,Wal,67,M,0.02325766626841896,0.02223719676549865 +2006,Wal,67,F,0.01226139978791093,0.014879107253564791 +2006,Wal,68,M,0.02358136821931506,0.02229508196721312 +2006,Wal,68,F,0.012733924299985927,0.0055248618784530384 +2006,Wal,69,M,0.02709338009644893,0.02603800140745954 +2006,Wal,69,F,0.014249255635899618,0.01267605633802817 +2006,Wal,70,M,0.03194888178913738,0.03345195729537367 +2006,Wal,70,F,0.015373563218390809,0.0174146014735432 +2006,Wal,71,M,0.03297777777777778,0.02011922503725782 +2006,Wal,71,F,0.01488053653765544,0.01006036217303823 +2006,Wal,72,M,0.03644380455322596,0.02917981072555205 +2006,Wal,72,F,0.01955716979814207,0.01683501683501684 +2006,Wal,73,M,0.03864905593475757,0.04634721131186174 +2006,Wal,73,F,0.02009364026531409,0.01745454545454546 +2006,Wal,74,M,0.04243723755918878,0.036681222707423584 +2006,Wal,74,F,0.02185404847859722,0.0157819225251076 +2006,Wal,75,M,0.0494890234670704,0.05166666666666666 +2006,Wal,75,F,0.02729448289243904,0.02517482517482518 +2006,Wal,76,M,0.05281837160751567,0.06233062330623306 +2006,Wal,76,F,0.0316067947646895,0.029126213592233014 +2006,Wal,77,M,0.06022752621012715,0.06613226452905811 +2006,Wal,77,F,0.03589309639658698,0.03285256410256411 +2006,Wal,78,M,0.061368812177873676,0.08040201005025126 +2006,Wal,78,F,0.03864056150720355,0.03748981255093725 +2006,Wal,79,M,0.07854209445585215,0.08066298342541436 +2006,Wal,79,F,0.04523755398954308,0.04637917005695687 +2006,Wal,80,M,0.07938031258568687,0.09819121447028424 +2006,Wal,80,F,0.04980901451489687,0.05086206896551724 +2006,Wal,81,M,0.08632218844984803,0.08811188811188811 +2006,Wal,81,F,0.05815568079719024,0.0576171875 +2006,Wal,82,M,0.1024568740198641,0.1105845181674566 +2006,Wal,82,F,0.06484313554137901,0.06289308176100629 +2006,Wal,83,M,0.11234640140433,0.10727969348659 +2006,Wal,83,F,0.07408442829186469,0.07602339181286549 +2006,Wal,84,M,0.1148230088495575,0.103448275862069 +2006,Wal,84,F,0.08371818807114081,0.09423347398030944 +2006,Wal,85,M,0.1440721649484536,0.1724137931034483 +2006,Wal,85,F,0.09526923915413124,0.08995502248875563 +2006,Wal,86,M,0.1388540359682141,0.1412429378531074 +2006,Wal,86,F,0.09522229595222297,0.09156626506024096 +2006,Wal,87,M,0.1583577712609971,0.154639175257732 +2006,Wal,87,F,0.1301134864080232,0.1565217391304348 +2006,Wal,88,M,0.1925182481751825,0.1298701298701299 +2006,Wal,88,F,0.1420209488601356,0.103448275862069 +2006,Wal,89,M,0.1843409316154609,0.24 +2006,Wal,89,F,0.1548494983277592,0.16402116402116398 +2006,Wal,90,M,0.24429967426710106,0.2807017543859649 +2006,Wal,90,F,0.1569878749202297,0.1642512077294686 +2006,Wal,91,M,0.2534090909090909,0.2985074626865672 +2006,Wal,91,F,0.17748640869843302,0.2323232323232323 +2006,Wal,92,M,0.2369668246445498,0.4347826086956522 +2006,Wal,92,F,0.201803349076857,0.17449664429530198 +2006,Wal,93,M,0.3102625298329356,0.2631578947368421 +2006,Wal,93,F,0.2206748794858061,0.1304347826086957 +2006,Wal,94,M,0.2786885245901639,0.2777777777777778 +2006,Wal,94,F,0.253968253968254,0.2560975609756098 +2006,Wal,95,M,0.3526570048309179,0.2727272727272727 +2006,Wal,95,F,0.2713414634146342,0.24 +2006,Wal,96,M,0.359375,0.0 +2006,Wal,96,F,0.2711370262390671,0.2592592592592593 +2006,Wal,97,M,0.3015873015873016,0.5714285714285714 +2006,Wal,97,F,0.3313492063492064,0.4137931034482759 +2006,Wal,98,M,0.3333333333333333,0.5 +2006,Wal,98,F,0.3362068965517242,0.3333333333333333 +2006,Wal,99,M,0.5,0.0 +2006,Wal,99,F,0.3598130841121495,0.1 +2006,Wal,100,M,0.2352941176470588,0.3333333333333333 +2006,Wal,100,F,0.3795620437956204,0.6 +2006,Wal,101,M,0.75,0.0 +2006,Wal,101,F,0.4142857142857143,0.6 +2006,Wal,102,M,0.3333333333333333,1.0 +2006,Wal,102,F,0.36,0.0 +2006,Wal,103,M,0.0,0.0 +2006,Wal,103,F,0.35,0.6666666666666666 +2006,Wal,104,M,0.0,0.0 +2006,Wal,104,F,0.5333333333333333,0.0 +2006,Wal,105,M,0.0,0.0 +2006,Wal,105,F,0.5,0.5 +2006,Wal,106,M,0.0,0.0 +2006,Wal,106,F,0.5714285714285714,0.0 +2006,Wal,107,M,0.0,0.0 +2006,Wal,107,F,1.0,0.0 +2006,Wal,108,M,0.0,0.0 +2006,Wal,108,F,0.0,0.0 +2006,Wal,109,M,0.0,0.0 +2006,Wal,109,F,0.0,0.0 +2006,Wal,110,M,0.0,0.0 +2006,Wal,110,F,0.0,0.0 +2006,Wal,111,M,0.0,0.0 +2006,Wal,111,F,0.0,0.0 +2006,Wal,112,M,0.0,0.0 +2006,Wal,112,F,0.0,0.0 +2006,Wal,113,M,0.0,0.0 +2006,Wal,113,F,0.0,0.0 +2006,Wal,114,M,0.0,0.0 +2006,Wal,114,F,0.0,0.0 +2006,Wal,115,M,0.0,0.0 +2006,Wal,115,F,0.0,0.0 +2006,Wal,116,M,0.0,0.0 +2006,Wal,116,F,0.0,0.0 +2006,Wal,117,M,0.0,0.0 +2006,Wal,117,F,0.0,0.0 +2006,Wal,118,M,0.0,0.0 +2006,Wal,118,F,0.0,0.0 +2006,Wal,119,M,0.0,0.0 +2006,Wal,119,F,0.0,0.0 +2006,Wal,120,M,0.0,0.0 +2006,Wal,120,F,0.0,0.0 +2007,BruCap,0,M,0.0007619628162145687,0.001669449081803005 +2007,BruCap,0,F,0.0003266372693124286,0.001140901312036509 +2007,BruCap,1,M,0.0001638538423726036,0.0005793742757821553 +2007,BruCap,1,F,0.0001707358716066246,0.0 +2007,BruCap,2,M,0.000169606512890095,0.0 +2007,BruCap,2,F,0.000176056338028169,0.000643915003219575 +2007,BruCap,3,M,0.0005472455308281649,0.0 +2007,BruCap,3,F,0.0,0.0 +2007,BruCap,4,M,0.0,0.0 +2007,BruCap,4,F,0.0,0.0 +2007,BruCap,5,M,0.0,0.0 +2007,BruCap,5,F,0.0,0.0 +2007,BruCap,6,M,0.0,0.0 +2007,BruCap,6,F,0.0,0.0 +2007,BruCap,7,M,0.0002003205128205128,0.0 +2007,BruCap,7,F,0.0,0.0 +2007,BruCap,8,M,0.0,0.0008368200836820082 +2007,BruCap,8,F,0.0,0.0 +2007,BruCap,9,M,0.0,0.0 +2007,BruCap,9,F,0.0004385964912280702,0.0 +2007,BruCap,10,M,0.0,0.0 +2007,BruCap,10,F,0.0,0.0 +2007,BruCap,11,M,0.0,0.0 +2007,BruCap,11,F,0.00022763487366264515,0.0 +2007,BruCap,12,M,0.0002132650885050117,0.000877963125548727 +2007,BruCap,12,F,0.0,0.0 +2007,BruCap,13,M,0.00021519259737465038,0.0 +2007,BruCap,13,F,0.0,0.0 +2007,BruCap,14,M,0.0002150537634408602,0.0008695652173913044 +2007,BruCap,14,F,0.00022441651705565533,0.0 +2007,BruCap,15,M,0.0,0.0 +2007,BruCap,15,F,0.0,0.0 +2007,BruCap,16,M,0.0,0.0008718395815170009 +2007,BruCap,16,F,0.0,0.0 +2007,BruCap,17,M,0.0004371584699453552,0.0 +2007,BruCap,17,F,0.00022411474675033618,0.0 +2007,BruCap,18,M,0.00043299415457891317,0.0 +2007,BruCap,18,F,0.0006762849413886385,0.0 +2007,BruCap,19,M,0.0008824178248400617,0.0 +2007,BruCap,19,F,0.0008804754567466431,0.0 +2007,BruCap,20,M,0.001773049645390071,0.0013227513227513233 +2007,BruCap,20,F,0.0,0.0 +2007,BruCap,21,M,0.0006724949562878277,0.001272264631043257 +2007,BruCap,21,F,0.0004616805170821791,0.0004349717268377556 +2007,BruCap,22,M,0.0006565988181221272,0.0 +2007,BruCap,22,F,0.0002111932418162619,0.0 +2007,BruCap,23,M,0.000649772579597141,0.0010224948875255618 +2007,BruCap,23,F,0.0006234413965087283,0.00036010082823190496 +2007,BruCap,24,M,0.0008297033810412777,0.0004219409282700422 +2007,BruCap,24,F,0.00038857586943850784,0.0003272251308900524 +2007,BruCap,25,M,0.0009509319132750091,0.0007604562737642585 +2007,BruCap,25,F,0.0,0.0 +2007,BruCap,26,M,0.0001825150574922431,0.0006605019815059445 +2007,BruCap,26,F,0.0003466805338880221,0.0 +2007,BruCap,27,M,0.0005402485143165856,0.0003111387678904792 +2007,BruCap,27,F,0.0001769285208775655,0.0002643404705260375 +2007,BruCap,28,M,0.0005467468562055769,0.0002891844997108155 +2007,BruCap,28,F,0.0005303164221318722,0.0005300821627352238 +2007,BruCap,29,M,0.0009225092250922508,0.0008457851705666763 +2007,BruCap,29,F,0.0,0.0005303632988597188 +2007,BruCap,30,M,0.0003770028275212065,0.0005264543300868648 +2007,BruCap,30,F,0.0003682563063892469,0.0 +2007,BruCap,31,M,0.0009498480243161092,0.0 +2007,BruCap,31,F,0.0005941770647653001,0.0 +2007,BruCap,32,M,0.001338944146901301,0.0008058017727639 +2007,BruCap,32,F,0.0004020908725371933,0.0002760905577029266 +2007,BruCap,33,M,0.0007517383950385268,0.001085481682496608 +2007,BruCap,33,F,0.0009609840476648087,0.0002876042565429968 +2007,BruCap,34,M,0.0007500468779298706,0.001089028042472094 +2007,BruCap,34,F,0.0007980845969672786,0.0 +2007,BruCap,35,M,0.000946611132146914,0.0005558643690939412 +2007,BruCap,35,F,0.001401962747846986,0.0003075030750307503 +2007,BruCap,36,M,0.001137872179025223,0.0008101539292465569 +2007,BruCap,36,F,0.0007988815658078692,0.001550387596899225 +2007,BruCap,37,M,0.001357641582622188,0.0008831321754489256 +2007,BruCap,37,F,0.0012406947890818859,0.0003189792663476873 +2007,BruCap,38,M,0.0019790223629527013,0.001181334908446545 +2007,BruCap,38,F,0.001506024096385542,0.0006851661527920522 +2007,BruCap,39,M,0.002426693629929222,0.0003156565656565657 +2007,BruCap,39,F,0.00065359477124183,0.0007415647015202076 +2007,BruCap,40,M,0.002054653790836244,0.001302083333333333 +2007,BruCap,40,F,0.0010497585555322279,0.0007701193685021178 +2007,BruCap,41,M,0.0009817396426467704,0.001363791339924992 +2007,BruCap,41,F,0.001034554107179805,0.0 +2007,BruCap,42,M,0.001977848101265823,0.001036627505183138 +2007,BruCap,42,F,0.0014341323499282939,0.00041017227235438887 +2007,BruCap,43,M,0.002062280882656218,0.0011614401858304302 +2007,BruCap,43,F,0.0027270820222362077,0.000437636761487965 +2007,BruCap,44,M,0.002134927412467976,0.0008071025020177562 +2007,BruCap,44,F,0.00231286795626577,0.0004743833017077799 +2007,BruCap,45,M,0.003472222222222222,0.0016863406408094439 +2007,BruCap,45,F,0.0027559889760440967,0.001955034213098729 +2007,BruCap,46,M,0.0031466331025802397,0.002277904328018223 +2007,BruCap,46,F,0.001821125050586807,0.0009657170449058426 +2007,BruCap,47,M,0.003019844693701467,0.0009601536245799329 +2007,BruCap,47,F,0.002071251035625518,0.002092050209205021 +2007,BruCap,48,M,0.006746120980436249,0.002010050251256282 +2007,BruCap,48,F,0.0018568186507117808,0.002357100766057749 +2007,BruCap,49,M,0.0057313159101329645,0.0016759776536312847 +2007,BruCap,49,F,0.001486830926083263,0.0011750881316098714 +2007,BruCap,50,M,0.00559310184106269,0.001661129568106313 +2007,BruCap,50,F,0.003178639542275906,0.005454545454545455 +2007,BruCap,51,M,0.006708304418228082,0.005151688609044075 +2007,BruCap,51,F,0.0027460920997042677,0.001924310455420141 +2007,BruCap,52,M,0.005210800568450971,0.002582311168495804 +2007,BruCap,52,F,0.004507405022537025,0.0013236267372600929 +2007,BruCap,53,M,0.005861664712778429,0.001355013550135502 +2007,BruCap,53,F,0.003252385082393756,0.0013783597518952446 +2007,BruCap,54,M,0.0066429418742586,0.006040268456375839 +2007,BruCap,54,F,0.004552352048558422,0.002032520325203252 +2007,BruCap,55,M,0.011071967790639159,0.005359877488514547 +2007,BruCap,55,F,0.005560704355885079,0.003837298541826554 +2007,BruCap,56,M,0.009751090582499358,0.003474635163307853 +2007,BruCap,56,F,0.0064761054041983035,0.0028653295128939827 +2007,BruCap,57,M,0.008031088082901554,0.006891271056661562 +2007,BruCap,57,F,0.00507380073800738,0.003149606299212599 +2007,BruCap,58,M,0.011455350169226771,0.006106870229007634 +2007,BruCap,58,F,0.005563282336578581,0.005604483586869495 +2007,BruCap,59,M,0.008714021653023502,0.009508716323296357 +2007,BruCap,59,F,0.0063006300630063,0.0057851239669421475 +2007,BruCap,60,M,0.014941302027748132,0.012048192771084341 +2007,BruCap,60,F,0.007517030772844727,0.0033500837520938037 +2007,BruCap,61,M,0.01591263650546022,0.022633744855967083 +2007,BruCap,61,F,0.006347527109230362,0.006653992395437262 +2007,BruCap,62,M,0.01436695600119725,0.009268795056642637 +2007,BruCap,62,F,0.01014040561622465,0.004854368932038835 +2007,BruCap,63,M,0.015132002575660018,0.01224944320712695 +2007,BruCap,63,F,0.01010652827096422,0.004282655246252678 +2007,BruCap,64,M,0.01712204007285975,0.017103762827822118 +2007,BruCap,64,F,0.0100250626566416,0.00576036866359447 +2007,BruCap,65,M,0.01539119281744335,0.01464713715046605 +2007,BruCap,65,F,0.0075867052023121375,0.0078023407022106625 +2007,BruCap,66,M,0.02429906542056075,0.02088452088452089 +2007,BruCap,66,F,0.01027717222049206,0.009081735620585271 +2007,BruCap,67,M,0.02196137826580841,0.029947916666666668 +2007,BruCap,67,F,0.01152822938220515,0.008827238335435058 +2007,BruCap,68,M,0.0260475651189128,0.0199203187250996 +2007,BruCap,68,F,0.01408028759736369,0.01125 +2007,BruCap,69,M,0.03265145554681353,0.02098950524737631 +2007,BruCap,69,F,0.01320339515875511,0.014666666666666668 +2007,BruCap,70,M,0.029747351263243682,0.0282574568288854 +2007,BruCap,70,F,0.01456912585244886,0.0076335877862595426 +2007,BruCap,71,M,0.027557411273486432,0.02581755593803787 +2007,BruCap,71,F,0.018700183936235442,0.025906735751295342 +2007,BruCap,72,M,0.03155737704918033,0.028419182948490232 +2007,BruCap,72,F,0.01602465331278891,0.01451378809869376 +2007,BruCap,73,M,0.03433476394849786,0.03689320388349515 +2007,BruCap,73,F,0.02331071112422544,0.01155115511551155 +2007,BruCap,74,M,0.03998316498316498,0.03962264150943396 +2007,BruCap,74,F,0.0244457077885162,0.026622296173044933 +2007,BruCap,75,M,0.043273350471293916,0.04128440366972478 +2007,BruCap,75,F,0.02637614678899083,0.02003642987249545 +2007,BruCap,76,M,0.04206241519674357,0.04781704781704782 +2007,BruCap,76,F,0.02379679144385027,0.01740506329113924 +2007,BruCap,77,M,0.04927536231884058,0.04050632911392405 +2007,BruCap,77,F,0.02640449438202248,0.03355704697986577 +2007,BruCap,78,M,0.05452775073028238,0.06006006006006006 +2007,BruCap,78,F,0.03526376146788991,0.04219409282700422 +2007,BruCap,79,M,0.06357477853048463,0.07942238267148015 +2007,BruCap,79,F,0.03377777777777778,0.02736318407960199 +2007,BruCap,80,M,0.07008830022075055,0.06367041198501873 +2007,BruCap,80,F,0.04652515266065717,0.04261363636363636 +2007,BruCap,81,M,0.0937682003494467,0.06698564593301436 +2007,BruCap,81,F,0.04930847865303668,0.0487012987012987 +2007,BruCap,82,M,0.08298999411418481,0.0748663101604278 +2007,BruCap,82,F,0.0593881223755249,0.06557377049180327 +2007,BruCap,83,M,0.1056194989844279,0.117283950617284 +2007,BruCap,83,F,0.059490953695185526,0.06538461538461539 +2007,BruCap,84,M,0.1013313609467456,0.0949367088607595 +2007,BruCap,84,F,0.0674746151326564,0.07142857142857142 +2007,BruCap,85,M,0.1179173047473201,0.109375 +2007,BruCap,85,F,0.0814116002795248,0.08064516129032258 +2007,BruCap,86,M,0.1412742382271468,0.06666666666666668 +2007,BruCap,86,F,0.0943609022556391,0.1171171171171171 +2007,BruCap,87,M,0.1557719054242003,0.1076923076923077 +2007,BruCap,87,F,0.1105413105413105,0.0873015873015873 +2007,BruCap,88,M,0.1371571072319202,0.1395348837209302 +2007,BruCap,88,F,0.1110154905335628,0.1276595744680851 +2007,BruCap,89,M,0.1676470588235294,0.2 +2007,BruCap,89,F,0.1157786885245902,0.05813953488372092 +2007,BruCap,90,M,0.1865079365079365,0.08695652173913042 +2007,BruCap,90,F,0.1240951396070321,0.04166666666666667 +2007,BruCap,91,M,0.2140221402214022,0.2 +2007,BruCap,91,F,0.1689119170984456,0.234375 +2007,BruCap,92,M,0.2023346303501946,0.24 +2007,BruCap,92,F,0.1586134453781513,0.1612903225806452 +2007,BruCap,93,M,0.248587570621469,0.2 +2007,BruCap,93,F,0.2016574585635359,0.125 +2007,BruCap,94,M,0.2651515151515152,0.3333333333333333 +2007,BruCap,94,F,0.2328767123287671,0.2325581395348837 +2007,BruCap,95,M,0.2525252525252526,0.1 +2007,BruCap,95,F,0.2455696202531646,0.1379310344827586 +2007,BruCap,96,M,0.2923076923076923,0.2 +2007,BruCap,96,F,0.251497005988024,0.1363636363636364 +2007,BruCap,97,M,0.3235294117647059,0.3333333333333333 +2007,BruCap,97,F,0.2660098522167488,0.2 +2007,BruCap,98,M,0.4285714285714286,0.0 +2007,BruCap,98,F,0.3116883116883117,0.09090909090909093 +2007,BruCap,99,M,0.5555555555555556,0.0 +2007,BruCap,99,F,0.3085106382978724,0.0 +2007,BruCap,100,M,0.375,0.0 +2007,BruCap,100,F,0.4457831325301205,0.0 +2007,BruCap,101,M,0.4444444444444444,0.0 +2007,BruCap,101,F,0.4054054054054055,0.0 +2007,BruCap,102,M,0.2,0.0 +2007,BruCap,102,F,0.3888888888888889,0.0 +2007,BruCap,103,M,1.0,0.0 +2007,BruCap,103,F,0.3076923076923077,0.0 +2007,BruCap,104,M,0.0,0.0 +2007,BruCap,104,F,0.5,0.0 +2007,BruCap,105,M,0.0,0.0 +2007,BruCap,105,F,0.4,0.0 +2007,BruCap,106,M,0.0,0.0 +2007,BruCap,106,F,1.0,0.0 +2007,BruCap,107,M,0.0,0.0 +2007,BruCap,107,F,1.0,0.0 +2007,BruCap,108,M,0.0,0.0 +2007,BruCap,108,F,0.0,0.0 +2007,BruCap,109,M,0.0,0.0 +2007,BruCap,109,F,0.0,0.0 +2007,BruCap,110,M,0.0,0.0 +2007,BruCap,110,F,0.0,0.0 +2007,BruCap,111,M,0.0,0.0 +2007,BruCap,111,F,0.0,0.0 +2007,BruCap,112,M,0.0,0.0 +2007,BruCap,112,F,0.0,0.0 +2007,BruCap,113,M,0.0,0.0 +2007,BruCap,113,F,0.0,0.0 +2007,BruCap,114,M,0.0,0.0 +2007,BruCap,114,F,0.0,0.0 +2007,BruCap,115,M,0.0,0.0 +2007,BruCap,115,F,0.0,0.0 +2007,BruCap,116,M,0.0,0.0 +2007,BruCap,116,F,0.0,0.0 +2007,BruCap,117,M,0.0,0.0 +2007,BruCap,117,F,0.0,0.0 +2007,BruCap,118,M,0.0,0.0 +2007,BruCap,118,F,0.0,0.0 +2007,BruCap,119,M,0.0,0.0 +2007,BruCap,119,F,0.0,0.0 +2007,BruCap,120,M,0.0,0.0 +2007,BruCap,120,F,0.0,0.0 +2007,Fla,0,M,0.000887648998224702,0.0005037783375314861 +2007,Fla,0,F,0.0006265870791148633,0.001570680628272252 +2007,Fla,1,M,0.0004121880845936777,0.0005167958656330749 +2007,Fla,1,F,0.00020185708518369,0.0 +2007,Fla,2,M,0.0001931682817681337,0.0 +2007,Fla,2,F,0.0001701316819218075,0.0 +2007,Fla,3,M,0.0001334044823906083,0.0 +2007,Fla,3,F,3.489427036080676e-05,0.0 +2007,Fla,4,M,0.0001329875656626106,0.0 +2007,Fla,4,F,3.498093539021234e-05,0.0 +2007,Fla,5,M,0.0001315486565593449,0.0005865102639296188 +2007,Fla,5,F,3.432297923459757e-05,0.0 +2007,Fla,6,M,6.408818534303199e-05,0.0005824111822947001 +2007,Fla,6,F,6.676458806249166e-05,0.0005858230814294082 +2007,Fla,7,M,6.417249566835656e-05,0.0 +2007,Fla,7,F,0.0001324722636198046,0.0 +2007,Fla,8,M,3.111968631356196e-05,0.0 +2007,Fla,8,F,6.547073458164201e-05,0.0 +2007,Fla,9,M,3.055114261273372e-05,0.0 +2007,Fla,9,F,6.365574970559216e-05,0.0 +2007,Fla,10,M,0.00012186947778928768,0.0018999366687777073 +2007,Fla,10,F,0.00022094564737074683,0.0 +2007,Fla,11,M,3.030762236702531e-05,0.0 +2007,Fla,11,F,9.47597839476926e-05,0.0 +2007,Fla,12,M,0.0002089614615361653,0.0 +2007,Fla,12,F,0.0001886021437777009,0.0006788866259334692 +2007,Fla,13,M,0.0001148765077541643,0.0 +2007,Fla,13,F,0.00020754269449715367,0.0 +2007,Fla,14,M,0.0001940186812273068,0.0006435006435006435 +2007,Fla,14,F,0.0001156537327242237,0.0 +2007,Fla,15,M,0.00035542432195975515,0.0006309148264984228 +2007,Fla,15,F,0.00017264696572957732,0.0006896551724137933 +2007,Fla,16,M,0.000193477059148701,0.0 +2007,Fla,16,F,0.0002318706161961626,0.0 +2007,Fla,17,M,0.0004856032906764168,0.001304631441617743 +2007,Fla,17,F,0.0003005530175522962,0.0 +2007,Fla,18,M,0.0006362979031091829,0.0006116207951070336 +2007,Fla,18,F,0.00024194036170084083,0.00115606936416185 +2007,Fla,19,M,0.0006716701223607745,0.0012795905310300712 +2007,Fla,19,F,0.0004014452027298274,0.0 +2007,Fla,20,M,0.001139717700692598,0.0 +2007,Fla,20,F,0.0002783619943090437,0.0 +2007,Fla,21,M,0.0009376890502117364,0.00055005500550055 +2007,Fla,21,F,0.0002826899519427082,0.0007686395080707147 +2007,Fla,22,M,0.0008595139300533491,0.0 +2007,Fla,22,F,0.00030865150158955517,0.0 +2007,Fla,23,M,0.001013670064874884,0.000925925925925926 +2007,Fla,23,F,0.00035884094375168214,0.0 +2007,Fla,24,M,0.0005930025696778018,0.001165501165501166 +2007,Fla,24,F,0.0004449850188376992,0.0003119151590767312 +2007,Fla,25,M,0.0006037984411022066,0.0 +2007,Fla,25,F,0.00017366136034732268,0.0 +2007,Fla,26,M,0.0009799255256600498,0.0006747638326585696 +2007,Fla,26,F,0.00040149125322626897,0.0002861230329041488 +2007,Fla,27,M,0.0009688313126280242,0.001625487646293888 +2007,Fla,27,F,0.00023154848046309703,0.0 +2007,Fla,28,M,0.001020437087219026,0.0006476683937823834 +2007,Fla,28,F,0.0002607259769981749,0.0002959455460195324 +2007,Fla,29,M,0.0006085192697768763,0.00031133250311332514 +2007,Fla,29,F,0.0002055679548925173,0.001191185229303157 +2007,Fla,30,M,0.0008234809717075466,0.0018410555385087448 +2007,Fla,30,F,0.0005448271687148133,0.0002922267679719462 +2007,Fla,31,M,0.0008436784379896347,0.0009140767824497258 +2007,Fla,31,F,0.0003405678194371343,0.001204819277108434 +2007,Fla,32,M,0.001214574898785425,0.00145602795573675 +2007,Fla,32,F,0.0004710592945887064,0.0003112356053532525 +2007,Fla,33,M,0.0010005558643690939,0.0008756567425569178 +2007,Fla,33,F,0.00037140734815153416,0.0006049606775559589 +2007,Fla,34,M,0.0010642543567912733,0.0005619556055071652 +2007,Fla,34,F,0.000431662439971942,0.0 +2007,Fla,35,M,0.0008381803865789541,0.000856898029134533 +2007,Fla,35,F,0.0004607587160190448,0.0008841732979664014 +2007,Fla,36,M,0.00098527021035519,0.0005405405405405405 +2007,Fla,36,F,0.0006525776818432807,0.0 +2007,Fla,37,M,0.0011045926507768972,0.0002754820936639118 +2007,Fla,37,F,0.0008771929824561404,0.00029841838257236653 +2007,Fla,38,M,0.001020259437399796,0.000555247084952804 +2007,Fla,38,F,0.0006694768162658071,0.001226993865030675 +2007,Fla,39,M,0.0015938122582913401,0.0008968609865470852 +2007,Fla,39,F,0.0007560238025558483,0.0009615384615384617 +2007,Fla,40,M,0.001342892909980653,0.001112656467315716 +2007,Fla,40,F,0.000908328675237563,0.0 +2007,Fla,41,M,0.001496742384222575,0.001145475372279496 +2007,Fla,41,F,0.001153089601844944,0.0006602839220864972 +2007,Fla,42,M,0.0015898588205367366,0.00254957507082153 +2007,Fla,42,F,0.001013651950740829,0.002367264119039568 +2007,Fla,43,M,0.001722744480837126,0.001252740369558409 +2007,Fla,43,F,0.001090583898619321,0.001135073779795687 +2007,Fla,44,M,0.0018775492586917575,0.002594033722438392 +2007,Fla,44,F,0.001528137665271411,0.001533742331288344 +2007,Fla,45,M,0.001810843242063925,0.004041764904008084 +2007,Fla,45,F,0.001364076388277744,0.0008278145695364237 +2007,Fla,46,M,0.0019354408133300711,0.00272572402044293 +2007,Fla,46,F,0.001757469244288225,0.002527379949452401 +2007,Fla,47,M,0.002740266573132235,0.0037271710771524407 +2007,Fla,47,F,0.001690842751624099,0.002239140170174653 +2007,Fla,48,M,0.003109758825898251,0.002148997134670487 +2007,Fla,48,F,0.001625197427152242,0.0005005005005005005 +2007,Fla,49,M,0.0034368171886380197,0.001579155151993684 +2007,Fla,49,F,0.002445386371046625,0.002564102564102564 +2007,Fla,50,M,0.003985184490599653,0.0028513238289205713 +2007,Fla,50,F,0.002548071251622036,0.002705627705627706 +2007,Fla,51,M,0.0038433076317108687,0.004122011541632317 +2007,Fla,51,F,0.002509680195038004,0.003409090909090909 +2007,Fla,52,M,0.005271893000097627,0.0016970725498515061 +2007,Fla,52,F,0.0026595089758427947,0.002280501710376283 +2007,Fla,53,M,0.004899755012249389,0.002293577981651377 +2007,Fla,53,F,0.0036233733095177344,0.003552397868561279 +2007,Fla,54,M,0.005848099994980172,0.0027726432532347517 +2007,Fla,54,F,0.0031111796770544077,0.0 +2007,Fla,55,M,0.005754256301966477,0.007146260123868509 +2007,Fla,55,F,0.003586051863944122,0.0025789813023855573 +2007,Fla,56,M,0.007377994795160036,0.005876591576885406 +2007,Fla,56,F,0.004112129438008977,0.0030978934324659237 +2007,Fla,57,M,0.007376609442060086,0.00875979714153988 +2007,Fla,57,F,0.003994348133253628,0.001277139208173691 +2007,Fla,58,M,0.00709506852271501,0.007253384912959382 +2007,Fla,58,F,0.0048097592433362,0.003903708523096942 +2007,Fla,59,M,0.0090230497908293,0.006018054162487462 +2007,Fla,59,F,0.004710815815270668,0.004504504504504504 +2007,Fla,60,M,0.009547307444754344,0.01047381546134663 +2007,Fla,60,F,0.005046708901535488,0.003516174402250352 +2007,Fla,61,M,0.010771390211155859,0.01079784043191362 +2007,Fla,61,F,0.005714114760964519,0.004769475357710651 +2007,Fla,62,M,0.010971689949313879,0.01038485033598045 +2007,Fla,62,F,0.006181215136439018,0.0066469719350073855 +2007,Fla,63,M,0.01207721605521013,0.01061836352279825 +2007,Fla,63,F,0.0060189707875082715,0.0033003300330033012 +2007,Fla,64,M,0.0148117594120294,0.010366275051831379 +2007,Fla,64,F,0.007950561960174912,0.007887817703768623 +2007,Fla,65,M,0.014119531315856032,0.011825572801182559 +2007,Fla,65,F,0.006804604976856431,0.008555133079847909 +2007,Fla,66,M,0.015487409238374791,0.02132352941176471 +2007,Fla,66,F,0.007752768846016434,0.0073589533932951765 +2007,Fla,67,M,0.01709038045597986,0.02220459952418716 +2007,Fla,67,F,0.009075111025294458,0.01284584980237154 +2007,Fla,68,M,0.01841684620195983,0.015322580645161291 +2007,Fla,68,F,0.010091423871437159,0.01016260162601626 +2007,Fla,69,M,0.020591973851461786,0.02016498625114574 +2007,Fla,69,F,0.010116321217912809,0.007352941176470587 +2007,Fla,70,M,0.02287769233712078,0.023054755043227668 +2007,Fla,70,F,0.01225581474083353,0.01202185792349727 +2007,Fla,71,M,0.02370096690511753,0.02083333333333333 +2007,Fla,71,F,0.013167320484393659,0.015018773466833541 +2007,Fla,72,M,0.02726546906187625,0.028824833702882482 +2007,Fla,72,F,0.01451525789900081,0.025119617224880385 +2007,Fla,73,M,0.031167763157894737,0.03417861080485116 +2007,Fla,73,F,0.01628575338716299,0.01282051282051282 +2007,Fla,74,M,0.03585195009740126,0.05018359853121175 +2007,Fla,74,F,0.01964701964701965,0.0115606936416185 +2007,Fla,75,M,0.038176809847637085,0.04421326397919376 +2007,Fla,75,F,0.02052895021645022,0.022260273972602745 +2007,Fla,76,M,0.04516921397379912,0.053900709219858164 +2007,Fla,76,F,0.02434547721291038,0.03851851851851852 +2007,Fla,77,M,0.05114984015674951,0.05218855218855219 +2007,Fla,77,F,0.029189066404179613,0.041218637992831535 +2007,Fla,78,M,0.05320340501792115,0.05360443622920517 +2007,Fla,78,F,0.031191713956903063,0.04232804232804233 +2007,Fla,79,M,0.060936733692986765,0.061538461538461535 +2007,Fla,79,F,0.03609341825902336,0.0471311475409836 +2007,Fla,80,M,0.06693970726467034,0.07106598984771574 +2007,Fla,80,F,0.041750108837614285,0.050104384133611686 +2007,Fla,81,M,0.07612407512805919,0.07451923076923077 +2007,Fla,81,F,0.04695007550450739,0.04929577464788732 +2007,Fla,82,M,0.08632978297429326,0.08333333333333333 +2007,Fla,82,F,0.05775675142913464,0.048843187660668384 +2007,Fla,83,M,0.09715425049845933,0.08724832214765099 +2007,Fla,83,F,0.0632760143384072,0.05376344086021505 +2007,Fla,84,M,0.1061323235510676,0.08494208494208494 +2007,Fla,84,F,0.07514111006585136,0.0880281690140845 +2007,Fla,85,M,0.1212862208093899,0.1442307692307692 +2007,Fla,85,F,0.08474467949127629,0.1165413533834587 +2007,Fla,86,M,0.1375345655654199,0.1629213483146068 +2007,Fla,86,F,0.1003037315591553,0.07423580786026203 +2007,Fla,87,M,0.1456551103106709,0.1238095238095238 +2007,Fla,87,F,0.1106161841128434,0.1194029850746269 +2007,Fla,88,M,0.1700569568755085,0.1794871794871795 +2007,Fla,88,F,0.1216354344122658,0.08035714285714286 +2007,Fla,89,M,0.1818642350557244,0.1568627450980392 +2007,Fla,89,F,0.1441295546558704,0.11 +2007,Fla,90,M,0.2016620498614959,0.1777777777777778 +2007,Fla,90,F,0.1545923632610939,0.09210526315789473 +2007,Fla,91,M,0.2147688838782413,0.175 +2007,Fla,91,F,0.1822342417308093,0.1764705882352941 +2007,Fla,92,M,0.2482900136798906,0.2 +2007,Fla,92,F,0.1912280701754386,0.2 +2007,Fla,93,M,0.2629016553067186,0.1578947368421053 +2007,Fla,93,F,0.2217426490423523,0.2156862745098039 +2007,Fla,94,M,0.2911051212938006,0.3333333333333333 +2007,Fla,94,F,0.2238163558106169,0.1224489795918368 +2007,Fla,95,M,0.3075356415478615,0.3333333333333333 +2007,Fla,95,F,0.2432851239669422,0.1904761904761905 +2007,Fla,96,M,0.3545454545454546,0.25 +2007,Fla,96,F,0.2802919708029198,0.3333333333333333 +2007,Fla,97,M,0.2810810810810811,0.1666666666666667 +2007,Fla,97,F,0.2985232067510549,0.2666666666666667 +2007,Fla,98,M,0.2538461538461539,0.25 +2007,Fla,98,F,0.2739322533136967,0.2 +2007,Fla,99,M,0.4337349397590362,0.0 +2007,Fla,99,F,0.3203661327231122,0.2857142857142857 +2007,Fla,100,M,0.5294117647058824,0.0 +2007,Fla,100,F,0.3961538461538462,0.0 +2007,Fla,101,M,0.6206896551724138,0.5 +2007,Fla,101,F,0.3615819209039548,0.4285714285714286 +2007,Fla,102,M,0.55,0.0 +2007,Fla,102,F,0.4631578947368421,0.0 +2007,Fla,103,M,1.0,0.0 +2007,Fla,103,F,0.3095238095238096,0.0 +2007,Fla,104,M,0.0,0.0 +2007,Fla,104,F,0.6071428571428571,0.0 +2007,Fla,105,M,0.0,0.0 +2007,Fla,105,F,0.5,0.0 +2007,Fla,106,M,0.5,0.0 +2007,Fla,106,F,0.6,0.0 +2007,Fla,107,M,0.0,0.0 +2007,Fla,107,F,0.25,0.0 +2007,Fla,108,M,0.0,0.0 +2007,Fla,108,F,0.6666666666666666,0.0 +2007,Fla,109,M,0.0,0.0 +2007,Fla,109,F,1.0,0.0 +2007,Fla,110,M,0.0,0.0 +2007,Fla,110,F,0.0,0.0 +2007,Fla,111,M,0.0,0.0 +2007,Fla,111,F,0.0,0.0 +2007,Fla,112,M,0.0,0.0 +2007,Fla,112,F,0.0,0.0 +2007,Fla,113,M,0.0,0.0 +2007,Fla,113,F,0.0,0.0 +2007,Fla,114,M,0.0,0.0 +2007,Fla,114,F,0.0,0.0 +2007,Fla,115,M,0.0,0.0 +2007,Fla,115,F,0.0,0.0 +2007,Fla,116,M,0.0,0.0 +2007,Fla,116,F,0.0,0.0 +2007,Fla,117,M,0.0,0.0 +2007,Fla,117,F,0.0,0.0 +2007,Fla,118,M,0.0,0.0 +2007,Fla,118,F,0.0,0.0 +2007,Fla,119,M,0.0,0.0 +2007,Fla,119,F,0.0,0.0 +2007,Fla,120,M,0.0,0.0 +2007,Fla,120,F,0.0,0.0 +2007,Wal,0,M,0.001399979259566525,0.0 +2007,Wal,0,F,0.0008052394245222246,0.001114827201783724 +2007,Wal,1,M,0.0003635419371591794,0.0011792452830188679 +2007,Wal,1,F,0.00032502708559046584,0.0023121387283237 +2007,Wal,2,M,0.0,0.0 +2007,Wal,2,F,0.000163826998689384,0.0 +2007,Wal,3,M,0.00031392246115209536,0.0 +2007,Wal,3,F,0.0002155520827719998,0.0011976047904191619 +2007,Wal,4,M,0.0002071251035625518,0.0 +2007,Wal,4,F,5.439216752787599e-05,0.0 +2007,Wal,5,M,4.998750312421894e-05,0.0 +2007,Wal,5,F,0.0,0.0 +2007,Wal,6,M,0.00014718869590815432,0.0 +2007,Wal,6,F,0.0002063770508719431,0.0 +2007,Wal,7,M,0.0001006390580184169,0.0 +2007,Wal,7,F,0.00010586491636671607,0.0 +2007,Wal,8,M,0.00010073536818777072,0.0010449320794148381 +2007,Wal,8,F,5.287088928835783e-05,0.0 +2007,Wal,9,M,0.0001508068164681044,0.0 +2007,Wal,9,F,5.226845076311938e-05,0.0 +2007,Wal,10,M,4.9657364187108946e-05,0.0 +2007,Wal,10,F,5.1977753521492795e-05,0.0 +2007,Wal,11,M,0.00025433643623785554,0.0009578544061302679 +2007,Wal,11,F,0.0002117522498676548,0.0010515247108307036 +2007,Wal,12,M,0.0002010959730531396,0.0 +2007,Wal,12,F,0.0001057417785767157,0.0 +2007,Wal,13,M,0.0001450256211930774,0.0 +2007,Wal,13,F,0.00010217113665389532,0.0 +2007,Wal,14,M,0.00046070211001566396,0.0008733624454148473 +2007,Wal,14,F,0.00024097546869728656,0.0 +2007,Wal,15,M,0.0005853482822279256,0.0 +2007,Wal,15,F,9.356725146198832e-05,0.0 +2007,Wal,16,M,0.00054827066295061,0.0007974481658692185 +2007,Wal,16,F,0.00028556470420256066,0.0008285004142502071 +2007,Wal,17,M,0.0008216176739090742,0.0 +2007,Wal,17,F,0.00023901716143219086,0.0 +2007,Wal,18,M,0.0009211495946941784,0.0007668711656441718 +2007,Wal,18,F,0.0001938078395271089,0.00138792505204719 +2007,Wal,19,M,0.001194001337281498,0.0 +2007,Wal,19,F,0.0002506014434643144,0.0007047216349541931 +2007,Wal,20,M,0.001103011701515442,0.002153625269203159 +2007,Wal,20,F,0.000403530895334174,0.0 +2007,Wal,21,M,0.0013541980138429132,0.0007272727272727272 +2007,Wal,21,F,0.0003138567766909034,0.0 +2007,Wal,22,M,0.001075434014441542,0.0 +2007,Wal,22,F,5.3075739079666685e-05,0.0005293806246691371 +2007,Wal,23,M,0.0010901728702694276,0.0005773672055427253 +2007,Wal,23,F,0.0005015324602953468,0.0 +2007,Wal,24,M,0.0008863861515198914,0.0005567928730512249 +2007,Wal,24,F,0.0002168139194536289,0.0 +2007,Wal,25,M,0.001259644150527476,0.001024065540194572 +2007,Wal,25,F,0.0004304778303917349,0.0008620689655172414 +2007,Wal,26,M,0.0009532888465204957,0.0013793103448275859 +2007,Wal,26,F,0.0003804347826086957,0.0004235493434985176 +2007,Wal,27,M,0.001025530307119339,0.0008908685968819599 +2007,Wal,27,F,0.0003377237419790612,0.0 +2007,Wal,28,M,0.001103935530165038,0.0 +2007,Wal,28,F,0.0005088483066659128,0.00041963911036508597 +2007,Wal,29,M,0.001585652578052381,0.00042789901583226365 +2007,Wal,29,F,0.000615798018250014,0.0 +2007,Wal,30,M,0.001676038062283737,0.0004194630872483222 +2007,Wal,30,F,0.0001630080417300587,0.0012931034482758616 +2007,Wal,31,M,0.0014460928712977349,0.0 +2007,Wal,31,F,0.0008043758043758043,0.0007961783439490446 +2007,Wal,32,M,0.000822326155111271,0.001115241635687732 +2007,Wal,32,F,0.0005695055656225733,0.001152073732718894 +2007,Wal,33,M,0.001323010584084673,0.0023592854735422987 +2007,Wal,33,F,0.0008392575039494472,0.0 +2007,Wal,34,M,0.0014174344436569813,0.00131104555883317 +2007,Wal,34,F,0.000853040140277712,0.0010552233556102714 +2007,Wal,35,M,0.001534241480310568,0.0006501950585175553 +2007,Wal,35,F,0.0006022700949733611,0.0003522367030644593 +2007,Wal,36,M,0.001313937118723604,0.001647989452867502 +2007,Wal,36,F,0.0005246339485858732,0.0003415300546448088 +2007,Wal,37,M,0.002177102560461925,0.0009871668311944716 +2007,Wal,37,F,0.001228559277985163,0.0 +2007,Wal,38,M,0.0019299430666795327,0.001671122994652407 +2007,Wal,38,F,0.0012340991076514151,0.0006770480704129992 +2007,Wal,39,M,0.002125448705837899,0.001618646811265782 +2007,Wal,39,F,0.001031217774444549,0.00035373187124159886 +2007,Wal,40,M,0.002547003797351116,0.001471020888496617 +2007,Wal,40,F,0.001194578451642546,0.0006402048655569782 +2007,Wal,41,M,0.002412760823913141,0.00145602795573675 +2007,Wal,41,F,0.0018587360594795536,0.0010323468685478321 +2007,Wal,42,M,0.002550579284108594,0.001539882968894364 +2007,Wal,42,F,0.001369159678247476,0.0006763611768684477 +2007,Wal,43,M,0.003217418132134515,0.002136752136752137 +2007,Wal,43,F,0.00133609171623136,0.000691085003455425 +2007,Wal,44,M,0.004076086956521739,0.002857142857142857 +2007,Wal,44,F,0.002065026362038665,0.003038359285985568 +2007,Wal,45,M,0.003411759493110018,0.004495825305073861 +2007,Wal,45,F,0.002789579846358526,0.0022230455724342357 +2007,Wal,46,M,0.00440411050313626,0.003253475303164744 +2007,Wal,46,F,0.00231917034962587,0.001544998068752414 +2007,Wal,47,M,0.004233511586452764,0.002836432398361173 +2007,Wal,47,F,0.0028836775370001282,0.0016019223067681222 +2007,Wal,48,M,0.004760393525864805,0.00412829469672912 +2007,Wal,48,F,0.003071864318781638,0.002860645688598284 +2007,Wal,49,M,0.005441047632222068,0.0032383419689119173 +2007,Wal,49,F,0.003321082229996015,0.0017211703958691911 +2007,Wal,50,M,0.0071110268322745794,0.003765296517100722 +2007,Wal,50,F,0.0036652959055962814,0.004625735912531539 +2007,Wal,51,M,0.008068389203726828,0.005232177894048398 +2007,Wal,51,F,0.003199206957148651,0.0030316154179298397 +2007,Wal,52,M,0.007412398921832884,0.0053226879574184965 +2007,Wal,52,F,0.004598224447985432,0.004839419269687638 +2007,Wal,53,M,0.008047995317529998,0.006291506466270535 +2007,Wal,53,F,0.004765429814009439,0.0037629350893697094 +2007,Wal,54,M,0.009306469976733829,0.005309734513274336 +2007,Wal,54,F,0.003815894850897442,0.006088992974238876 +2007,Wal,55,M,0.008626887131560028,0.009304056568663935 +2007,Wal,55,F,0.0051736526946107786,0.005205868433506862 +2007,Wal,56,M,0.009754406813230344,0.00633619083115915 +2007,Wal,56,F,0.0053437664010687535,0.002352941176470588 +2007,Wal,57,M,0.00983590103879159,0.00994263862332696 +2007,Wal,57,F,0.005398690936887871,0.004083716181725371 +2007,Wal,58,M,0.01192470680989455,0.009491268033409264 +2007,Wal,58,F,0.005853386602248444,0.004697040864255519 +2007,Wal,59,M,0.012815398424254509,0.007698229407236336 +2007,Wal,59,F,0.005144664180865625,0.006147540983606557 +2007,Wal,60,M,0.01332921620091606,0.011161637040099207 +2007,Wal,60,F,0.006462956802737252,0.005518763796909493 +2007,Wal,61,M,0.01398552741441692,0.008868022952529996 +2007,Wal,61,F,0.008141196942390155,0.00390625 +2007,Wal,62,M,0.01628984693161073,0.01359832635983264 +2007,Wal,62,F,0.00866407593807734,0.005141388174807198 +2007,Wal,63,M,0.017507802390195632,0.01707891637220259 +2007,Wal,63,F,0.0078050766933622905,0.009776536312849162 +2007,Wal,64,M,0.016580401789630668,0.01384518565135305 +2007,Wal,64,F,0.009414144557690813,0.010122921185827909 +2007,Wal,65,M,0.02200838414634146,0.01645819618169849 +2007,Wal,65,F,0.00909090909090909,0.0037707390648567115 +2007,Wal,66,M,0.02170742170742171,0.023557126030624268 +2007,Wal,66,F,0.010379596678529059,0.006935687263556116 +2007,Wal,67,M,0.0218056002574831,0.018714909544603867 +2007,Wal,67,F,0.01169630180515178,0.01321585903083701 +2007,Wal,68,M,0.0231270358306189,0.028452463566967387 +2007,Wal,68,F,0.011861680739847207,0.005646173149309913 +2007,Wal,69,M,0.02852763348377757,0.0271370420624152 +2007,Wal,69,F,0.015219401180570368,0.012578616352201259 +2007,Wal,70,M,0.029417056495142136,0.03282275711159737 +2007,Wal,70,F,0.01263369463785802,0.01276595744680851 +2007,Wal,71,M,0.03116760828625236,0.02906110283159464 +2007,Wal,71,F,0.01934730232897715,0.01508916323731139 +2007,Wal,72,M,0.03186702176508404,0.04198473282442748 +2007,Wal,72,F,0.02048192771084338,0.0175557056043214 +2007,Wal,73,M,0.04000372995151063,0.04660670482420278 +2007,Wal,73,F,0.020940170940170942,0.02518720217835262 +2007,Wal,74,M,0.04795655375552283,0.04942339373970346 +2007,Wal,74,F,0.0226760376607877,0.032376747608535685 +2007,Wal,75,M,0.04799627213420317,0.06118721461187215 +2007,Wal,75,F,0.028407592934352764,0.0247632920611799 +2007,Wal,76,M,0.05255314921517981,0.059806508355321024 +2007,Wal,76,F,0.02810631229235881,0.02514367816091954 +2007,Wal,77,M,0.05923805329222636,0.06401551891367603 +2007,Wal,77,F,0.0334123733563268,0.03783783783783784 +2007,Wal,78,M,0.06347134891446198,0.06796116504854369 +2007,Wal,78,F,0.037879341864716636,0.042833607907743 +2007,Wal,79,M,0.07073668111139435,0.08960176991150443 +2007,Wal,79,F,0.0453847335278759,0.05276595744680851 +2007,Wal,80,M,0.07979390057095112,0.09254807692307693 +2007,Wal,80,F,0.04604533206530353,0.04619332763045338 +2007,Wal,81,M,0.08905738923580138,0.09871244635193133 +2007,Wal,81,F,0.0554263254993182,0.053734061930783235 +2007,Wal,82,M,0.09293433083956774,0.1104294478527607 +2007,Wal,82,F,0.06307399064286953,0.07068607068607069 +2007,Wal,83,M,0.1071705426356589,0.0920353982300885 +2007,Wal,83,F,0.07442641298265247,0.09810479375696766 +2007,Wal,84,M,0.1216305062458909,0.1741935483870968 +2007,Wal,84,F,0.07781240575047753,0.07944514501891553 +2007,Wal,85,M,0.1343469591226321,0.1648648648648649 +2007,Wal,85,F,0.09373326191751473,0.1145038167938931 +2007,Wal,86,M,0.1517615176151762,0.1856060606060606 +2007,Wal,86,F,0.1082771896053898,0.1191626409017714 +2007,Wal,87,M,0.1510164569215876,0.1493506493506494 +2007,Wal,87,F,0.1258677383997077,0.1372031662269129 +2007,Wal,88,M,0.1617391304347826,0.1411764705882353 +2007,Wal,88,F,0.1445856019358742,0.09743589743589744 +2007,Wal,89,M,0.152542372881356,0.196969696969697 +2007,Wal,89,F,0.1356174161313348,0.1584699453551913 +2007,Wal,90,M,0.2176541717049577,0.2068965517241379 +2007,Wal,90,F,0.1822834645669291,0.1455696202531646 +2007,Wal,91,M,0.2402877697841727,0.3181818181818182 +2007,Wal,91,F,0.1831570996978852,0.22905027932960895 +2007,Wal,92,M,0.2492447129909366,0.2448979591836735 +2007,Wal,92,F,0.1967213114754098,0.2565789473684211 +2007,Wal,93,M,0.2603305785123967,0.2962962962962963 +2007,Wal,93,F,0.2292891501870658,0.208 +2007,Wal,94,M,0.3058419243986255,0.28125 +2007,Wal,94,F,0.2381280110116999,0.2692307692307692 +2007,Wal,95,M,0.3050847457627119,0.5 +2007,Wal,95,F,0.2201005025125628,0.265625 +2007,Wal,96,M,0.3529411764705883,0.5555555555555556 +2007,Wal,96,F,0.3004172461752434,0.2833333333333334 +2007,Wal,97,M,0.3170731707317073,0.0 +2007,Wal,97,F,0.28600000000000003,0.2564102564102564 +2007,Wal,98,M,0.2727272727272727,0.3333333333333333 +2007,Wal,98,F,0.3343195266272189,0.2222222222222222 +2007,Wal,99,M,0.2592592592592593,1.0 +2007,Wal,99,F,0.3171806167400882,0.2727272727272727 +2007,Wal,100,M,0.6153846153846154,0.0 +2007,Wal,100,F,0.4087591240875913,0.3333333333333333 +2007,Wal,101,M,0.1818181818181818,0.5 +2007,Wal,101,F,0.3604651162790698,0.25 +2007,Wal,102,M,1.0,0.0 +2007,Wal,102,F,0.38095238095238093,0.5 +2007,Wal,103,M,0.5,0.0 +2007,Wal,103,F,0.53125,0.3333333333333333 +2007,Wal,104,M,1.0,0.0 +2007,Wal,104,F,0.6923076923076923,1.0 +2007,Wal,105,M,0.0,0.0 +2007,Wal,105,F,0.4285714285714286,1.0 +2007,Wal,106,M,0.0,0.0 +2007,Wal,106,F,0.0,0.0 +2007,Wal,107,M,0.0,0.0 +2007,Wal,107,F,0.3333333333333333,0.0 +2007,Wal,108,M,0.0,0.0 +2007,Wal,108,F,0.0,0.0 +2007,Wal,109,M,0.0,0.0 +2007,Wal,109,F,0.0,0.0 +2007,Wal,110,M,0.0,0.0 +2007,Wal,110,F,0.0,0.0 +2007,Wal,111,M,0.0,0.0 +2007,Wal,111,F,0.0,0.0 +2007,Wal,112,M,0.0,0.0 +2007,Wal,112,F,0.0,0.0 +2007,Wal,113,M,0.0,0.0 +2007,Wal,113,F,0.0,0.0 +2007,Wal,114,M,0.0,0.0 +2007,Wal,114,F,0.0,0.0 +2007,Wal,115,M,0.0,0.0 +2007,Wal,115,F,0.0,0.0 +2007,Wal,116,M,0.0,0.0 +2007,Wal,116,F,0.0,0.0 +2007,Wal,117,M,0.0,0.0 +2007,Wal,117,F,0.0,0.0 +2007,Wal,118,M,0.0,0.0 +2007,Wal,118,F,0.0,0.0 +2007,Wal,119,M,0.0,0.0 +2007,Wal,119,F,0.0,0.0 +2007,Wal,120,M,0.0,0.0 +2007,Wal,120,F,0.0,0.0 +2008,BruCap,0,M,0.0007849293563579277,0.001046572475143904 +2008,BruCap,0,F,0.0004975949577044286,0.0005370569280343716 +2008,BruCap,1,M,0.00015532774153463808,0.0005443658138268917 +2008,BruCap,1,F,0.0003285690816494168,0.0 +2008,BruCap,2,M,0.0001669727834362999,0.0005793742757821553 +2008,BruCap,2,F,0.0001721170395869191,0.0006075334143377885 +2008,BruCap,3,M,0.0,0.0 +2008,BruCap,3,F,0.0003590664272890485,0.0 +2008,BruCap,4,M,0.0,0.0 +2008,BruCap,4,F,0.0001879345987596317,0.0 +2008,BruCap,5,M,0.00019197542714532545,0.0 +2008,BruCap,5,F,0.0,0.0 +2008,BruCap,6,M,0.0001901502186727515,0.0007513148009015777 +2008,BruCap,6,F,0.0001941370607649,0.0007818608287724785 +2008,BruCap,7,M,0.0001965022597759874,0.0 +2008,BruCap,7,F,0.0,0.0 +2008,BruCap,8,M,0.0004037141703673799,0.0 +2008,BruCap,8,F,0.0,0.0 +2008,BruCap,9,M,0.0,0.0 +2008,BruCap,9,F,0.0,0.0 +2008,BruCap,10,M,0.0,0.0 +2008,BruCap,10,F,0.000221729490022173,0.0 +2008,BruCap,11,M,0.0,0.0 +2008,BruCap,11,F,0.0004430660168365087,0.0 +2008,BruCap,12,M,0.0,0.0 +2008,BruCap,12,F,0.0002293052052281587,0.0 +2008,BruCap,13,M,0.0004241781548250265,0.0008795074758135447 +2008,BruCap,13,F,0.0,0.0009216589861751152 +2008,BruCap,14,M,0.0,0.0 +2008,BruCap,14,F,0.000224517287831163,0.0 +2008,BruCap,15,M,0.0,0.0 +2008,BruCap,15,F,0.0002237637055269635,0.0 +2008,BruCap,16,M,0.000427715996578272,0.0 +2008,BruCap,16,F,0.0006565988181221272,0.0 +2008,BruCap,17,M,0.0004272591326639607,0.0008583690987124463 +2008,BruCap,17,F,0.0,0.0 +2008,BruCap,18,M,0.0004302925989672978,0.0008326394671107411 +2008,BruCap,18,F,0.0004368719965050242,0.0 +2008,BruCap,19,M,0.0008488964346349745,0.0007407407407407407 +2008,BruCap,19,F,0.00044023772837332157,0.0 +2008,BruCap,20,M,0.00021786492374727668,0.0 +2008,BruCap,20,F,0.0004294610264118532,0.0005022601707684581 +2008,BruCap,21,M,0.0008624407072013798,0.0006035003017501509 +2008,BruCap,21,F,0.0006476683937823834,0.0 +2008,BruCap,22,M,0.0008701326952360235,0.0011001100110011 +2008,BruCap,22,F,0.00044464206313917306,0.0 +2008,BruCap,23,M,0.0006377551020408162,0.0 +2008,BruCap,23,F,0.0006071645415907711,0.0003379520108144643 +2008,BruCap,24,M,0.0004161464835622138,0.0 +2008,BruCap,24,F,0.0001985702938840349,0.0 +2008,BruCap,25,M,0.0005878894767783657,0.0 +2008,BruCap,25,F,0.0001837222120154327,0.0002831257078142696 +2008,BruCap,26,M,0.0005515719801434088,0.00033057851239669435 +2008,BruCap,26,F,0.00105615208590037,0.0002643404705260375 +2008,BruCap,27,M,0.0001776514478593001,0.0005765350245027388 +2008,BruCap,27,F,0.0,0.0002417794970986461 +2008,BruCap,28,M,0.0005330490405117272,0.0008289582757667862 +2008,BruCap,28,F,0.0001779359430604982,0.0004813477737665463 +2008,BruCap,29,M,0.00072992700729927,0.0 +2008,BruCap,29,F,0.0001782848992690319,0.0 +2008,BruCap,30,M,0.0007334066740007334,0.0005171967933798808 +2008,BruCap,30,F,0.0003636363636363636,0.0002515723270440252 +2008,BruCap,31,M,0.00150065653723504,0.0002476473501733532 +2008,BruCap,31,F,0.0007513148009015777,0.0002599428125812321 +2008,BruCap,32,M,0.0003810249571346924,0.0 +2008,BruCap,32,F,0.0006026516673362796,0.0002621919244887258 +2008,BruCap,33,M,0.0005703422053231937,0.0005256241787122207 +2008,BruCap,33,F,0.001011940902651285,0.0 +2008,BruCap,34,M,0.0009457159069415547,0.0005274261603375527 +2008,BruCap,34,F,0.0,0.00028240609997175935 +2008,BruCap,35,M,0.001328021248339974,0.0007976601967561817 +2008,BruCap,35,F,0.00040176777822418635,0.0 +2008,BruCap,36,M,0.00018875047187617969,0.0002748763056624519 +2008,BruCap,36,F,0.001212121212121212,0.000608457560085184 +2008,BruCap,37,M,0.0009460737937559133,0.0002673796791443851 +2008,BruCap,37,F,0.0003987240829346093,0.00031133250311332514 +2008,BruCap,38,M,0.0015530964861192,0.0014359563469270539 +2008,BruCap,38,F,0.000825593395252838,0.0006355258976803304 +2008,BruCap,39,M,0.00177619893428064,0.0008759124087591243 +2008,BruCap,39,F,0.00172637030643073,0.0003451846738004833 +2008,BruCap,40,M,0.002653061224489796,0.0003131850923896023 +2008,BruCap,40,F,0.002166847237269772,0.001849796522382538 +2008,BruCap,41,M,0.001856435643564357,0.002258064516129033 +2008,BruCap,41,F,0.001886396981764829,0.0003855050115651504 +2008,BruCap,42,M,0.002364998029168309,0.002427184466019418 +2008,BruCap,42,F,0.002273196941516843,0.002419354838709678 +2008,BruCap,43,M,0.002958579881656805,0.003120665742024965 +2008,BruCap,43,F,0.001637331150225133,0.001642710472279261 +2008,BruCap,44,M,0.002684286599215363,0.0007722007722007723 +2008,BruCap,44,F,0.001880091915604763,0.0013327410039982233 +2008,BruCap,45,M,0.003820033955857386,0.0016220600162206 +2008,BruCap,45,F,0.002099958000839983,0.0014360938247965538 +2008,BruCap,46,M,0.0047857298237981285,0.002126754572522331 +2008,BruCap,46,F,0.001898333684876609,0.0 +2008,BruCap,47,M,0.006079664570230608,0.0040467625899280575 +2008,BruCap,47,F,0.002999400119976005,0.002493765586034913 +2008,BruCap,48,M,0.004751619870410367,0.005250596658711217 +2008,BruCap,48,F,0.0020631318341242013,0.001049868766404199 +2008,BruCap,49,M,0.005174353205849269,0.002502502502502503 +2008,BruCap,49,F,0.002896152254861399,0.001157407407407408 +2008,BruCap,50,M,0.0055185100022993785,0.004512126339537507 +2008,BruCap,50,F,0.002959205242020715,0.004166666666666668 +2008,BruCap,51,M,0.0072872590503055956,0.003287671232876713 +2008,BruCap,51,F,0.002534318901795143,0.00243605359317905 +2008,BruCap,52,M,0.008596654275092937,0.001727115716753023 +2008,BruCap,52,F,0.004233700254022015,0.004519044544867657 +2008,BruCap,53,M,0.007642703606400765,0.0038167938931297713 +2008,BruCap,53,F,0.0032265003226500328,0.001347708894878706 +2008,BruCap,54,M,0.0063859981078524105,0.004824259131633356 +2008,BruCap,54,F,0.0036948489458813296,0.004884856943475228 +2008,BruCap,55,M,0.010498687664041993,0.004765146358066711 +2008,BruCap,55,F,0.005650945446642034,0.0013783597518952446 +2008,BruCap,56,M,0.009718670076726344,0.007058823529411766 +2008,BruCap,56,F,0.005138986218173324,0.0038819875776397524 +2008,BruCap,57,M,0.008787800465236495,0.005637773079633545 +2008,BruCap,57,F,0.006293549112160036,0.005094614264919942 +2008,BruCap,58,M,0.011820330969267141,0.005490196078431373 +2008,BruCap,58,F,0.004651162790697674,0.003182179793158314 +2008,BruCap,59,M,0.01061289466702043,0.0126984126984127 +2008,BruCap,59,F,0.0067457548267038855,0.005733005733005733 +2008,BruCap,60,M,0.01423200859291085,0.008244023083264633 +2008,BruCap,60,F,0.008196721311475409,0.003412969283276451 +2008,BruCap,61,M,0.014168937329700268,0.009812667261373774 +2008,BruCap,61,F,0.007345971563981044,0.005286343612334802 +2008,BruCap,62,M,0.01382636655948553,0.0076086956521739125 +2008,BruCap,62,F,0.006920415224913495,0.005865102639296189 +2008,BruCap,63,M,0.01580547112462006,0.01288936627282492 +2008,BruCap,63,F,0.00944386149003148,0.0 +2008,BruCap,64,M,0.02138861467588022,0.01051401869158878 +2008,BruCap,64,F,0.01108954810091489,0.0100111234705228 +2008,BruCap,65,M,0.0167910447761194,0.01833740831295844 +2008,BruCap,65,F,0.01176096630642085,0.006009615384615385 +2008,BruCap,66,M,0.024734982332155483,0.01697312588401697 +2008,BruCap,66,F,0.01052249637155298,0.0053262316910785605 +2008,BruCap,67,M,0.01886066204772902,0.016688061617458283 +2008,BruCap,67,F,0.011299435028248593,0.01147028154327425 +2008,BruCap,68,M,0.02491241728298949,0.01648351648351649 +2008,BruCap,68,F,0.01228648486664669,0.0101010101010101 +2008,BruCap,69,M,0.02678571428571429,0.02263083451202263 +2008,BruCap,69,F,0.014629686071319719,0.0154241645244216 +2008,BruCap,70,M,0.02942378422558235,0.01869158878504673 +2008,BruCap,70,F,0.01239275500476645,0.009523809523809523 +2008,BruCap,71,M,0.023089840470193117,0.03511705685618729 +2008,BruCap,71,F,0.015365318281592981,0.01935483870967742 +2008,BruCap,72,M,0.03446790176647997,0.030357142857142864 +2008,BruCap,72,F,0.0211706102117061,0.01761517615176152 +2008,BruCap,73,M,0.03041825095057034,0.03605313092979128 +2008,BruCap,73,F,0.01532686893963091,0.02806499261447563 +2008,BruCap,74,M,0.03739982190560998,0.04356846473029046 +2008,BruCap,74,F,0.02077687443541102,0.01706484641638225 +2008,BruCap,75,M,0.04117389399912396,0.03846153846153847 +2008,BruCap,75,F,0.0268770084721005,0.023049645390070917 +2008,BruCap,76,M,0.0484304932735426,0.03818615751789977 +2008,BruCap,76,F,0.02946375957572186,0.024482109227871945 +2008,BruCap,77,M,0.05534531693472091,0.03811659192825112 +2008,BruCap,77,F,0.03268332875583632,0.030894308943089432 +2008,BruCap,78,M,0.061897513952308476,0.04619565217391304 +2008,BruCap,78,F,0.03222996515679443,0.02657004830917875 +2008,BruCap,79,M,0.06649484536082474,0.07142857142857142 +2008,BruCap,79,F,0.04355608591885442,0.03579418344519016 +2008,BruCap,80,M,0.06789092932665554,0.09090909090909093 +2008,BruCap,80,F,0.03977798334875116,0.044155844155844164 +2008,BruCap,81,M,0.07765263781861292,0.07661290322580645 +2008,BruCap,81,F,0.04732824427480916,0.05029585798816568 +2008,BruCap,82,M,0.08247422680412371,0.06770833333333333 +2008,BruCap,82,F,0.05527479469361971,0.0528169014084507 +2008,BruCap,83,M,0.09207161125319692,0.1090909090909091 +2008,BruCap,83,F,0.06707317073170732,0.08041958041958043 +2008,BruCap,84,M,0.1366037735849057,0.07746478873239436 +2008,BruCap,84,F,0.0728282168517309,0.07531380753138077 +2008,BruCap,85,M,0.1124794745484401,0.09722222222222222 +2008,BruCap,85,F,0.08268824771287825,0.08673469387755102 +2008,BruCap,86,M,0.1125541125541126,0.09174311926605506 +2008,BruCap,86,F,0.09056171188383648,0.07228915662650602 +2008,BruCap,87,M,0.1408602150537635,0.1785714285714286 +2008,BruCap,87,F,0.1104114189756507,0.09278350515463918 +2008,BruCap,88,M,0.174055829228243,0.1964285714285714 +2008,BruCap,88,F,0.115483870967742,0.05357142857142857 +2008,BruCap,89,M,0.1899109792284867,0.1707317073170732 +2008,BruCap,89,F,0.1223091976516634,0.1511627906976744 +2008,BruCap,90,M,0.1619718309859155,0.09090909090909093 +2008,BruCap,90,F,0.1488862837045721,0.1298701298701299 +2008,BruCap,91,M,0.1893203883495146,0.1764705882352941 +2008,BruCap,91,F,0.1797346200241255,0.08955223880597014 +2008,BruCap,92,M,0.2535885167464115,0.1052631578947368 +2008,BruCap,92,F,0.1810237203495631,0.1372549019607843 +2008,BruCap,93,M,0.2631578947368421,0.1666666666666667 +2008,BruCap,93,F,0.1778058007566204,0.09433962264150944 +2008,BruCap,94,M,0.2272727272727273,0.125 +2008,BruCap,94,F,0.2245250431778929,0.2 +2008,BruCap,95,M,0.309278350515464,0.1111111111111111 +2008,BruCap,95,F,0.2755555555555556,0.1470588235294118 +2008,BruCap,96,M,0.2857142857142857,0.0 +2008,BruCap,96,F,0.2773972602739726,0.1666666666666667 +2008,BruCap,97,M,0.25,0.2 +2008,BruCap,97,F,0.256,0.1111111111111111 +2008,BruCap,98,M,0.25,0.0 +2008,BruCap,98,F,0.3175675675675676,0.0625 +2008,BruCap,99,M,0.3636363636363637,0.0 +2008,BruCap,99,F,0.3047619047619048,0.0 +2008,BruCap,100,M,0.0,0.0 +2008,BruCap,100,F,0.3333333333333333,1.0 +2008,BruCap,101,M,0.4,0.0 +2008,BruCap,101,F,0.3191489361702128,0.0 +2008,BruCap,102,M,1.0,0.0 +2008,BruCap,102,F,0.3181818181818182,0.0 +2008,BruCap,103,M,0.5,0.0 +2008,BruCap,103,F,0.38095238095238093,0.6666666666666666 +2008,BruCap,104,M,0.0,0.0 +2008,BruCap,104,F,0.5555555555555556,0.0 +2008,BruCap,105,M,0.0,0.0 +2008,BruCap,105,F,0.6666666666666666,0.0 +2008,BruCap,106,M,0.0,0.0 +2008,BruCap,106,F,0.3333333333333333,0.0 +2008,BruCap,107,M,0.0,0.0 +2008,BruCap,107,F,0.0,0.0 +2008,BruCap,108,M,0.0,0.0 +2008,BruCap,108,F,0.0,0.0 +2008,BruCap,109,M,0.0,0.0 +2008,BruCap,109,F,0.5,0.0 +2008,BruCap,110,M,0.0,0.0 +2008,BruCap,110,F,0.0,0.0 +2008,BruCap,111,M,0.0,0.0 +2008,BruCap,111,F,0.0,0.0 +2008,BruCap,112,M,0.0,0.0 +2008,BruCap,112,F,0.0,0.0 +2008,BruCap,113,M,0.0,0.0 +2008,BruCap,113,F,0.0,0.0 +2008,BruCap,114,M,0.0,0.0 +2008,BruCap,114,F,0.0,0.0 +2008,BruCap,115,M,0.0,0.0 +2008,BruCap,115,F,0.0,0.0 +2008,BruCap,116,M,0.0,0.0 +2008,BruCap,116,F,0.0,0.0 +2008,BruCap,117,M,0.0,0.0 +2008,BruCap,117,F,0.0,0.0 +2008,BruCap,118,M,0.0,0.0 +2008,BruCap,118,F,0.0,0.0 +2008,BruCap,119,M,0.0,0.0 +2008,BruCap,119,F,0.0,0.0 +2008,BruCap,120,M,0.0,0.0 +2008,BruCap,120,F,0.0,0.0 +2008,Fla,0,M,0.0005417981323899672,0.0 +2008,Fla,0,F,0.0006955024176988808,0.0009345794392523364 +2008,Fla,1,M,0.0002196974452325655,0.0 +2008,Fla,1,F,0.0002936378466557913,0.0 +2008,Fla,2,M,0.0003775603309945569,0.0 +2008,Fla,2,F,0.0001001268273145985,0.0 +2008,Fla,3,M,0.0002876594112570717,0.0005002501250625311 +2008,Fla,3,F,0.0001013068584743187,0.0 +2008,Fla,4,M,6.62646610562587e-05,0.0 +2008,Fla,4,F,3.461405330564209e-05,0.0 +2008,Fla,5,M,0.0001321920750850987,0.0 +2008,Fla,5,F,0.0001741553465691397,0.0 +2008,Fla,6,M,6.539366989275439e-05,0.0005488474204171242 +2008,Fla,6,F,6.815703380588877e-05,0.0 +2008,Fla,7,M,6.378161176132921e-05,0.0 +2008,Fla,7,F,9.978380176284718e-05,0.0 +2008,Fla,8,M,0.000159596539947014,0.0 +2008,Fla,8,F,6.595435958316844e-05,0.0005844535359438924 +2008,Fla,9,M,9.302037146135004e-05,0.0 +2008,Fla,9,F,6.521880910454576e-05,0.0 +2008,Fla,10,M,6.084760716784813e-05,0.0 +2008,Fla,10,F,0.0001266103250720096,0.0 +2008,Fla,11,M,0.00012131873464559773,0.0005913660555884093 +2008,Fla,11,F,9.438414346389808e-05,0.0 +2008,Fla,12,M,9.044589827851309e-05,0.0 +2008,Fla,12,F,0.0001256557660289637,0.0 +2008,Fla,13,M,0.0002083333333333334,0.0 +2008,Fla,13,F,9.396141317965422e-05,0.0 +2008,Fla,14,M,0.0001716492633385782,0.0 +2008,Fla,14,F,0.0001183466966478298,0.0 +2008,Fla,15,M,0.000276365244306876,0.0 +2008,Fla,15,F,0.0002015258384914352,0.0 +2008,Fla,16,M,0.0003266283785622908,0.0006042296072507553 +2008,Fla,16,F,0.0003155388543071054,0.0006493506493506495 +2008,Fla,17,M,0.0005511615730151294,0.001186239620403322 +2008,Fla,17,F,0.00011553347582462022,0.0006285355122564425 +2008,Fla,18,M,0.0005697843366285863,0.0 +2008,Fla,18,F,0.0004492093914710112,0.0 +2008,Fla,19,M,0.0006351589340878251,0.0 +2008,Fla,19,F,0.0001810664815764855,0.0005047955577990914 +2008,Fla,20,M,0.0006129776117224671,0.002799552071668533 +2008,Fla,20,F,0.0001232247928283171,0.0 +2008,Fla,21,M,0.0004975561214036936,0.001042209484106305 +2008,Fla,21,F,0.0002468526289804987,0.0 +2008,Fla,22,M,0.0007259747723766599,0.000909090909090909 +2008,Fla,22,F,0.0003137254901960785,0.0 +2008,Fla,23,M,0.001038883941822499,0.0012111425111021401 +2008,Fla,23,F,0.0003386490979619482,0.0 +2008,Fla,24,M,0.0006970665117629974,0.0 +2008,Fla,24,F,0.0002689296599533855,0.0 +2008,Fla,25,M,0.0008226483603767162,0.00033057851239669435 +2008,Fla,25,F,0.0002674591381872214,0.0 +2008,Fla,26,M,0.00118372515553598,0.0009282178217821783 +2008,Fla,26,F,0.0004628022677311119,0.0002767783005812344 +2008,Fla,27,M,0.0006734195684502932,0.0008700696055684454 +2008,Fla,27,F,0.0002285844905423167,0.0005188067444876783 +2008,Fla,28,M,0.0008855925167432336,0.001432254368375824 +2008,Fla,28,F,0.0004032722663901371,0.0 +2008,Fla,29,M,0.0009913890777249036,0.0005720823798627003 +2008,Fla,29,F,0.0004037258124981977,0.000814774579033134 +2008,Fla,30,M,0.0006931407942238268,0.00027723870252287214 +2008,Fla,30,F,0.0003506311360448809,0.000275027502750275 +2008,Fla,31,M,0.0008505645989147968,0.001094990418833835 +2008,Fla,31,F,0.00027092113184828417,0.0 +2008,Fla,32,M,0.0009603841536614646,0.0002732987154960372 +2008,Fla,32,F,0.0002769145564751854,0.0002803476310625176 +2008,Fla,33,M,0.001066651291512915,0.001326611833377554 +2008,Fla,33,F,0.0003806846466953644,0.001148765077541643 +2008,Fla,34,M,0.000942010916244147,0.0010799136069114474 +2008,Fla,34,F,0.0003974224316575355,0.0 +2008,Fla,35,M,0.0011127301629354884,0.001572739187418087 +2008,Fla,35,F,0.0004824055959049125,0.0002725538293813028 +2008,Fla,36,M,0.001114883697359753,0.0010643959552953698 +2008,Fla,36,F,0.0004583534923989713,0.0008455467869222098 +2008,Fla,37,M,0.001006703169887298,0.0014988758431176616 +2008,Fla,37,F,0.0008753720331140737,0.0005408328826392644 +2008,Fla,38,M,0.001223990208078335,0.002074688796680498 +2008,Fla,38,F,0.0007491197842535021,0.001452221899506245 +2008,Fla,39,M,0.001261125797298281,0.0017948717948717949 +2008,Fla,39,F,0.0008394439918030762,0.0 +2008,Fla,40,M,0.001286971171845751,0.0005566379070414695 +2008,Fla,40,F,0.0008507948855073169,0.0 +2008,Fla,41,M,0.0014075873498762687,0.0010548523206751052 +2008,Fla,41,F,0.0008137642408742152,0.0003067484662576688 +2008,Fla,42,M,0.001231039788964608,0.0019089173711480784 +2008,Fla,42,F,0.0011507999187670653,0.0009581603321622484 +2008,Fla,43,M,0.001673161640121993,0.001917808219178082 +2008,Fla,43,F,0.001205208221241795,0.0009927200529450694 +2008,Fla,44,M,0.002126438003700002,0.0017793594306049821 +2008,Fla,44,F,0.001306449505726604,0.0003732736095558044 +2008,Fla,45,M,0.0019836136265631733,0.0031123560535325236 +2008,Fla,45,F,0.001305916465614556,0.0007544322897019992 +2008,Fla,46,M,0.002530761846583472,0.001643655489809336 +2008,Fla,46,F,0.001494899753781217,0.001231527093596059 +2008,Fla,47,M,0.002468641579930611,0.000984251968503937 +2008,Fla,47,F,0.001713409685273695,0.002879473467708762 +2008,Fla,48,M,0.002679551943773337,0.003972553268327917 +2008,Fla,48,F,0.002225733935765319,0.0008771929824561404 +2008,Fla,49,M,0.002937812563073266,0.0038234271810914148 +2008,Fla,49,F,0.002036520067731454,0.0009832841691248774 +2008,Fla,50,M,0.003805227060405132,0.005753739930955121 +2008,Fla,50,F,0.002261599440429005,0.0035300050428643467 +2008,Fla,51,M,0.004657398913273587,0.002407704654895666 +2008,Fla,51,F,0.002244218185254306,0.001599147121535181 +2008,Fla,52,M,0.004571237106000048,0.003248071457572067 +2008,Fla,52,F,0.003015652673400029,0.004986149584487534 +2008,Fla,53,M,0.004533091568449683,0.0037704231252618354 +2008,Fla,53,F,0.003034115296381263,0.005614823133071308 +2008,Fla,54,M,0.005372160160662735,0.006320541760722348 +2008,Fla,54,F,0.003785263050205888,0.00353356890459364 +2008,Fla,55,M,0.006126153380729089,0.004606172270842929 +2008,Fla,55,F,0.004175903490230447,0.003010234798314269 +2008,Fla,56,M,0.006845680322649119,0.004655493482309125 +2008,Fla,56,F,0.003972727760777365,0.00445859872611465 +2008,Fla,57,M,0.0075029688006045545,0.00872515753756665 +2008,Fla,57,F,0.0042839822174323035,0.004247572815533981 +2008,Fla,58,M,0.007665110253434455,0.008268259072117593 +2008,Fla,58,F,0.004255319148936171,0.005072923272035511 +2008,Fla,59,M,0.009096586743421946,0.009633911368015412 +2008,Fla,59,F,0.004315227358541453,0.005825242718446602 +2008,Fla,60,M,0.010179029544012579,0.01 +2008,Fla,60,F,0.005191824243086676,0.003188775510204082 +2008,Fla,61,M,0.0112079701120797,0.01107754279959718 +2008,Fla,61,F,0.005583427739116362,0.00350385423966363 +2008,Fla,62,M,0.01169662644668801,0.0146163215590743 +2008,Fla,62,F,0.00562456763016212,0.0095389507154213 +2008,Fla,63,M,0.012587063122716059,0.01307596513075965 +2008,Fla,63,F,0.0063966531255684215,0.002232142857142857 +2008,Fla,64,M,0.013824884792626729,0.009572431397574984 +2008,Fla,64,F,0.006746911624960406,0.001668056713928274 +2008,Fla,65,M,0.014739401306792282,0.019176136363636367 +2008,Fla,65,F,0.0069121071012805575,0.00530035335689046 +2008,Fla,66,M,0.01537935748462064,0.01793721973094171 +2008,Fla,66,F,0.007925445059540405,0.0115718418514947 +2008,Fla,67,M,0.01728462804734655,0.014318010550113041 +2008,Fla,67,F,0.008849875885886966,0.00894308943089431 +2008,Fla,68,M,0.01795759411510169,0.01775625504439064 +2008,Fla,68,F,0.00925024342745862,0.009861932938856016 +2008,Fla,69,M,0.01934229137199434,0.01726973684210527 +2008,Fla,69,F,0.01104972375690608,0.009193054136874362 +2008,Fla,70,M,0.021213579652734068,0.01682242990654206 +2008,Fla,70,F,0.01134888674410091,0.01577287066246057 +2008,Fla,71,M,0.02576533604410213,0.02463054187192119 +2008,Fla,71,F,0.0132881263056954,0.016465422612513717 +2008,Fla,72,M,0.02666827561240497,0.02968270214943705 +2008,Fla,72,F,0.01430002417878484,0.023779724655819786 +2008,Fla,73,M,0.03082978025582158,0.028669724770642214 +2008,Fla,73,F,0.01626099756940878,0.00979192166462668 +2008,Fla,74,M,0.03394930914639315,0.02886836027713626 +2008,Fla,74,F,0.01791242043755,0.02894736842105263 +2008,Fla,75,M,0.0377244994414368,0.04291287386215865 +2008,Fla,75,F,0.02121376688615844,0.02765647743813683 +2008,Fla,76,M,0.04391378230927466,0.03477051460361613 +2008,Fla,76,F,0.02371255004832252,0.03900709219858156 +2008,Fla,77,M,0.04956476240308234,0.05522388059701493 +2008,Fla,77,F,0.02748811803929915,0.03003003003003003 +2008,Fla,78,M,0.05592962641181581,0.04480286738351255 +2008,Fla,78,F,0.030051449953227317,0.03738317757009346 +2008,Fla,79,M,0.061177444142333615,0.0821917808219178 +2008,Fla,79,F,0.03833394765941762,0.04496402877697842 +2008,Fla,80,M,0.06540166927490873,0.07380952380952381 +2008,Fla,80,F,0.04124438177491848,0.06236559139784946 +2008,Fla,81,M,0.07646424721523536,0.06944444444444445 +2008,Fla,81,F,0.04889009941440828,0.04835164835164835 +2008,Fla,82,M,0.08749135081110171,0.07387862796833773 +2008,Fla,82,F,0.0572333989532818,0.05925925925925926 +2008,Fla,83,M,0.09890590809628008,0.1067961165048544 +2008,Fla,83,F,0.0636563185951709,0.06043956043956044 +2008,Fla,84,M,0.1059861626391256,0.1102941176470588 +2008,Fla,84,F,0.07164642599678367,0.05965909090909091 +2008,Fla,85,M,0.1177992005643076,0.1324786324786325 +2008,Fla,85,F,0.08574879227053141,0.103448275862069 +2008,Fla,86,M,0.1348611111111111,0.1325966850828729 +2008,Fla,86,F,0.0980310012568077,0.07327586206896551 +2008,Fla,87,M,0.146707091123463,0.1266666666666667 +2008,Fla,87,F,0.1101565636290646,0.1220657276995305 +2008,Fla,88,M,0.166491043203372,0.1444444444444444 +2008,Fla,88,F,0.1292054402290623,0.1206896551724138 +2008,Fla,89,M,0.1883561643835617,0.203125 +2008,Fla,89,F,0.14471387002909802,0.13 +2008,Fla,90,M,0.187732342007435,0.2380952380952381 +2008,Fla,90,F,0.1543370361616639,0.1235955056179775 +2008,Fla,91,M,0.2397782397782398,0.2307692307692308 +2008,Fla,91,F,0.1696733300828864,0.161764705882353 +2008,Fla,92,M,0.2365591397849463,0.2058823529411765 +2008,Fla,92,F,0.2002035105571101,0.1724137931034483 +2008,Fla,93,M,0.270909090909091,0.39130434782608703 +2008,Fla,93,F,0.2200542005420054,0.2105263157894737 +2008,Fla,94,M,0.2894736842105264,0.1875 +2008,Fla,94,F,0.2396265560165975,0.0975609756097561 +2008,Fla,95,M,0.3005671077504726,0.1666666666666667 +2008,Fla,95,F,0.2624768946395564,0.25 +2008,Fla,96,M,0.3304347826086957,0.25 +2008,Fla,96,F,0.2564625850340136,0.4117647058823529 +2008,Fla,97,M,0.3615023474178404,0.2 +2008,Fla,97,F,0.2804878048780488,0.1538461538461539 +2008,Fla,98,M,0.3565891472868218,0.3333333333333333 +2008,Fla,98,F,0.3094170403587444,0.3636363636363637 +2008,Fla,99,M,0.4020618556701031,0.5 +2008,Fla,99,F,0.3645621181262729,0.3333333333333333 +2008,Fla,100,M,0.4468085106382979,0.0 +2008,Fla,100,F,0.3843537414965986,0.25 +2008,Fla,101,M,0.4375,0.0 +2008,Fla,101,F,0.5286624203821656,0.8 +2008,Fla,102,M,0.4545454545454545,0.0 +2008,Fla,102,F,0.3035714285714286,0.3333333333333333 +2008,Fla,103,M,0.5555555555555556,0.0 +2008,Fla,103,F,0.3584905660377358,1.0 +2008,Fla,104,M,0.0,1.0 +2008,Fla,104,F,0.3214285714285715,0.0 +2008,Fla,105,M,1.0,0.0 +2008,Fla,105,F,0.25,0.0 +2008,Fla,106,M,0.0,0.0 +2008,Fla,106,F,0.25,0.0 +2008,Fla,107,M,0.0,0.0 +2008,Fla,107,F,0.5,0.0 +2008,Fla,108,M,0.0,0.0 +2008,Fla,108,F,0.3333333333333333,0.0 +2008,Fla,109,M,0.0,0.0 +2008,Fla,109,F,0.0,0.0 +2008,Fla,110,M,0.0,0.0 +2008,Fla,110,F,0.0,0.0 +2008,Fla,111,M,0.0,0.0 +2008,Fla,111,F,0.0,0.0 +2008,Fla,112,M,0.0,0.0 +2008,Fla,112,F,0.0,0.0 +2008,Fla,113,M,0.0,0.0 +2008,Fla,113,F,0.0,0.0 +2008,Fla,114,M,0.0,0.0 +2008,Fla,114,F,0.0,0.0 +2008,Fla,115,M,0.0,0.0 +2008,Fla,115,F,0.0,0.0 +2008,Fla,116,M,0.0,0.0 +2008,Fla,116,F,0.0,0.0 +2008,Fla,117,M,0.0,0.0 +2008,Fla,117,F,0.0,0.0 +2008,Fla,118,M,0.0,0.0 +2008,Fla,118,F,0.0,0.0 +2008,Fla,119,M,0.0,0.0 +2008,Fla,119,F,0.0,0.0 +2008,Fla,120,M,0.0,0.0 +2008,Fla,120,F,0.0,0.0 +2008,Wal,0,M,0.0005242463958060288,0.001020408163265306 +2008,Wal,0,F,0.0004988636993514771,0.0 +2008,Wal,1,M,0.0003072668612690122,0.0 +2008,Wal,1,F,0.0001057250092509383,0.0 +2008,Wal,2,M,0.0,0.0 +2008,Wal,2,F,0.00021393806493020268,0.0 +2008,Wal,3,M,0.0002046140467543097,0.0 +2008,Wal,3,F,0.0001080788975952445,0.0 +2008,Wal,4,M,0.0001039230969082879,0.0 +2008,Wal,4,F,0.0,0.0 +2008,Wal,5,M,0.0001540515559207148,0.0 +2008,Wal,5,F,0.0,0.0 +2008,Wal,6,M,9.944806324896822e-05,0.0010351966873706 +2008,Wal,6,F,0.0002067290299240271,0.0 +2008,Wal,7,M,9.767532721234616e-05,0.0 +2008,Wal,7,F,0.0,0.0 +2008,Wal,8,M,5.0107731622989425e-05,0.0 +2008,Wal,8,F,0.00010532413502554108,0.0 +2008,Wal,9,M,0.0,0.0 +2008,Wal,9,F,0.0,0.0 +2008,Wal,10,M,0.0001498426652015384,0.0 +2008,Wal,10,F,0.0001040907671489539,0.0 +2008,Wal,11,M,0.0001482872818941229,0.0 +2008,Wal,11,F,0.0,0.0 +2008,Wal,12,M,0.0002024393947062098,0.0009174311926605506 +2008,Wal,12,F,0.0001054240683147963,0.0 +2008,Wal,13,M,5.010522096402445e-05,0.0 +2008,Wal,13,F,0.0,0.0 +2008,Wal,14,M,4.81069899456391e-05,0.0018744142455482675 +2008,Wal,14,F,0.00015274171376202842,0.0 +2008,Wal,15,M,0.0003670903501124214,0.001740644038294169 +2008,Wal,15,F,0.0002881152460984393,0.0008710801393728223 +2008,Wal,16,M,0.0004487121959974872,0.0 +2008,Wal,16,F,0.00018654976214905333,0.0 +2008,Wal,17,M,0.0009560229445506693,0.001584786053882726 +2008,Wal,17,F,0.000142369020501139,0.0 +2008,Wal,18,M,0.000999727347087158,0.0 +2008,Wal,18,F,0.0005239093160602018,0.0006920415224913495 +2008,Wal,19,M,0.0008744477172312223,0.0 +2008,Wal,19,F,0.00029050062941803035,0.0 +2008,Wal,20,M,0.00114805070557283,0.0 +2008,Wal,20,F,0.0001500900540324195,0.0 +2008,Wal,21,M,0.00100995527340932,0.0 +2008,Wal,21,F,0.0002521177894312223,0.0 +2008,Wal,22,M,0.001363016810540664,0.0 +2008,Wal,22,F,0.0003671842215694503,0.0 +2008,Wal,23,M,0.0008258917049501884,0.0011848341232227491 +2008,Wal,23,F,0.0002136638000106832,0.0 +2008,Wal,24,M,0.001151410477835349,0.0016034206306787821 +2008,Wal,24,F,0.000336436021083324,0.00046663555762949143 +2008,Wal,25,M,0.0009484166710574844,0.001009591115598183 +2008,Wal,25,F,0.0003820752142350308,0.0004199916001679967 +2008,Wal,26,M,0.001059546514091969,0.0004789272030651341 +2008,Wal,26,F,0.000377725016188215,0.0004084967320261438 +2008,Wal,27,M,0.001172270474769542,0.001722652885443583 +2008,Wal,27,F,0.0003249038826013971,0.0 +2008,Wal,28,M,0.0012983500135244786,0.001666666666666667 +2008,Wal,28,F,0.0007826038347587902,0.0008012820512820513 +2008,Wal,29,M,0.0011536559907707519,0.0008080808080808081 +2008,Wal,29,F,0.0005036937541974478,0.0008035355564483727 +2008,Wal,30,M,0.001196562601979767,0.000814000814000814 +2008,Wal,30,F,0.0003884357138893513,0.0007833920877399138 +2008,Wal,31,M,0.001403130059363195,0.0011614401858304302 +2008,Wal,31,F,0.00010744600838078873,0.000411522633744856 +2008,Wal,32,M,0.001330140994945464,0.0 +2008,Wal,32,F,0.0004246059126373335,0.0007719027402547277 +2008,Wal,33,M,0.001689275659073458,0.001771165426850868 +2008,Wal,33,F,0.0006159215726530821,0.0003727171077152441 +2008,Wal,34,M,0.0014617033716624438,0.001315789473684211 +2008,Wal,34,F,0.00043990419864118474,0.0003603603603603604 +2008,Wal,35,M,0.001127078050154973,0.0006466214031684449 +2008,Wal,35,F,0.000517063081695967,0.0003404834865509023 +2008,Wal,36,M,0.001389918458117124,0.0009535918626827717 +2008,Wal,36,F,0.0009194134142417136,0.0 +2008,Wal,37,M,0.002710407028365812,0.0016249593760156 +2008,Wal,37,F,0.001087881941159777,0.0003369272237196766 +2008,Wal,38,M,0.0016936394429808062,0.001285760205721633 +2008,Wal,38,F,0.0013151714419915462,0.00103950103950104 +2008,Wal,39,M,0.0026423252462166712,0.0006576783952647156 +2008,Wal,39,F,0.0010861865407319948,0.00033523298692591364 +2008,Wal,40,M,0.002162162162162162,0.0022357074417119127 +2008,Wal,40,F,0.00107326178254783,0.000350385423966363 +2008,Wal,41,M,0.002401514801644114,0.004105571847507332 +2008,Wal,41,F,0.001414491695564884,0.0009686793671294801 +2008,Wal,42,M,0.003025583982202447,0.003769208466222094 +2008,Wal,42,F,0.0009715168911459484,0.000343878954607978 +2008,Wal,43,M,0.0037118563597911,0.001531393568147014 +2008,Wal,43,F,0.001321848882824493,0.001004016064257028 +2008,Wal,44,M,0.004096916299559472,0.0030553009471432947 +2008,Wal,44,F,0.002020549417479902,0.001386001386001386 +2008,Wal,45,M,0.003263382132982822,0.0028653295128939827 +2008,Wal,45,F,0.001666301249725937,0.002683020314296666 +2008,Wal,46,M,0.003805814931185557,0.0035381151495657774 +2008,Wal,46,F,0.0017157073003345633,0.00112739571589628 +2008,Wal,47,M,0.004807692307692308,0.004131012097964002 +2008,Wal,47,F,0.002184837229626393,0.001152073732718894 +2008,Wal,48,M,0.0054773779836123975,0.004719949653870359 +2008,Wal,48,F,0.0033461815409377787,0.002829426030719483 +2008,Wal,49,M,0.006588812650520289,0.00415335463258786 +2008,Wal,49,F,0.004108285763708701,0.003292181069958848 +2008,Wal,50,M,0.0061522805069849215,0.004533678756476684 +2008,Wal,50,F,0.003361195878112423,0.0012914334911752054 +2008,Wal,51,M,0.0067002471013115385,0.00825658939345824 +2008,Wal,51,F,0.003983172216254923,0.0029774564015312643 +2008,Wal,52,M,0.008295553197646377,0.005590266359750082 +2008,Wal,52,F,0.003873524907665976,0.002177700348432056 +2008,Wal,53,M,0.009046052631578948,0.007023411371237459 +2008,Wal,53,F,0.0042409594600757,0.002224199288256228 +2008,Wal,54,M,0.008717371075958666,0.009457092819614713 +2008,Wal,54,F,0.0039859102706711145,0.0028530670470756072 +2008,Wal,55,M,0.010571984241759341,0.007069635913750442 +2008,Wal,55,F,0.005517306422710554,0.0037842951750236523 +2008,Wal,56,M,0.010782644585461493,0.00943040362127499 +2008,Wal,56,F,0.004514022281982329,0.004300047778308648 +2008,Wal,57,M,0.012224328909290491,0.0067340067340067354 +2008,Wal,57,F,0.0060806281719812325,0.003287928604978864 +2008,Wal,58,M,0.01146233084225409,0.009652509652509652 +2008,Wal,58,F,0.00603448275862069,0.0036045314109165814 +2008,Wal,59,M,0.01330883448378607,0.009563886763580718 +2008,Wal,59,F,0.007187864644107351,0.0037842951750236523 +2008,Wal,60,M,0.01381953901245776,0.01245136186770428 +2008,Wal,60,F,0.0066818311060562975,0.005136106831022085 +2008,Wal,61,M,0.014523685580426859,0.012987012987012991 +2008,Wal,61,F,0.00758479225301722,0.005614823133071308 +2008,Wal,62,M,0.01760687372350166,0.01279317697228145 +2008,Wal,62,F,0.008875,0.005259697567389875 +2008,Wal,63,M,0.01892699587306105,0.01486988847583643 +2008,Wal,63,F,0.008717389910903147,0.004557291666666667 +2008,Wal,64,M,0.019983026001080168,0.017459361830222758 +2008,Wal,64,F,0.009773100054674685,0.003597122302158274 +2008,Wal,65,M,0.0208073981860217,0.01806451612903226 +2008,Wal,65,F,0.00956037928062064,0.008804108584005871 +2008,Wal,66,M,0.02253740042743346,0.01808439383791025 +2008,Wal,66,F,0.012405295146116059,0.00456968773800457 +2008,Wal,67,M,0.02275312855517634,0.01455427531837477 +2008,Wal,67,F,0.01271408271632638,0.01401273885350319 +2008,Wal,68,M,0.0264797507788162,0.02572347266881029 +2008,Wal,68,F,0.01304021301290367,0.01025641025641026 +2008,Wal,69,M,0.02670549084858569,0.028612303290414882 +2008,Wal,69,F,0.014416243654822341,0.0120253164556962 +2008,Wal,70,M,0.02742246364114246,0.02456140350877193 +2008,Wal,70,F,0.01585814171412096,0.011971830985915493 +2008,Wal,71,M,0.0312037037037037,0.03471698113207547 +2008,Wal,71,F,0.01700087183958152,0.01503221188260558 +2008,Wal,72,M,0.03260869565217391,0.03248259860788863 +2008,Wal,72,F,0.016810473073490033,0.02169349195241428 +2008,Wal,73,M,0.040530303030303035,0.04581993569131833 +2008,Wal,73,F,0.019955173161738133,0.01646090534979424 +2008,Wal,74,M,0.043562627340642285,0.04023972602739726 +2008,Wal,74,F,0.02266124346310285,0.02025139664804469 +2008,Wal,75,M,0.045056320400500616,0.04340277777777778 +2008,Wal,75,F,0.0256618592998849,0.01957831325301205 +2008,Wal,76,M,0.051537335285505116,0.05160662122687439 +2008,Wal,76,F,0.029320151679306614,0.02600297176820208 +2008,Wal,77,M,0.05253793825222396,0.06809701492537314 +2008,Wal,77,F,0.03372474057891863,0.028571428571428567 +2008,Wal,78,M,0.06629252893721503,0.07388137356919876 +2008,Wal,78,F,0.03543890865954923,0.036888532477947066 +2008,Wal,79,M,0.07335272543316049,0.09523809523809523 +2008,Wal,79,F,0.04451691187623237,0.05326460481099656 +2008,Wal,80,M,0.0774175899329777,0.09068627450980392 +2008,Wal,80,F,0.04664044312434777,0.0498220640569395 +2008,Wal,81,M,0.08436462420766677,0.08994708994708994 +2008,Wal,81,F,0.05869168188610328,0.061278863232682064 +2008,Wal,82,M,0.09558703794170333,0.1077654516640254 +2008,Wal,82,F,0.06095803306485799,0.07197696737044146 +2008,Wal,83,M,0.1113553113553114,0.1037414965986395 +2008,Wal,83,F,0.07123085440118103,0.07632743362831858 +2008,Wal,84,M,0.1162589305044382,0.1403508771929825 +2008,Wal,84,F,0.08479003415712276,0.09471094710947107 +2008,Wal,85,M,0.1344621513944223,0.1658031088082902 +2008,Wal,85,F,0.09487068028689416,0.1115646258503401 +2008,Wal,86,M,0.1473714449870727,0.1708860759493671 +2008,Wal,86,F,0.1045690061234103,0.109452736318408 +2008,Wal,87,M,0.1661364439731354,0.1306306306306306 +2008,Wal,87,F,0.1218172071830609,0.1469534050179212 +2008,Wal,88,M,0.1794434980124929,0.1804511278195489 +2008,Wal,88,F,0.1339285714285714,0.1117824773413897 +2008,Wal,89,M,0.2047325102880659,0.2207792207792208 +2008,Wal,89,F,0.1365235749472203,0.2116402116402116 +2008,Wal,90,M,0.2084993359893759,0.2407407407407408 +2008,Wal,90,F,0.1621510673234811,0.2038216560509554 +2008,Wal,91,M,0.2030769230769231,0.2765957446808511 +2008,Wal,91,F,0.1927653498334127,0.1386861313868613 +2008,Wal,92,M,0.2691588785046729,0.1666666666666667 +2008,Wal,92,F,0.1965025310630465,0.1666666666666667 +2008,Wal,93,M,0.2776659959758551,0.2972972972972973 +2008,Wal,93,F,0.2447013487475916,0.2195121951219512 +2008,Wal,94,M,0.2849162011173184,0.5789473684210527 +2008,Wal,94,F,0.2458563535911603,0.2735849056603774 +2008,Wal,95,M,0.4141414141414142,0.4583333333333333 +2008,Wal,95,F,0.2849462365591398,0.2631578947368421 +2008,Wal,96,M,0.392,0.3333333333333333 +2008,Wal,96,F,0.2974358974358975,0.2641509433962264 +2008,Wal,97,M,0.3068181818181818,0.2 +2008,Wal,97,F,0.2834645669291339,0.3095238095238096 +2008,Wal,98,M,0.423728813559322,0.25 +2008,Wal,98,F,0.332409972299169,0.4827586206896552 +2008,Wal,99,M,0.3125,0.5 +2008,Wal,99,F,0.3060344827586207,0.3571428571428572 +2008,Wal,100,M,0.5,0.0 +2008,Wal,100,F,0.3782051282051282,0.4285714285714286 +2008,Wal,101,M,0.2,0.0 +2008,Wal,101,F,0.325,0.7142857142857143 +2008,Wal,102,M,0.2222222222222222,0.0 +2008,Wal,102,F,0.3333333333333333,0.0 +2008,Wal,103,M,0.0,0.0 +2008,Wal,103,F,0.5384615384615384,0.0 +2008,Wal,104,M,1.0,0.0 +2008,Wal,104,F,0.7333333333333333,0.75 +2008,Wal,105,M,0.0,0.0 +2008,Wal,105,F,0.75,0.0 +2008,Wal,106,M,0.0,0.0 +2008,Wal,106,F,0.5,0.0 +2008,Wal,107,M,0.0,0.0 +2008,Wal,107,F,0.0,0.0 +2008,Wal,108,M,0.0,0.0 +2008,Wal,108,F,0.0,0.0 +2008,Wal,109,M,0.0,0.0 +2008,Wal,109,F,0.0,0.0 +2008,Wal,110,M,0.0,0.0 +2008,Wal,110,F,0.0,0.0 +2008,Wal,111,M,0.0,0.0 +2008,Wal,111,F,0.0,0.0 +2008,Wal,112,M,0.0,0.0 +2008,Wal,112,F,0.0,0.0 +2008,Wal,113,M,0.0,0.0 +2008,Wal,113,F,0.0,0.0 +2008,Wal,114,M,0.0,0.0 +2008,Wal,114,F,0.0,0.0 +2008,Wal,115,M,0.0,0.0 +2008,Wal,115,F,0.0,0.0 +2008,Wal,116,M,0.0,0.0 +2008,Wal,116,F,0.0,0.0 +2008,Wal,117,M,0.0,0.0 +2008,Wal,117,F,0.0,0.0 +2008,Wal,118,M,0.0,0.0 +2008,Wal,118,F,0.0,0.0 +2008,Wal,119,M,0.0,0.0 +2008,Wal,119,F,0.0,0.0 +2008,Wal,120,M,0.0,0.0 +2008,Wal,120,F,0.0,0.0 +2009,BruCap,0,M,0.00045864546705396726,0.0009442870632672332 +2009,BruCap,0,F,0.0006472491909385112,0.0 +2009,BruCap,1,M,0.0004721435316336166,0.0004904364884747426 +2009,BruCap,1,F,0.0,0.0 +2009,BruCap,2,M,0.00047664442326024784,0.0 +2009,BruCap,2,F,0.0001678697330871244,0.0005656108597285067 +2009,BruCap,3,M,0.0001690902942171119,0.0 +2009,BruCap,3,F,0.0,0.0 +2009,BruCap,4,M,0.0003463803255975061,0.0 +2009,BruCap,4,F,0.0,0.0 +2009,BruCap,5,M,0.0,0.0 +2009,BruCap,5,F,0.0,0.0 +2009,BruCap,6,M,0.0,0.0 +2009,BruCap,6,F,0.0002002803925495694,0.0 +2009,BruCap,7,M,0.0,0.0 +2009,BruCap,7,F,0.0,0.0 +2009,BruCap,8,M,0.0,0.0 +2009,BruCap,8,F,0.0,0.000784313725490196 +2009,BruCap,9,M,0.0,0.0 +2009,BruCap,9,F,0.0002111040743086342,0.0 +2009,BruCap,10,M,0.00021213406873143832,0.0008257638315441782 +2009,BruCap,10,F,0.0004380201489268507,0.0 +2009,BruCap,11,M,0.0,0.0 +2009,BruCap,11,F,0.000223563603845294,0.0 +2009,BruCap,12,M,0.0002164502164502165,0.0 +2009,BruCap,12,F,0.0,0.0 +2009,BruCap,13,M,0.0,0.0 +2009,BruCap,13,F,0.0,0.0 +2009,BruCap,14,M,0.0,0.0008431703204047218 +2009,BruCap,14,F,0.0,0.0 +2009,BruCap,15,M,0.0,0.0 +2009,BruCap,15,F,0.0,0.0 +2009,BruCap,16,M,0.0002125398512221042,0.0 +2009,BruCap,16,F,0.0006666666666666666,0.0 +2009,BruCap,17,M,0.0,0.0016570008285004142 +2009,BruCap,17,F,0.0,0.0 +2009,BruCap,18,M,0.0006365372374283894,0.0 +2009,BruCap,18,F,0.0,0.0 +2009,BruCap,19,M,0.001699235344095157,0.001395673412421493 +2009,BruCap,19,F,0.0006435006435006435,0.0 +2009,BruCap,20,M,0.0004164931278633903,0.0006199628022318662 +2009,BruCap,20,F,0.0002162162162162162,0.0004885197850512948 +2009,BruCap,21,M,0.001283971752621442,0.0005574136008918619 +2009,BruCap,21,F,0.0004221190375685944,0.0 +2009,BruCap,22,M,0.0002138122728244601,0.0005200208008320333 +2009,BruCap,22,F,0.0,0.0003680529996319471 +2009,BruCap,23,M,0.001267962806424345,0.0 +2009,BruCap,23,F,0.0006388415672913117,0.0 +2009,BruCap,24,M,0.0006092607636068237,0.0003849114703618168 +2009,BruCap,24,F,0.0,0.0 +2009,BruCap,25,M,0.0008051529790660223,0.0 +2009,BruCap,25,F,0.0,0.0005425935973955506 +2009,BruCap,26,M,0.0007531538316701186,0.0006029544769369913 +2009,BruCap,26,F,0.0005321979776476849,0.0 +2009,BruCap,27,M,0.0005455537370430987,0.0002868617326448652 +2009,BruCap,27,F,0.0001739130434782609,0.0007163323782234957 +2009,BruCap,28,M,0.001397624039133473,0.0007604562737642585 +2009,BruCap,28,F,0.0005118580447022691,0.00022079929344226093 +2009,BruCap,29,M,0.0008857395925597873,0.0 +2009,BruCap,29,F,0.0005373455131649651,0.0006705409029950827 +2009,BruCap,30,M,0.0005463485703879075,0.0 +2009,BruCap,30,F,0.0001797591227754809,0.0006976744186046513 +2009,BruCap,31,M,0.0007373271889400923,0.0004850836769342711 +2009,BruCap,31,F,0.0005501558774986246,0.0002457002457002457 +2009,BruCap,32,M,0.0007603117278084015,0.0009431737797689225 +2009,BruCap,32,F,0.0007580064430547659,0.0004957858205255329 +2009,BruCap,33,M,0.0007673124880107424,0.0002512562814070352 +2009,BruCap,33,F,0.0004016064257028113,0.0 +2009,BruCap,34,M,0.001146131805157593,0.0007621951219512195 +2009,BruCap,34,F,0.0004078303425774878,0.0002628120893561104 +2009,BruCap,35,M,0.001688238604389421,0.0005091649694501019 +2009,BruCap,35,F,0.001186943620178042,0.0002771618625277162 +2009,BruCap,36,M,0.0003820439350525311,0.00104602510460251 +2009,BruCap,36,F,0.0004036326942482341,0.0002790178571428572 +2009,BruCap,37,M,0.0020829388373414127,0.001368363437328955 +2009,BruCap,37,F,0.0016220600162206,0.0006058770069675858 +2009,BruCap,38,M,0.001698433666729572,0.0010612894667020429 +2009,BruCap,38,F,0.0002003606491685033,0.0009375 +2009,BruCap,39,M,0.001755412521942657,0.0008410428931875525 +2009,BruCap,39,F,0.002070822116380203,0.0006418485237483952 +2009,BruCap,40,M,0.001389716100853683,0.001439263097294186 +2009,BruCap,40,F,0.001728608470181504,0.0003455425017277125 +2009,BruCap,41,M,0.001227244835344651,0.001559575795383656 +2009,BruCap,41,F,0.002608695652173913,0.001104972375690608 +2009,BruCap,42,M,0.0008267879288962381,0.002234993614303959 +2009,BruCap,42,F,0.001045806316670153,0.001529051987767584 +2009,BruCap,43,M,0.0027755749405233947,0.002716468590831919 +2009,BruCap,43,F,0.001444490301279406,0.0 +2009,BruCap,44,M,0.002982107355864811,0.0006898930665746809 +2009,BruCap,44,F,0.001228249744114637,0.0008257638315441782 +2009,BruCap,45,M,0.00311332503113325,0.0019215987701767872 +2009,BruCap,45,F,0.002298370246552445,0.001325673884224481 +2009,BruCap,46,M,0.003194207836456559,0.002821442966545748 +2009,BruCap,46,F,0.002323616392057457,0.001415762151958471 +2009,BruCap,47,M,0.003293807641633729,0.003448275862068966 +2009,BruCap,47,F,0.002527379949452401,0.001474201474201474 +2009,BruCap,48,M,0.003177292946409659,0.002258355916892502 +2009,BruCap,48,F,0.0025850069596341217,0.001526717557251909 +2009,BruCap,49,M,0.0058428911491019255,0.005301204819277107 +2009,BruCap,49,F,0.002676549310273832,0.0005347593582887701 +2009,BruCap,50,M,0.007450891849175886,0.00199700449326011 +2009,BruCap,50,F,0.00269485903814262,0.0005807200929152149 +2009,BruCap,51,M,0.005816658911121451,0.002793296089385475 +2009,BruCap,51,F,0.0038159847360610564,0.0035735556879094702 +2009,BruCap,52,M,0.008280104092737165,0.005984766050054407 +2009,BruCap,52,F,0.005292125317527519,0.0049230769230769215 +2009,BruCap,53,M,0.008958038661008956,0.005163511187607574 +2009,BruCap,53,F,0.003611642234969195,0.001963350785340314 +2009,BruCap,54,M,0.005321722302854378,0.001271455816910363 +2009,BruCap,54,F,0.004759844223279966,0.0013218770654329153 +2009,BruCap,55,M,0.0100864553314121,0.008953168044077135 +2009,BruCap,55,F,0.005213990875515968,0.006502890173410405 +2009,BruCap,56,M,0.01072124756335283,0.007601935038009675 +2009,BruCap,56,F,0.004822446295484437,0.00204778156996587 +2009,BruCap,57,M,0.00860495436766623,0.010963194988253721 +2009,BruCap,57,F,0.0061248527679623075,0.003852080123266564 +2009,BruCap,58,M,0.007845188284518828,0.005805515239477504 +2009,BruCap,58,F,0.005894355021537067,0.005128205128205128 +2009,BruCap,59,M,0.01226993865030675,0.006289308176100629 +2009,BruCap,59,F,0.005161895823557016,0.0024174053182917012 +2009,BruCap,60,M,0.01352813852813853,0.006498781478472786 +2009,BruCap,60,F,0.008738781294284365,0.006779661016949152 +2009,BruCap,61,M,0.01182618261826183,0.007765314926660914 +2009,BruCap,61,F,0.006004618937644342,0.006956521739130435 +2009,BruCap,62,M,0.01721743960011108,0.0092678405931418 +2009,BruCap,62,F,0.008169149447381067,0.005434782608695652 +2009,BruCap,63,M,0.018133860863831192,0.01662971175166297 +2009,BruCap,63,F,0.00968783638320775,0.008121827411167513 +2009,BruCap,64,M,0.01957737725295215,0.0111731843575419 +2009,BruCap,64,F,0.0140882509303562,0.003080082135523614 +2009,BruCap,65,M,0.02058029689608637,0.01237623762376238 +2009,BruCap,65,F,0.009285312324141813,0.0069364161849710965 +2009,BruCap,66,M,0.01948051948051948,0.01945525291828794 +2009,BruCap,66,F,0.008957133717210493,0.009913258983890954 +2009,BruCap,67,M,0.02411282984531392,0.01188707280832095 +2009,BruCap,67,F,0.01100513573000734,0.0069637883008356535 +2009,BruCap,68,M,0.026656213249706,0.02945113788487283 +2009,BruCap,68,F,0.009490667510281556,0.0130718954248366 +2009,BruCap,69,M,0.02485966319165999,0.02124645892351275 +2009,BruCap,69,F,0.017895056111616618,0.007731958762886598 +2009,BruCap,70,M,0.024390243902439032,0.02794117647058824 +2009,BruCap,70,F,0.015203226807322369,0.011952191235059759 +2009,BruCap,71,M,0.029548332629801614,0.02627257799671593 +2009,BruCap,71,F,0.01668270773179339,0.011267605633802821 +2009,BruCap,72,M,0.02505399568034558,0.036971830985915485 +2009,BruCap,72,F,0.02597819114817191,0.01203208556149733 +2009,BruCap,73,M,0.03662349263063868,0.0285171102661597 +2009,BruCap,73,F,0.01741057296612852,0.01680672268907563 +2009,BruCap,74,M,0.03922432789775232,0.03992015968063873 +2009,BruCap,74,F,0.01968879009209273,0.03230769230769232 +2009,BruCap,75,M,0.03963133640552996,0.0272108843537415 +2009,BruCap,75,F,0.02314814814814815,0.0176678445229682 +2009,BruCap,76,M,0.05015959872321021,0.03921568627450981 +2009,BruCap,76,F,0.02159568086382724,0.02808988764044944 +2009,BruCap,77,M,0.049195837275307484,0.04663212435233161 +2009,BruCap,77,F,0.034188034188034185,0.018000000000000002 +2009,BruCap,78,M,0.06733167082294264,0.05012531328320802 +2009,BruCap,78,F,0.03576497303434573,0.030664395229982967 +2009,BruCap,79,M,0.05588714053174173,0.05187319884726225 +2009,BruCap,79,F,0.04583835946924004,0.0399002493765586 +2009,BruCap,80,M,0.07087486157253599,0.06474820143884892 +2009,BruCap,80,F,0.04452806522420822,0.03365384615384615 +2009,BruCap,81,M,0.07343283582089552,0.1 +2009,BruCap,81,F,0.04662379421221865,0.04359673024523161 +2009,BruCap,82,M,0.08779857972885732,0.1022222222222222 +2009,BruCap,82,F,0.057915057915057924,0.03883495145631068 +2009,BruCap,83,M,0.09985835694050993,0.06214689265536723 +2009,BruCap,83,F,0.05626684636118599,0.03773584905660377 +2009,BruCap,84,M,0.09872159090909093,0.06 +2009,BruCap,84,F,0.06691962745774405,0.07307692307692308 +2009,BruCap,85,M,0.1282952548330404,0.124031007751938 +2009,BruCap,85,F,0.07738944365192582,0.05045871559633028 +2009,BruCap,86,M,0.1290622098421541,0.0859375 +2009,BruCap,86,F,0.08498253783469151,0.1073446327683616 +2009,BruCap,87,M,0.1170731707317073,0.14893617021276598 +2009,BruCap,87,F,0.1050402371876324,0.1176470588235294 +2009,BruCap,88,M,0.1748427672955975,0.1363636363636364 +2009,BruCap,88,F,0.1004283674440743,0.1073446327683616 +2009,BruCap,89,M,0.1927710843373494,0.1590909090909091 +2009,BruCap,89,F,0.1166051660516605,0.1142857142857143 +2009,BruCap,90,M,0.2132352941176471,0.1333333333333333 +2009,BruCap,90,F,0.1557562076749436,0.1142857142857143 +2009,BruCap,91,M,0.1906779661016949,0.1 +2009,BruCap,91,F,0.159500693481276,0.234375 +2009,BruCap,92,M,0.2060606060606061,0.2 +2009,BruCap,92,F,0.1872146118721461,0.1694915254237288 +2009,BruCap,93,M,0.2649006622516557,0.5294117647058824 +2009,BruCap,93,F,0.2,0.2142857142857143 +2009,BruCap,94,M,0.2679738562091503,0.07692307692307693 +2009,BruCap,94,F,0.2266244057052298,0.1836734693877551 +2009,BruCap,95,M,0.2376237623762376,0.2857142857142857 +2009,BruCap,95,F,0.2449438202247191,0.36 +2009,BruCap,96,M,0.4696969696969697,0.2857142857142857 +2009,BruCap,96,F,0.2452830188679246,0.2222222222222222 +2009,BruCap,97,M,0.34,0.3333333333333333 +2009,BruCap,97,F,0.2060301507537689,0.25 +2009,BruCap,98,M,0.25,0.25 +2009,BruCap,98,F,0.3461538461538462,0.1428571428571429 +2009,BruCap,99,M,0.5625,1.0 +2009,BruCap,99,F,0.2673267326732674,0.1875 +2009,BruCap,100,M,0.1428571428571429,0.0 +2009,BruCap,100,F,0.2361111111111111,0.4444444444444444 +2009,BruCap,101,M,0.6666666666666666,0.0 +2009,BruCap,101,F,0.3571428571428572,0.0 +2009,BruCap,102,M,0.3333333333333333,0.0 +2009,BruCap,102,F,0.3225806451612903,1.0 +2009,BruCap,103,M,0.0,0.0 +2009,BruCap,103,F,0.2142857142857143,0.0 +2009,BruCap,104,M,0.0,0.0 +2009,BruCap,104,F,0.6666666666666666,1.0 +2009,BruCap,105,M,0.0,0.0 +2009,BruCap,105,F,1.0,0.0 +2009,BruCap,106,M,0.0,0.0 +2009,BruCap,106,F,1.0,0.0 +2009,BruCap,107,M,0.0,0.0 +2009,BruCap,107,F,0.5,0.0 +2009,BruCap,108,M,0.0,0.0 +2009,BruCap,108,F,0.0,0.0 +2009,BruCap,109,M,0.0,0.0 +2009,BruCap,109,F,0.0,0.0 +2009,BruCap,110,M,0.0,0.0 +2009,BruCap,110,F,1.0,0.0 +2009,BruCap,111,M,0.0,0.0 +2009,BruCap,111,F,0.0,0.0 +2009,BruCap,112,M,0.0,0.0 +2009,BruCap,112,F,0.0,0.0 +2009,BruCap,113,M,0.0,0.0 +2009,BruCap,113,F,0.0,0.0 +2009,BruCap,114,M,0.0,0.0 +2009,BruCap,114,F,0.0,0.0 +2009,BruCap,115,M,0.0,0.0 +2009,BruCap,115,F,0.0,0.0 +2009,BruCap,116,M,0.0,0.0 +2009,BruCap,116,F,0.0,0.0 +2009,BruCap,117,M,0.0,0.0 +2009,BruCap,117,F,0.0,0.0 +2009,BruCap,118,M,0.0,0.0 +2009,BruCap,118,F,0.0,0.0 +2009,BruCap,119,M,0.0,0.0 +2009,BruCap,119,F,0.0,0.0 +2009,BruCap,120,M,0.0,0.0 +2009,BruCap,120,F,0.0,0.0 +2009,Fla,0,M,0.0009368389241462678,0.0011976047904191619 +2009,Fla,0,F,0.0004756468797564688,0.0004271678769756515 +2009,Fla,1,M,0.0002788968081809731,0.0 +2009,Fla,1,F,0.0002897057876778472,0.001277683134582624 +2009,Fla,2,M,0.00012422746048013907,0.00044014084507042265 +2009,Fla,2,F,0.0001294624073534647,0.0 +2009,Fla,3,M,9.38174312787316e-05,0.0 +2009,Fla,3,F,6.627344423089668e-05,0.0 +2009,Fla,4,M,0.0001270688395438229,0.0 +2009,Fla,4,F,3.3599892480344065e-05,0.0 +2009,Fla,5,M,6.581545346847439e-05,0.0004805382027871216 +2009,Fla,5,F,0.00027551055549815764,0.0 +2009,Fla,6,M,9.873617693522908e-05,0.0 +2009,Fla,6,F,6.91323885240235e-05,0.000526592943654555 +2009,Fla,7,M,6.509569066527795e-05,0.0 +2009,Fla,7,F,0.0001357865435535339,0.0 +2009,Fla,8,M,9.523507190247928e-05,0.0 +2009,Fla,8,F,3.3091763460074794e-05,0.0005238344683080147 +2009,Fla,9,M,3.181774793980083e-05,0.0 +2009,Fla,9,F,6.572029442691903e-05,0.0 +2009,Fla,10,M,0.00012352923010407343,0.0005324813631522896 +2009,Fla,10,F,0.00012980269989615778,0.0 +2009,Fla,11,M,0.00015148760831364,0.0 +2009,Fla,11,F,6.295048944005539e-05,0.0 +2009,Fla,12,M,0.00012080942313500459,0.0 +2009,Fla,12,F,6.267431293284448e-05,0.0005917159763313612 +2009,Fla,13,M,0.00012018147402577894,0.0005787037037037037 +2009,Fla,13,F,6.257039169065198e-05,0.0 +2009,Fla,14,M,0.0002076042469897384,0.0 +2009,Fla,14,F,0.0002495165616617803,0.0 +2009,Fla,15,M,0.0002279462046956918,0.0 +2009,Fla,15,F,0.0002360996340455672,0.0 +2009,Fla,16,M,0.0002755428193541276,0.0 +2009,Fla,16,F,0.0002296672695432492,0.0 +2009,Fla,17,M,0.0004612921607467506,0.0 +2009,Fla,17,F,0.00022884604382401738,0.0 +2009,Fla,18,M,0.0003848585644775545,0.0005379236148466917 +2009,Fla,18,F,0.0002882425849595019,0.0 +2009,Fla,19,M,0.0006261384335154827,0.0 +2009,Fla,19,F,0.0001195921906299519,0.0 +2009,Fla,20,M,0.0005199757344657249,0.000975609756097561 +2009,Fla,20,F,0.0001804565550843635,0.0 +2009,Fla,21,M,0.0011084534157867099,0.0004597701149425287 +2009,Fla,21,F,0.0003072574202666995,0.0003518648838845883 +2009,Fla,22,M,0.0007605230058209261,0.001252086811352254 +2009,Fla,22,F,0.00021518598217030432,0.0003071253071253071 +2009,Fla,23,M,0.0006970330636118438,0.0 +2009,Fla,23,F,0.0003130380341211457,0.0 +2009,Fla,24,M,0.0006551323665167804,0.0003271180896303566 +2009,Fla,24,F,0.0001231413354677832,0.0 +2009,Fla,25,M,0.0006389590775754407,0.0003129890453834116 +2009,Fla,25,F,0.00029862334637321947,0.0 +2009,Fla,26,M,0.0006820894674018077,0.0005611672278338945 +2009,Fla,26,F,0.0002663115845539281,0.0 +2009,Fla,27,M,0.0007158393216045812,0.0002744990392533626 +2009,Fla,27,F,0.00034639032416361167,0.0005103342689461597 +2009,Fla,28,M,0.0007851274430081597,0.00102014792144861 +2009,Fla,28,F,0.00048361401911697774,0.00023769907297361542 +2009,Fla,29,M,0.001020633344367207,0.0007682458386683739 +2009,Fla,29,F,0.00048689674924817415,0.0 +2009,Fla,30,M,0.0009319927699954812,0.000255819902788437 +2009,Fla,30,F,0.0003154121863799283,0.000250501002004008 +2009,Fla,31,M,0.001035792381171596,0.0007641365257259298 +2009,Fla,31,F,0.0004646705195597247,0.0005162622612287042 +2009,Fla,32,M,0.0006728293938684765,0.0007470119521912348 +2009,Fla,32,F,0.0005378914654554146,0.0005230125523012552 +2009,Fla,33,M,0.0009568519570612683,0.0007618080243778567 +2009,Fla,33,F,0.0005491823285330732,0.0008034279592929834 +2009,Fla,34,M,0.001234851530641549,0.0004961548002976929 +2009,Fla,34,F,0.0003781378166904215,0.0 +2009,Fla,35,M,0.001215939866246615,0.0005148005148005149 +2009,Fla,35,F,0.0005363595302619691,0.0002759381898454746 +2009,Fla,36,M,0.001029567053854277,0.0002452182442373713 +2009,Fla,36,F,0.0005065991201173177,0.0002642706131078224 +2009,Fla,37,M,0.001137167694329324,0.001508295625942685 +2009,Fla,37,F,0.0005321575186255132,0.0008264462809917355 +2009,Fla,38,M,0.001395485482054547,0.0007146260123868509 +2009,Fla,38,F,0.0006724614579960649,0.0 +2009,Fla,39,M,0.001489403262037309,0.00048685491723466414 +2009,Fla,39,F,0.0006967600656945205,0.0008453085376162299 +2009,Fla,40,M,0.001573278470289241,0.00098159509202454 +2009,Fla,40,F,0.0008617081517591157,0.001426533523537803 +2009,Fla,41,M,0.001402721279281807,0.0026631158455392807 +2009,Fla,41,F,0.0009941080910699997,0.0006024096385542169 +2009,Fla,42,M,0.001542474764659181,0.002325581395348837 +2009,Fla,42,F,0.0009973095834492996,0.0006044122091266245 +2009,Fla,43,M,0.001538630618749313,0.000784313725490196 +2009,Fla,43,F,0.00117206870125772,0.0009413241292751805 +2009,Fla,44,M,0.002284892208094442,0.002394890899414582 +2009,Fla,44,F,0.0012682444487435779,0.0006538084341288003 +2009,Fla,45,M,0.002065587734241908,0.001147117866360769 +2009,Fla,45,F,0.0011314186248912099,0.00072992700729927 +2009,Fla,46,M,0.002372786298237667,0.0012051822838204278 +2009,Fla,46,F,0.001370317162117361,0.001129943502824859 +2009,Fla,47,M,0.002335071907120878,0.001899335232668566 +2009,Fla,47,F,0.0017588989292702767,0.002030044660982542 +2009,Fla,48,M,0.0024927665257066553,0.004786215698787492 +2009,Fla,48,F,0.0019599008785762557,0.001640016400164002 +2009,Fla,49,M,0.003387146439097348,0.003480682213713888 +2009,Fla,49,F,0.002183746685384496,0.0004355400696864112 +2009,Fla,50,M,0.003571669249949458,0.0013793103448275859 +2009,Fla,50,F,0.002540452704094478,0.002436647173489279 +2009,Fla,51,M,0.004316349601479893,0.005611672278338946 +2009,Fla,51,F,0.002706170535401843,0.003970223325062035 +2009,Fla,52,M,0.004365781710914454,0.002766798418972332 +2009,Fla,52,F,0.003146737330241802,0.0015856236786469349 +2009,Fla,53,M,0.005498331292468007,0.0032076984763432237 +2009,Fla,53,F,0.00318967791447826,0.001623376623376624 +2009,Fla,54,M,0.00504143816245727,0.0053366174055829215 +2009,Fla,54,F,0.003460122092879563,0.0010989010989010991 +2009,Fla,55,M,0.005693699140906457,0.004508566275924256 +2009,Fla,55,F,0.003361301413799297,0.001752336448598131 +2009,Fla,56,M,0.0064426125554850975,0.005537609598523304 +2009,Fla,56,F,0.003672382134636771,0.0054249547920434 +2009,Fla,57,M,0.008009611533840609,0.00797373358348968 +2009,Fla,57,F,0.0044432476100713615,0.007060333761232348 +2009,Fla,58,M,0.007882148293107197,0.006809338521400778 +2009,Fla,58,F,0.004351351351351352,0.003629764065335753 +2009,Fla,59,M,0.00807460170735686,0.01158480074142725 +2009,Fla,59,F,0.004954153551389079,0.005674653215636823 +2009,Fla,60,M,0.0093711467324291,0.0072744907856450046 +2009,Fla,60,F,0.004793240718173694,0.003865979381443299 +2009,Fla,61,M,0.01096668243939099,0.009713701431492843 +2009,Fla,61,F,0.005460732122276494,0.007046764894298526 +2009,Fla,62,M,0.01089366361023676,0.007135575942915392 +2009,Fla,62,F,0.00607078974470161,0.005617977528089887 +2009,Fla,63,M,0.01138980519076368,0.00674432863274065 +2009,Fla,63,F,0.005980788980849393,0.00963855421686747 +2009,Fla,64,M,0.014004362532798027,0.011443102352193259 +2009,Fla,64,F,0.007565588773642466,0.006024096385542169 +2009,Fla,65,M,0.01431192660550459,0.013409961685823759 +2009,Fla,65,F,0.007679316827581812,0.004248088360237893 +2009,Fla,66,M,0.01484137080297599,0.0170940170940171 +2009,Fla,66,F,0.0081312724342539,0.006211180124223602 +2009,Fla,67,M,0.017260071989244983,0.01076923076923077 +2009,Fla,67,F,0.008788827353720201,0.0107421875 +2009,Fla,68,M,0.01881527545244359,0.01785714285714286 +2009,Fla,68,F,0.01065951198288677,0.01235584843492587 +2009,Fla,69,M,0.0222417969610218,0.01580698835274543 +2009,Fla,69,F,0.01073825503355705,0.016881827209533268 +2009,Fla,70,M,0.02105187267942756,0.026182432432432432 +2009,Fla,70,F,0.01139224165752275,0.01732925586136595 +2009,Fla,71,M,0.02441421012849584,0.01990521327014218 +2009,Fla,71,F,0.01386551793767248,0.01822079314040729 +2009,Fla,72,M,0.0278479996789856,0.02989690721649485 +2009,Fla,72,F,0.013355534741735179,0.0136830102622577 +2009,Fla,73,M,0.03157155254349353,0.032085561497326213 +2009,Fla,73,F,0.014635341899793432,0.01552393272962484 +2009,Fla,74,M,0.03158161755379868,0.03106332138590203 +2009,Fla,74,F,0.01788137067316055,0.020100502512562814 +2009,Fla,75,M,0.03751316251316252,0.03473053892215569 +2009,Fla,75,F,0.01996177532384795,0.03382949932341002 +2009,Fla,76,M,0.04325892857142858,0.0340599455040872 +2009,Fla,76,F,0.02233242015466241,0.020926756352765318 +2009,Fla,77,M,0.04841652243064976,0.03907380607814761 +2009,Fla,77,F,0.02595015025631961,0.027881040892193308 +2009,Fla,78,M,0.05188301282051282,0.05079365079365079 +2009,Fla,78,F,0.02987197724039829,0.01602564102564103 +2009,Fla,79,M,0.0598940336328035,0.05019305019305019 +2009,Fla,79,F,0.03483886522542795,0.033398821218074665 +2009,Fla,80,M,0.06466032865327709,0.04772234273318872 +2009,Fla,80,F,0.04261484701269922,0.05671077504725897 +2009,Fla,81,M,0.07254175693619401,0.07387862796833773 +2009,Fla,81,F,0.04455787005104153,0.04377880184331797 +2009,Fla,82,M,0.08675692499221911,0.08484848484848485 +2009,Fla,82,F,0.056872490919518265,0.06103286384976527 +2009,Fla,83,M,0.09855830031194672,0.0942857142857143 +2009,Fla,83,F,0.06386879902210453,0.09042553191489362 +2009,Fla,84,M,0.1071775919081891,0.1082089552238806 +2009,Fla,84,F,0.07353023281782145,0.06784660766961652 +2009,Fla,85,M,0.1193979557452544,0.1416309012875537 +2009,Fla,85,F,0.08538627122697919,0.06116207951070336 +2009,Fla,86,M,0.1365456486919381,0.1457286432160804 +2009,Fla,86,F,0.0954070981210856,0.07327586206896551 +2009,Fla,87,M,0.1472531013371999,0.1069182389937107 +2009,Fla,87,F,0.1076994649918586,0.1047619047619048 +2009,Fla,88,M,0.1630025747672807,0.1317829457364341 +2009,Fla,88,F,0.1190454668715539,0.1147540983606558 +2009,Fla,89,M,0.1778481012658228,0.1333333333333333 +2009,Fla,89,F,0.140406258578095,0.1515151515151515 +2009,Fla,90,M,0.1897280966767372,0.1923076923076923 +2009,Fla,90,F,0.1509090909090909,0.1428571428571429 +2009,Fla,91,M,0.25,0.1290322580645161 +2009,Fla,91,F,0.1819708846584547,0.1298701298701299 +2009,Fla,92,M,0.2353479853479854,0.103448275862069 +2009,Fla,92,F,0.2,0.1864406779661017 +2009,Fla,93,M,0.264346190028222,0.3076923076923077 +2009,Fla,93,F,0.2031299904183967,0.12 +2009,Fla,94,M,0.2710163111668758,0.4285714285714286 +2009,Fla,94,F,0.2446845590798188,0.1063829787234043 +2009,Fla,95,M,0.2921348314606742,0.2142857142857143 +2009,Fla,95,F,0.258256880733945,0.1388888888888889 +2009,Fla,96,M,0.3643835616438356,0.6666666666666666 +2009,Fla,96,F,0.2811320754716981,0.2121212121212121 +2009,Fla,97,M,0.33628318584070804,0.6 +2009,Fla,97,F,0.2853211009174312,0.3333333333333333 +2009,Fla,98,M,0.3582089552238806,0.5 +2009,Fla,98,F,0.3101983002832861,0.09090909090909093 +2009,Fla,99,M,0.4166666666666667,0.0 +2009,Fla,99,F,0.3201754385964912,0.2857142857142857 +2009,Fla,100,M,0.3448275862068966,0.0 +2009,Fla,100,F,0.3814102564102564,0.25 +2009,Fla,101,M,0.4,1.0 +2009,Fla,101,F,0.3756906077348066,0.3333333333333333 +2009,Fla,102,M,0.2222222222222222,0.0 +2009,Fla,102,F,0.3378378378378379,0.0 +2009,Fla,103,M,0.3333333333333333,0.0 +2009,Fla,103,F,0.3461538461538462,0.0 +2009,Fla,104,M,0.75,0.0 +2009,Fla,104,F,0.4375,0.0 +2009,Fla,105,M,0.0,0.0 +2009,Fla,105,F,0.631578947368421,1.0 +2009,Fla,106,M,0.0,0.0 +2009,Fla,106,F,0.5714285714285714,1.0 +2009,Fla,107,M,0.0,0.0 +2009,Fla,107,F,0.3333333333333333,0.0 +2009,Fla,108,M,0.0,0.0 +2009,Fla,108,F,1.0,0.0 +2009,Fla,109,M,0.0,0.0 +2009,Fla,109,F,0.0,0.0 +2009,Fla,110,M,0.0,0.0 +2009,Fla,110,F,0.0,0.0 +2009,Fla,111,M,0.0,0.0 +2009,Fla,111,F,0.0,0.0 +2009,Fla,112,M,0.0,0.0 +2009,Fla,112,F,0.0,0.0 +2009,Fla,113,M,0.0,0.0 +2009,Fla,113,F,0.0,0.0 +2009,Fla,114,M,0.0,0.0 +2009,Fla,114,F,0.0,0.0 +2009,Fla,115,M,0.0,0.0 +2009,Fla,115,F,0.0,0.0 +2009,Fla,116,M,0.0,0.0 +2009,Fla,116,F,0.0,0.0 +2009,Fla,117,M,0.0,0.0 +2009,Fla,117,F,0.0,0.0 +2009,Fla,118,M,0.0,0.0 +2009,Fla,118,F,0.0,0.0 +2009,Fla,119,M,0.0,0.0 +2009,Fla,119,F,0.0,0.0 +2009,Fla,120,M,0.0,0.0 +2009,Fla,120,F,0.0,0.0 +2009,Wal,0,M,0.001221125470642109,0.0 +2009,Wal,0,F,0.0006484033068568651,0.0 +2009,Wal,1,M,0.0003044140030441401,0.0 +2009,Wal,1,F,0.0003222687721559781,0.0 +2009,Wal,2,M,0.0001517297187942545,0.0 +2009,Wal,2,F,0.0001567807682257643,0.0 +2009,Wal,3,M,0.0004578987534978377,0.001021450459652707 +2009,Wal,3,F,0.0002118756290057736,0.0 +2009,Wal,4,M,0.0002034277577175406,0.0 +2009,Wal,4,F,0.0002144427169892243,0.0 +2009,Wal,5,M,0.0,0.0 +2009,Wal,5,F,5.308700960874874e-05,0.0 +2009,Wal,6,M,5.103342689461598e-05,0.001004016064257028 +2009,Wal,6,F,0.0001075211010160744,0.0 +2009,Wal,7,M,4.948535233570863e-05,0.0 +2009,Wal,7,F,0.0001541386220007193,0.001074113856068743 +2009,Wal,8,M,4.852249017419574e-05,0.0 +2009,Wal,8,F,5.112735824939926e-05,0.0 +2009,Wal,9,M,0.000149655791679138,0.0 +2009,Wal,9,F,0.0002097975453687192,0.0 +2009,Wal,10,M,9.971580994166626e-05,0.0 +2009,Wal,10,F,0.0,0.0 +2009,Wal,11,M,9.941346058256288e-05,0.0 +2009,Wal,11,F,5.181078700585462e-05,0.0 +2009,Wal,12,M,0.0002456278247199843,0.0 +2009,Wal,12,F,0.00010284891494394731,0.0 +2009,Wal,13,M,0.0002015113350125945,0.0 +2009,Wal,13,F,0.000104942806170637,0.0 +2009,Wal,14,M,9.983527180152747e-05,0.0 +2009,Wal,14,F,0.00015682174594877158,0.0 +2009,Wal,15,M,0.0003349282296650718,0.0 +2009,Wal,15,F,0.0001013068584743187,0.0 +2009,Wal,16,M,0.0002745115981150204,0.0 +2009,Wal,16,F,0.00023933751376190707,0.000846740050804403 +2009,Wal,17,M,0.0006254188072369888,0.0 +2009,Wal,17,F,0.00023224487900041813,0.0008183306055646483 +2009,Wal,18,M,0.0009084714967067908,0.001511715797430083 +2009,Wal,18,F,0.0003778932451582428,0.001411432604093155 +2009,Wal,19,M,0.0008168822328114364,0.0 +2009,Wal,19,F,0.0003325573661456601,0.0 +2009,Wal,20,M,0.0007825806748607468,0.0 +2009,Wal,20,F,0.00024199012680282646,0.0006180469715698393 +2009,Wal,21,M,0.001006325474410581,0.001339584728734093 +2009,Wal,21,F,0.0005502751375687844,0.0005408328826392644 +2009,Wal,22,M,0.0007713817375373638,0.0006277463904582549 +2009,Wal,22,F,0.0006067347557892608,0.0 +2009,Wal,23,M,0.0008645679702995473,0.002326934264107039 +2009,Wal,23,F,0.00047526007287321124,0.0 +2009,Wal,24,M,0.001041775184915095,0.0 +2009,Wal,24,F,0.0002153779883695887,0.0 +2009,Wal,25,M,0.001428571428571429,0.0004887585532746823 +2009,Wal,25,F,0.0003950338600451469,0.0008976660682226213 +2009,Wal,26,M,0.00100924253691703,0.0009220839096357767 +2009,Wal,26,F,0.0002743634767339772,0.0 +2009,Wal,27,M,0.0011725203858658,0.000445632798573975 +2009,Wal,27,F,0.0005370569280343716,0.0 +2009,Wal,28,M,0.001117021276595745,0.0012515644555694619 +2009,Wal,28,F,0.0004299457193529317,0.00037664783427495286 +2009,Wal,29,M,0.0008632782993417503,0.00038431975403535736 +2009,Wal,29,F,0.00044424700133274093,0.0 +2009,Wal,30,M,0.0009298255209757695,0.001527883880825057 +2009,Wal,30,F,0.00044375416019525195,0.0 +2009,Wal,31,M,0.0010285281221241813,0.0007763975155279503 +2009,Wal,31,F,0.0005485764441274892,0.0007451564828614009 +2009,Wal,32,M,0.0009092367759533614,0.001155179052753177 +2009,Wal,32,F,0.0002658160552897395,0.0 +2009,Wal,33,M,0.001055631795629684,0.0007572889057175312 +2009,Wal,33,F,0.0006304176516942475,0.0 +2009,Wal,34,M,0.001062591711784648,0.0027739251040221928 +2009,Wal,34,F,0.0006111224281931147,0.0 +2009,Wal,35,M,0.0015998448635283849,0.0006495615459564793 +2009,Wal,35,F,0.0006304252946025896,0.0007092198581560284 +2009,Wal,36,M,0.001583752561952674,0.00032299741602067185 +2009,Wal,36,F,0.0006069944436662465,0.0003410641200545703 +2009,Wal,37,M,0.0013338852858654161,0.0006343165239454488 +2009,Wal,37,F,0.0009127002236115547,0.0007057163020465772 +2009,Wal,38,M,0.001956582502562191,0.0003205128205128205 +2009,Wal,38,F,0.001031411157993437,0.001020755358965634 +2009,Wal,39,M,0.001968503937007874,0.000962463907603465 +2009,Wal,39,F,0.001400429465035945,0.0003447087211306446 +2009,Wal,40,M,0.001723725161599234,0.002952755905511811 +2009,Wal,40,F,0.0007046223224351747,0.001007387508394896 +2009,Wal,41,M,0.002620863949080358,0.0009618467457518436 +2009,Wal,41,F,0.001533029824398402,0.001060070671378092 +2009,Wal,42,M,0.002855169237854018,0.0029472443265546712 +2009,Wal,42,F,0.0017729690412328961,0.001310615989515072 +2009,Wal,43,M,0.002887220716919114,0.0008759124087591243 +2009,Wal,43,F,0.001715945089757128,0.002735042735042735 +2009,Wal,44,M,0.0030610045268376807,0.0027734976887519264 +2009,Wal,44,F,0.001485568760611206,0.0003404834865509023 +2009,Wal,45,M,0.003474360102031841,0.003355704697986577 +2009,Wal,45,F,0.0019298396088858391,0.0007005253940455343 +2009,Wal,46,M,0.003900049884358986,0.001919385796545106 +2009,Wal,46,F,0.00223292469352014,0.001937233630375823 +2009,Wal,47,M,0.004300407873736478,0.004820051413881748 +2009,Wal,47,F,0.0032993401319736052,0.001889644746787604 +2009,Wal,48,M,0.005036997414638495,0.004788985333732416 +2009,Wal,48,F,0.0026635228364334986,0.003087610961018912 +2009,Wal,49,M,0.005983478455012279,0.003192848020434228 +2009,Wal,49,F,0.00262489415749365,0.002052545155993432 +2009,Wal,50,M,0.006565149995440868,0.004829362524146813 +2009,Wal,50,F,0.00329089806876245,0.00125 +2009,Wal,51,M,0.007739722853037956,0.0036101083032490976 +2009,Wal,51,F,0.003717143110009736,0.001722652885443583 +2009,Wal,52,M,0.007631403224267862,0.005756315957787015 +2009,Wal,52,F,0.00385149357337991,0.0012931034482758616 +2009,Wal,53,M,0.007504599593299119,0.005661005661005661 +2009,Wal,53,F,0.00400738439371426,0.004363001745200698 +2009,Wal,54,M,0.009484897125346564,0.006449422946367957 +2009,Wal,54,F,0.004799561182977557,0.002244165170556553 +2009,Wal,55,M,0.00895933838731909,0.0056757715501951035 +2009,Wal,55,F,0.005058474104325229,0.00285442435775452 +2009,Wal,56,M,0.009987452948557091,0.00604551920341394 +2009,Wal,56,F,0.0054381236109140784,0.003795066413662239 +2009,Wal,57,M,0.01139497372391904,0.0068311195445920295 +2009,Wal,57,F,0.005299161768956547,0.002904162633107454 +2009,Wal,58,M,0.013348780979246421,0.009523809523809523 +2009,Wal,58,F,0.00586594864890855,0.003787878787878789 +2009,Wal,59,M,0.01264596399979603,0.008637612877895563 +2009,Wal,59,F,0.006348595613697576,0.0062370062370062365 +2009,Wal,60,M,0.01302685846494317,0.0078125 +2009,Wal,60,F,0.006754538205356724,0.0038259206121472977 +2009,Wal,61,M,0.01435357817847474,0.01351351351351352 +2009,Wal,61,F,0.007104033565366644,0.007212776919113859 +2009,Wal,62,M,0.014875771482829559,0.01534526854219949 +2009,Wal,62,F,0.008453410182516809,0.0039347948285553686 +2009,Wal,63,M,0.01667620956198111,0.01454741379310345 +2009,Wal,63,F,0.008946008946008947,0.006626905235255136 +2009,Wal,64,M,0.01970300615718942,0.011911207363291829 +2009,Wal,64,F,0.01047052740434333,0.003304692663582287 +2009,Wal,65,M,0.02090866216003773,0.01791229153798641 +2009,Wal,65,F,0.01130956485759603,0.01015965166908563 +2009,Wal,66,M,0.019517066085693542,0.01982815598149372 +2009,Wal,66,F,0.01097079715864246,0.005235602094240838 +2009,Wal,67,M,0.021445591739475783,0.022053756030323918 +2009,Wal,67,F,0.01304164913756837,0.008435582822085891 +2009,Wal,68,M,0.024488336759317192,0.02109181141439206 +2009,Wal,68,F,0.01171579743008315,0.01809954751131222 +2009,Wal,69,M,0.02280376977448671,0.015251989389920432 +2009,Wal,69,F,0.012233895493502909,0.01432291666666667 +2009,Wal,70,M,0.030657557643040137,0.01789709172259508 +2009,Wal,70,F,0.01618655692729767,0.01743060038734668 +2009,Wal,71,M,0.03109789075175771,0.028860028860028863 +2009,Wal,71,F,0.01551635804728098,0.014347202295552369 +2009,Wal,72,M,0.031032177981476183,0.035685963521015066 +2009,Wal,72,F,0.020150575730735167,0.01955104996379435 +2009,Wal,73,M,0.03583224902412172,0.0413961038961039 +2009,Wal,73,F,0.0188422247446084,0.01779359430604983 +2009,Wal,74,M,0.03805580203095732,0.02991452991452992 +2009,Wal,74,F,0.02351120283018868,0.0243393602225313 +2009,Wal,75,M,0.04643146796431468,0.04541326067211626 +2009,Wal,75,F,0.02570770488149194,0.025659301496792592 +2009,Wal,76,M,0.05151729004940014,0.050644567219152864 +2009,Wal,76,F,0.02736111111111111,0.028352490421455937 +2009,Wal,77,M,0.057139915577061676,0.04708290685772774 +2009,Wal,77,F,0.03179472876865151,0.03601532567049808 +2009,Wal,78,M,0.06037151702786377,0.06513026052104208 +2009,Wal,78,F,0.03961864406779661,0.03878326996197719 +2009,Wal,79,M,0.06890083781418031,0.06440677966101695 +2009,Wal,79,F,0.04217561650149805,0.04481327800829876 +2009,Wal,80,M,0.07535836177474403,0.0685640362225097 +2009,Wal,80,F,0.05091859360152043,0.041780199818346964 +2009,Wal,81,M,0.08245588017203026,0.09029649595687332 +2009,Wal,81,F,0.05423614620178541,0.05 +2009,Wal,82,M,0.09066886870355076,0.09649122807017543 +2009,Wal,82,F,0.06122629025143361,0.07202993451824134 +2009,Wal,83,M,0.1011883327331653,0.1046099290780142 +2009,Wal,83,F,0.07072531839942191,0.06843718079673136 +2009,Wal,84,M,0.1170037144036319,0.1532710280373832 +2009,Wal,84,F,0.07875894988066827,0.08382526564344746 +2009,Wal,85,M,0.12659470068694806,0.1278026905829597 +2009,Wal,85,F,0.0958123218592414,0.09416445623342172 +2009,Wal,86,M,0.1494385257702275,0.1919504643962848 +2009,Wal,86,F,0.1063114950803936,0.112759643916914 +2009,Wal,87,M,0.1596355045561931,0.1679389312977099 +2009,Wal,87,F,0.115835198104515,0.1293260473588343 +2009,Wal,88,M,0.1834394904458599,0.1413612565445026 +2009,Wal,88,F,0.126984126984127,0.1428571428571429 +2009,Wal,89,M,0.1913709116214336,0.1651376146788991 +2009,Wal,89,F,0.1398416886543536,0.1785714285714286 +2009,Wal,90,M,0.1783854166666667,0.2241379310344828 +2009,Wal,90,F,0.1591555014210313,0.1455696202531646 +2009,Wal,91,M,0.2293423271500843,0.2 +2009,Wal,91,F,0.1815505397448479,0.1363636363636364 +2009,Wal,92,M,0.2325581395348837,0.3333333333333333 +2009,Wal,92,F,0.1906729634002361,0.208 +2009,Wal,93,M,0.2596401028277635,0.2222222222222222 +2009,Wal,93,F,0.2176403207331043,0.2601626016260163 +2009,Wal,94,M,0.3008356545961003,0.1481481481481482 +2009,Wal,94,F,0.2302798982188295,0.1875 +2009,Wal,95,M,0.29296875,0.1818181818181818 +2009,Wal,95,F,0.2618613138686132,0.2716049382716049 +2009,Wal,96,M,0.4310344827586207,0.4285714285714286 +2009,Wal,96,F,0.2970922882427307,0.3518518518518519 +2009,Wal,97,M,0.2368421052631579,0.75 +2009,Wal,97,F,0.2667876588021779,0.35 +2009,Wal,98,M,0.4166666666666667,0.5 +2009,Wal,98,F,0.2991689750692521,0.2424242424242425 +2009,Wal,99,M,0.5151515151515151,0.3333333333333333 +2009,Wal,99,F,0.4033613445378152,0.2941176470588236 +2009,Wal,100,M,0.3636363636363637,0.5 +2009,Wal,100,F,0.3548387096774194,0.6153846153846154 +2009,Wal,101,M,0.2727272727272727,0.0 +2009,Wal,101,F,0.3814432989690722,0.3333333333333333 +2009,Wal,102,M,0.5,0.0 +2009,Wal,102,F,0.3703703703703704,0.0 +2009,Wal,103,M,0.8571428571428571,0.0 +2009,Wal,103,F,0.4324324324324325,0.3333333333333333 +2009,Wal,104,M,0.0,0.0 +2009,Wal,104,F,0.4545454545454545,0.0 +2009,Wal,105,M,0.0,0.0 +2009,Wal,105,F,0.25,0.5 +2009,Wal,106,M,0.0,0.0 +2009,Wal,106,F,0.0,0.0 +2009,Wal,107,M,0.0,0.0 +2009,Wal,107,F,0.5,0.0 +2009,Wal,108,M,0.0,0.0 +2009,Wal,108,F,0.0,0.0 +2009,Wal,109,M,0.0,0.0 +2009,Wal,109,F,0.0,0.0 +2009,Wal,110,M,0.0,0.0 +2009,Wal,110,F,0.0,0.0 +2009,Wal,111,M,0.0,0.0 +2009,Wal,111,F,0.0,0.0 +2009,Wal,112,M,0.0,0.0 +2009,Wal,112,F,0.0,0.0 +2009,Wal,113,M,0.0,0.0 +2009,Wal,113,F,0.0,0.0 +2009,Wal,114,M,0.0,0.0 +2009,Wal,114,F,0.0,0.0 +2009,Wal,115,M,0.0,0.0 +2009,Wal,115,F,0.0,0.0 +2009,Wal,116,M,0.0,0.0 +2009,Wal,116,F,0.0,0.0 +2009,Wal,117,M,0.0,0.0 +2009,Wal,117,F,0.0,0.0 +2009,Wal,118,M,0.0,0.0 +2009,Wal,118,F,0.0,0.0 +2009,Wal,119,M,0.0,0.0 +2009,Wal,119,F,0.0,0.0 +2009,Wal,120,M,0.0,0.0 +2009,Wal,120,F,0.0,0.0 +2010,BruCap,0,M,0.0008915304606240713,0.0008598452278589854 +2010,BruCap,0,F,0.0006239276243955701,0.000882223202470225 +2010,BruCap,1,M,0.0,0.001363016810540664 +2010,BruCap,1,F,0.0,0.0 +2010,BruCap,2,M,0.000160926939169617,0.0 +2010,BruCap,2,F,0.0006755615605472049,0.0 +2010,BruCap,3,M,0.0003250975292587777,0.0 +2010,BruCap,3,F,0.0001712035610340695,0.0 +2010,BruCap,4,M,0.0,0.0005675368898978432 +2010,BruCap,4,F,0.00035486160397445,0.0 +2010,BruCap,5,M,0.0,0.0 +2010,BruCap,5,F,0.0001838911364472233,0.0 +2010,BruCap,6,M,0.0,0.0 +2010,BruCap,6,F,0.0003896356906292616,0.0 +2010,BruCap,7,M,0.0,0.0 +2010,BruCap,7,F,0.0,0.0 +2010,BruCap,8,M,0.0003960396039603961,0.0 +2010,BruCap,8,F,0.0,0.0 +2010,BruCap,9,M,0.00019952114924181967,0.0 +2010,BruCap,9,F,0.0002125850340136054,0.0 +2010,BruCap,10,M,0.0,0.0 +2010,BruCap,10,F,0.0,0.0 +2010,BruCap,11,M,0.0,0.0 +2010,BruCap,11,F,0.0,0.0 +2010,BruCap,12,M,0.0002076411960132891,0.0 +2010,BruCap,12,F,0.0004504504504504505,0.0 +2010,BruCap,13,M,0.00043327556325823216,0.0007855459544383348 +2010,BruCap,13,F,0.0,0.0 +2010,BruCap,14,M,0.00021834061135371185,0.0 +2010,BruCap,14,F,0.0,0.0 +2010,BruCap,15,M,0.0,0.0 +2010,BruCap,15,F,0.0,0.0 +2010,BruCap,16,M,0.0006472491909385112,0.0 +2010,BruCap,16,F,0.0,0.0 +2010,BruCap,17,M,0.0006333122229259026,0.0 +2010,BruCap,17,F,0.0004396570674873599,0.0008598452278589854 +2010,BruCap,18,M,0.0002106149957877001,0.0007267441860465116 +2010,BruCap,18,F,0.0,0.0 +2010,BruCap,19,M,0.0,0.0006397952655150353 +2010,BruCap,19,F,0.0002142245072836333,0.0 +2010,BruCap,20,M,0.0004202563563773902,0.001754385964912281 +2010,BruCap,20,F,0.000211595429538722,0.0 +2010,BruCap,21,M,0.0008220304151253597,0.0005488474204171242 +2010,BruCap,21,F,0.00021199915200339198,0.0 +2010,BruCap,22,M,0.000211864406779661,0.0 +2010,BruCap,22,F,0.000408997955010225,0.0 +2010,BruCap,23,M,0.00020807324178110704,0.0004486316733961418 +2010,BruCap,23,F,0.0,0.0 +2010,BruCap,24,M,0.0002050861361771944,0.0003875968992248062 +2010,BruCap,24,F,0.0008040201005025126,0.00028200789622109416 +2010,BruCap,25,M,0.0005911330049261082,0.0019563090968373 +2010,BruCap,25,F,0.0009110787172011662,0.0004952947003467064 +2010,BruCap,26,M,0.0007705644384511655,0.0006273525721455458 +2010,BruCap,26,F,0.0001806684733514002,0.0 +2010,BruCap,27,M,0.001110494169905608,0.0002675943270002676 +2010,BruCap,27,F,0.000353857041755131,0.00045372050816696913 +2010,BruCap,28,M,0.0007247689798876608,0.00102537810817739 +2010,BruCap,28,F,0.0006946856547412296,0.0006721935917544253 +2010,BruCap,29,M,0.000176678445229682,0.0006931608133086876 +2010,BruCap,29,F,0.0006882312456985548,0.00042105263157894734 +2010,BruCap,30,M,0.0007127583749109052,0.0004600874166091557 +2010,BruCap,30,F,0.0003616636528028933,0.0002141786249732277 +2010,BruCap,31,M,0.0007344840249724567,0.0004599816007359706 +2010,BruCap,31,F,0.0005433798224959246,0.0002242655303879794 +2010,BruCap,32,M,0.0007384160974709249,0.0006926806742091898 +2010,BruCap,32,F,0.0005512679162072766,0.0007058823529411765 +2010,BruCap,33,M,0.0005724098454493418,0.0004554771122751082 +2010,BruCap,33,F,0.0005797101449275362,0.0 +2010,BruCap,34,M,0.0005785920925747347,0.0 +2010,BruCap,34,F,0.0004079135223332654,0.00024987506246876555 +2010,BruCap,35,M,0.000967305088024763,0.0012106537530266349 +2010,BruCap,35,F,0.0,0.0 +2010,BruCap,36,M,0.0007575757575757576,0.0002483854942871337 +2010,BruCap,36,F,0.0008028904054596548,0.0005483959418700301 +2010,BruCap,37,M,0.001534919416730622,0.0007772020725388603 +2010,BruCap,37,F,0.00020181634712411708,0.000825536598789213 +2010,BruCap,38,M,0.001333333333333333,0.0010908099263703301 +2010,BruCap,38,F,0.0008221993833504625,0.0003017501508750755 +2010,BruCap,39,M,0.0009493070058857033,0.001569037656903766 +2010,BruCap,39,F,0.0004012841091492777,0.0009322560596643877 +2010,BruCap,40,M,0.001941370607649,0.0010989010989010991 +2010,BruCap,40,F,0.0002085070892410342,0.0003177629488401653 +2010,BruCap,41,M,0.0007936507936507938,0.0005698005698005698 +2010,BruCap,41,F,0.0006437768240343348,0.00033863867253640373 +2010,BruCap,42,M,0.0008213552361396304,0.001228501228501229 +2010,BruCap,42,F,0.0010924186148131964,0.000736648250460405 +2010,BruCap,43,M,0.001859888406695599,0.0034953924372418178 +2010,BruCap,43,F,0.001047998323202683,0.001932740626207963 +2010,BruCap,44,M,0.0037750844426783225,0.002053388090349076 +2010,BruCap,44,F,0.0014373716632443527,0.0008084074373484238 +2010,BruCap,45,M,0.002994609702535436,0.002031144211238998 +2010,BruCap,45,F,0.002042066571370227,0.001221995926680245 +2010,BruCap,46,M,0.004174493842621583,0.002297970126388357 +2010,BruCap,46,F,0.00251994960100798,0.0021654395842356 +2010,BruCap,47,M,0.00299017513882956,0.0028078620136381873 +2010,BruCap,47,F,0.00253057781526782,0.0023353573096683788 +2010,BruCap,48,M,0.0053015241882041104,0.0029686174724342677 +2010,BruCap,48,F,0.001900739176346357,0.000949667616334283 +2010,BruCap,49,M,0.004261666311527808,0.003584229390681004 +2010,BruCap,49,F,0.002781088597536751,0.001968503937007874 +2010,BruCap,50,M,0.006110868616324749,0.003357314148681055 +2010,BruCap,50,F,0.003491476689258575,0.001037344398340249 +2010,BruCap,51,M,0.005921202459576406,0.004513540621865597 +2010,BruCap,51,F,0.003741425898981501,0.002829654782116582 +2010,BruCap,52,M,0.0060790273556231,0.003908431044109436 +2010,BruCap,52,F,0.003192168546499255,0.0017452006980802786 +2010,BruCap,53,M,0.004536771728748806,0.005952380952380952 +2010,BruCap,53,F,0.002967359050445104,0.005474452554744526 +2010,BruCap,54,M,0.007868383404864092,0.004029936672423719 +2010,BruCap,54,F,0.0029869852784296987,0.003759398496240602 +2010,BruCap,55,M,0.00929322572756175,0.003838771593090211 +2010,BruCap,55,F,0.0036940460669274227,0.002580645161290323 +2010,BruCap,56,M,0.008505467800729041,0.005606166783461808 +2010,BruCap,56,F,0.0034972677595628424,0.0035435861091424525 +2010,BruCap,57,M,0.0093734583127775,0.007719298245614035 +2010,BruCap,57,F,0.0041785792830437655,0.003346720214190094 +2010,BruCap,58,M,0.01082937136819863,0.00792393026941363 +2010,BruCap,58,F,0.005451528798293436,0.003081664098613252 +2010,BruCap,59,M,0.0136518771331058,0.010463378176382659 +2010,BruCap,59,F,0.00546448087431694,0.003665689149560118 +2010,BruCap,60,M,0.013598041881969,0.005742411812961444 +2010,BruCap,60,F,0.007112375533428166,0.0057189542483660144 +2010,BruCap,61,M,0.015405777166437418,0.009159034138218152 +2010,BruCap,61,F,0.00714455822814956,0.002581755593803787 +2010,BruCap,62,M,0.012376933895921241,0.008071748878923767 +2010,BruCap,62,F,0.006290773532152842,0.006200177147918512 +2010,BruCap,63,M,0.014797951052931132,0.01633045148895293 +2010,BruCap,63,F,0.010199125789218073,0.005560704355885079 +2010,BruCap,64,M,0.02332657200811359,0.008083140877598153 +2010,BruCap,64,F,0.010618023414102907,0.004123711340206186 +2010,BruCap,65,M,0.0194888178913738,0.013333333333333341 +2010,BruCap,65,F,0.01081958344603733,0.006263048016701462 +2010,BruCap,66,M,0.02427184466019418,0.0103359173126615 +2010,BruCap,66,F,0.012275192691978307,0.008196721311475409 +2010,BruCap,67,M,0.0235201881615053,0.01335113484646195 +2010,BruCap,67,F,0.01256443298969072,0.005108556832694764 +2010,BruCap,68,M,0.02614379084967321,0.02024922118380062 +2010,BruCap,68,F,0.0117820324005891,0.00424929178470255 +2010,BruCap,69,M,0.02546483427647535,0.02086230876216968 +2010,BruCap,69,F,0.01630956188039655,0.004524886877828055 +2010,BruCap,70,M,0.02913418137053755,0.028744326777609682 +2010,BruCap,70,F,0.014728444308069959,0.008985879332477536 +2010,BruCap,71,M,0.03151862464183381,0.03732503888024884 +2010,BruCap,71,F,0.016393442622950817,0.009308510638297872 +2010,BruCap,72,M,0.03563667970447632,0.032148900169204735 +2010,BruCap,72,F,0.020175724048161408,0.01457725947521866 +2010,BruCap,73,M,0.03442188879082083,0.03345724907063197 +2010,BruCap,73,F,0.01901639344262295,0.01345895020188426 +2010,BruCap,74,M,0.041512915129151284,0.04016064257028113 +2010,BruCap,74,F,0.01697629724535554,0.02031930333817126 +2010,BruCap,75,M,0.0462878093492209,0.025157232704402517 +2010,BruCap,75,F,0.01852453688657784,0.02392344497607656 +2010,BruCap,76,M,0.04032645223235718,0.03747072599531616 +2010,BruCap,76,F,0.027874564459930317,0.02363636363636364 +2010,BruCap,77,M,0.04467680608365019,0.04608294930875576 +2010,BruCap,77,F,0.030405405405405414,0.035502958579881665 +2010,BruCap,78,M,0.06112224448897795,0.047619047619047616 +2010,BruCap,78,F,0.03608736942070275,0.032388663967611336 +2010,BruCap,79,M,0.06300053390282967,0.06043956043956044 +2010,BruCap,79,F,0.03963593658250147,0.042857142857142864 +2010,BruCap,80,M,0.0768348623853211,0.04923076923076923 +2010,BruCap,80,F,0.03656597774244833,0.03865979381443298 +2010,BruCap,81,M,0.08988095238095238,0.09411764705882353 +2010,BruCap,81,F,0.04442250740375124,0.04228855721393035 +2010,BruCap,82,M,0.08676092544987146,0.09137055837563453 +2010,BruCap,82,F,0.051771117166212535,0.04310344827586207 +2010,BruCap,83,M,0.07960199004975124,0.1020408163265306 +2010,BruCap,83,F,0.06471600688468157,0.0584192439862543 +2010,BruCap,84,M,0.1098814229249012,0.1075949367088608 +2010,BruCap,84,F,0.06487455197132616,0.06666666666666668 +2010,BruCap,85,M,0.1184834123222749,0.1492537313432836 +2010,BruCap,85,F,0.08143444153903623,0.09745762711864407 +2010,BruCap,86,M,0.1508097165991903,0.08928571428571429 +2010,BruCap,86,F,0.09044834307992204,0.06829268292682927 +2010,BruCap,87,M,0.1379310344827586,0.1293103448275862 +2010,BruCap,87,F,0.1079229122055674,0.06832298136645963 +2010,BruCap,88,M,0.153072625698324,0.1428571428571429 +2010,BruCap,88,F,0.1201716738197425,0.1068702290076336 +2010,BruCap,89,M,0.1836115326251897,0.06779661016949153 +2010,BruCap,89,F,0.1348012889366273,0.1132075471698113 +2010,BruCap,90,M,0.195,0.1351351351351352 +2010,BruCap,90,F,0.1366723259762309,0.1098901098901099 +2010,BruCap,91,M,0.1932367149758454,0.1923076923076923 +2010,BruCap,91,F,0.1653116531165312,0.1451612903225807 +2010,BruCap,92,M,0.2072538860103627,0.05555555555555555 +2010,BruCap,92,F,0.1683168316831683,0.1521739130434783 +2010,BruCap,93,M,0.2384615384615385,0.1538461538461539 +2010,BruCap,93,F,0.1701323251417769,0.1666666666666667 +2010,BruCap,94,M,0.3243243243243244,0.25 +2010,BruCap,94,F,0.2256809338521401,0.1612903225806452 +2010,BruCap,95,M,0.2972972972972973,0.08333333333333333 +2010,BruCap,95,F,0.2288659793814433,0.1052631578947368 +2010,BruCap,96,M,0.3866666666666667,0.2 +2010,BruCap,96,F,0.2738461538461539,0.1875 +2010,BruCap,97,M,0.2222222222222222,0.0 +2010,BruCap,97,F,0.2551440329218107,0.25 +2010,BruCap,98,M,0.28125,0.0 +2010,BruCap,98,F,0.2820512820512821,0.1538461538461539 +2010,BruCap,99,M,0.48,0.0 +2010,BruCap,99,F,0.3050847457627119,0.2727272727272727 +2010,BruCap,100,M,0.4285714285714286,0.0 +2010,BruCap,100,F,0.3888888888888889,0.07142857142857142 +2010,BruCap,101,M,0.5,0.0 +2010,BruCap,101,F,0.3962264150943397,0.0 +2010,BruCap,102,M,1.0,0.0 +2010,BruCap,102,F,0.3703703703703704,0.0 +2010,BruCap,103,M,0.0,0.0 +2010,BruCap,103,F,0.5217391304347826,0.0 +2010,BruCap,104,M,0.0,0.0 +2010,BruCap,104,F,0.4545454545454545,0.0 +2010,BruCap,105,M,1.0,0.0 +2010,BruCap,105,F,0.75,0.0 +2010,BruCap,106,M,0.0,0.0 +2010,BruCap,106,F,0.0,0.0 +2010,BruCap,107,M,0.0,0.0 +2010,BruCap,107,F,0.0,0.0 +2010,BruCap,108,M,0.0,0.0 +2010,BruCap,108,F,1.0,0.0 +2010,BruCap,109,M,0.0,0.0 +2010,BruCap,109,F,0.0,0.0 +2010,BruCap,110,M,0.0,0.0 +2010,BruCap,110,F,0.0,0.0 +2010,BruCap,111,M,0.0,0.0 +2010,BruCap,111,F,0.0,0.0 +2010,BruCap,112,M,0.0,0.0 +2010,BruCap,112,F,0.0,0.0 +2010,BruCap,113,M,0.0,0.0 +2010,BruCap,113,F,0.0,0.0 +2010,BruCap,114,M,0.0,0.0 +2010,BruCap,114,F,0.0,0.0 +2010,BruCap,115,M,0.0,0.0 +2010,BruCap,115,F,0.0,0.0 +2010,BruCap,116,M,0.0,0.0 +2010,BruCap,116,F,0.0,0.0 +2010,BruCap,117,M,0.0,0.0 +2010,BruCap,117,F,0.0,0.0 +2010,BruCap,118,M,0.0,0.0 +2010,BruCap,118,F,0.0,0.0 +2010,BruCap,119,M,0.0,0.0 +2010,BruCap,119,F,0.0,0.0 +2010,BruCap,120,M,0.0,0.0 +2010,BruCap,120,F,0.0,0.0 +2010,Fla,0,M,0.0008561382051674056,0.001096892138939671 +2010,Fla,0,F,0.0007125967674019369,0.001920860545524395 +2010,Fla,1,M,0.0002992130696268813,0.001132930513595166 +2010,Fla,1,F,0.00015709438230488882,0.0 +2010,Fla,2,M,6.142883469500583e-05,0.0008041817450743867 +2010,Fla,2,F,0.00012770168885483507,0.0004048582995951417 +2010,Fla,3,M,0.00018477457501847748,0.0 +2010,Fla,3,F,0.0001283903065318569,0.0 +2010,Fla,4,M,0.000186422246388069,0.000441696113074205 +2010,Fla,4,F,6.586530545035402e-05,0.0 +2010,Fla,5,M,6.314327208435941e-05,0.0 +2010,Fla,5,F,3.333666700003334e-05,0.0 +2010,Fla,6,M,0.0001634948662611994,0.0004608294930875576 +2010,Fla,6,F,3.422899195618689e-05,0.0 +2010,Fla,7,M,3.275681341719078e-05,0.0 +2010,Fla,7,F,0.0,0.0004982561036372695 +2010,Fla,8,M,6.469351447517386e-05,0.0004897159647404506 +2010,Fla,8,F,6.757669955399377e-05,0.0 +2010,Fla,9,M,0.0001580228184949907,0.0 +2010,Fla,9,F,0.00013170025023047548,0.0 +2010,Fla,10,M,6.335128286347799e-05,0.0 +2010,Fla,10,F,3.2696834946377194e-05,0.0 +2010,Fla,11,M,3.077301821762679e-05,0.0 +2010,Fla,11,F,6.459531038046638e-05,0.0 +2010,Fla,12,M,0.0002111741281525281,0.0 +2010,Fla,12,F,0.00012541937102185428,0.0 +2010,Fla,13,M,0.0002106276704579648,0.0 +2010,Fla,13,F,9.37353538509608e-05,0.0 +2010,Fla,14,M,0.0002696225284601558,0.0005467468562055769 +2010,Fla,14,F,9.352787130564908e-05,0.000572737686139748 +2010,Fla,15,M,0.0003253667770941789,0.0005151983513652757 +2010,Fla,15,F,0.00018664841659926591,0.0 +2010,Fla,16,M,0.0003125532761266125,0.0 +2010,Fla,16,F,5.888761299060743e-05,0.0 +2010,Fla,17,M,0.0002748385323622372,0.0 +2010,Fla,17,F,0.00022918039361732607,0.0 +2010,Fla,18,M,0.0006769747353028785,0.0 +2010,Fla,18,F,0.0002568199977171556,0.0 +2010,Fla,19,M,0.0003844358404042068,0.00049800796812749 +2010,Fla,19,F,0.0001724683089482308,0.0 +2010,Fla,20,M,0.000483462730711259,0.0004904364884747426 +2010,Fla,20,F,0.0002686807773830493,0.0004168403501458942 +2010,Fla,21,M,0.001010305112143868,0.000429553264604811 +2010,Fla,21,F,0.00039044901636882417,0.0003442340791738384 +2010,Fla,22,M,0.0008174705126707929,0.0007797270955165693 +2010,Fla,22,F,0.0002458059362133596,0.0 +2010,Fla,23,M,0.000877860361678469,0.0003607503607503608 +2010,Fla,23,F,0.0001841055538508745,0.0002677376171352075 +2010,Fla,24,M,0.0009095594700300154,0.0 +2010,Fla,24,F,0.0002817077751345938,0.0002430724355858046 +2010,Fla,25,M,0.0007745010425975572,0.0011357183418512213 +2010,Fla,25,F,0.0004309681391411421,0.00023546032493524838 +2010,Fla,26,M,0.0007861177429686135,0.001110185956147655 +2010,Fla,26,F,0.0004177857356013132,0.00046674445740956834 +2010,Fla,27,M,0.0009661835748792268,0.0 +2010,Fla,27,F,0.0002063618407476195,0.0002275312855517634 +2010,Fla,28,M,0.0007420640373780402,0.000514668039114771 +2010,Fla,28,F,0.0002874389192296637,0.0002325040688212044 +2010,Fla,29,M,0.0009237745989978443,0.0009476427386875149 +2010,Fla,29,F,0.00033977008890650665,0.000449034575662326 +2010,Fla,30,M,0.0007709675642931879,0.0009571667863125153 +2010,Fla,30,F,0.00048408223702944364,0.0002284669865204478 +2010,Fla,31,M,0.0009284789826121207,0.0002384927259718579 +2010,Fla,31,F,0.0004275453198038992,0.0002344116268166901 +2010,Fla,32,M,0.0010610231704519392,0.0004832085044696786 +2010,Fla,32,F,0.0004621606008087812,0.00048355899419729207 +2010,Fla,33,M,0.0008740749373579628,0.0004658746797111577 +2010,Fla,33,F,0.0002966478789676654,0.0 +2010,Fla,34,M,0.0008043135035300426,0.0004829751267809708 +2010,Fla,34,F,0.0005453884377651194,0.0002513194269917065 +2010,Fla,35,M,0.001085900440075441,0.001670245764733954 +2010,Fla,35,F,0.0005782853838369235,0.0 +2010,Fla,36,M,0.001128109178956637,0.0009784735812133072 +2010,Fla,36,F,0.000645976688667322,0.001043296817944705 +2010,Fla,37,M,0.001341222879684418,0.0007085498346717053 +2010,Fla,37,F,0.0006895271435012067,0.0010180707559175359 +2010,Fla,38,M,0.0010320177204993961,0.001689189189189189 +2010,Fla,38,F,0.0007064997981429148,0.0007976601967561817 +2010,Fla,39,M,0.001320519404299024,0.0006922011998154131 +2010,Fla,39,F,0.0006941861906532787,0.0007686395080707147 +2010,Fla,40,M,0.001048473617477811,0.0014357501794687731 +2010,Fla,40,F,0.0007192995510578664,0.0 +2010,Fla,41,M,0.001376711832475908,0.0004789272030651341 +2010,Fla,41,F,0.0007610536911104019,0.0013892747985551552 +2010,Fla,42,M,0.0015648355754858,0.00233584220088243 +2010,Fla,42,F,0.001329594352850167,0.001190121987503719 +2010,Fla,43,M,0.0014499977343785401,0.003028009084027252 +2010,Fla,43,F,0.001179136224914455,0.001787842669845054 +2010,Fla,44,M,0.001668166553260607,0.003309572301425662 +2010,Fla,44,F,0.001169459125154616,0.001883239171374765 +2010,Fla,45,M,0.0020963916652549553,0.002375296912114015 +2010,Fla,45,F,0.001245811495832975,0.0016165535079211118 +2010,Fla,46,M,0.00212915451274299,0.00140686550365785 +2010,Fla,46,F,0.0015224010439321446,0.0010695187165775401 +2010,Fla,47,M,0.002072225699915816,0.001474056603773585 +2010,Fla,47,F,0.001613081427466579,0.0007344840249724567 +2010,Fla,48,M,0.00297248267873145,0.002503912363067293 +2010,Fla,48,F,0.0018023562510989981,0.0007968127490039841 +2010,Fla,49,M,0.002740275364256116,0.003123048094940662 +2010,Fla,49,F,0.002050242198941084,0.002403846153846154 +2010,Fla,50,M,0.0035493827160493828,0.002062564455139223 +2010,Fla,50,F,0.002185694850235297,0.003829787234042553 +2010,Fla,51,M,0.0039203316510454216,0.0031023784901758012 +2010,Fla,51,F,0.002475531207738327,0.0033034450212364322 +2010,Fla,52,M,0.004197825388814975,0.002623688155922039 +2010,Fla,52,F,0.002873093363855084,0.00291970802919708 +2010,Fla,53,M,0.004781857349146604,0.003174603174603175 +2010,Fla,53,F,0.003105295595695255,0.00257201646090535 +2010,Fla,54,M,0.005138101555903992,0.004387714399680893 +2010,Fla,54,F,0.0031006633977502173,0.002669514148424987 +2010,Fla,55,M,0.006098916022617843,0.0050125313283208035 +2010,Fla,55,F,0.003318885448916409,0.0021598272138228947 +2010,Fla,56,M,0.006332640964587872,0.002669039145907474 +2010,Fla,56,F,0.003319010986183652,0.002883506343713957 +2010,Fla,57,M,0.0069164412230105655,0.007383479464697739 +2010,Fla,57,F,0.004252229827836547,0.004764740917212627 +2010,Fla,58,M,0.006748944637143395,0.00615530303030303 +2010,Fla,58,F,0.004595960961366893,0.0038436899423446506 +2010,Fla,59,M,0.007993430057486997,0.005429417571569595 +2010,Fla,59,F,0.004177857356013131,0.004186602870813397 +2010,Fla,60,M,0.009158212229229504,0.008482563619227144 +2010,Fla,60,F,0.004756144498817836,0.0038022813688212928 +2010,Fla,61,M,0.009730476848652385,0.007338551859099805 +2010,Fla,61,F,0.005222784396931615,0.005115089514066497 +2010,Fla,62,M,0.01136395600686338,0.00667693888032871 +2010,Fla,62,F,0.006201251274701651,0.005825242718446602 +2010,Fla,63,M,0.01103612325053936,0.00980392156862745 +2010,Fla,63,F,0.007358351729212656,0.007801418439716313 +2010,Fla,64,M,0.01293144133656357,0.01115933044017359 +2010,Fla,64,F,0.0070448196283250325,0.005668016194331984 +2010,Fla,65,M,0.01486798256857216,0.014857881136950909 +2010,Fla,65,F,0.007681199496113312,0.009885931558935359 +2010,Fla,66,M,0.014918809201623818,0.01228183581124758 +2010,Fla,66,F,0.008346977431057176,0.011045029736618521 +2010,Fla,67,M,0.01587115437238576,0.02127659574468085 +2010,Fla,67,F,0.01,0.006129597197898424 +2010,Fla,68,M,0.018298866793068483,0.02036021926389977 +2010,Fla,68,F,0.008859223300970873,0.01181102362204725 +2010,Fla,69,M,0.021101326948829286,0.018503620273531786 +2010,Fla,69,F,0.01196399824381677,0.01173512154233026 +2010,Fla,70,M,0.0226139133695856,0.01959114139693356 +2010,Fla,70,F,0.01081778483525208,0.01529051987767584 +2010,Fla,71,M,0.0253062125280465,0.0270979020979021 +2010,Fla,71,F,0.01259297925094611,0.009297520661157029 +2010,Fla,72,M,0.02541355131135475,0.02154750244857982 +2010,Fla,72,F,0.0140551973527104,0.0065717415115005475 +2010,Fla,73,M,0.02885329810946917,0.01388888888888889 +2010,Fla,73,F,0.01599297012302285,0.01974448315911731 +2010,Fla,74,M,0.03243289378227286,0.02905027932960894 +2010,Fla,74,F,0.01933534743202417,0.01439790575916231 +2010,Fla,75,M,0.034431595025092736,0.03712871287128714 +2010,Fla,75,F,0.01961339658712738,0.014193548387096782 +2010,Fla,76,M,0.04026967930029155,0.0451693851944793 +2010,Fla,76,F,0.02314079422382672,0.02292263610315186 +2010,Fla,77,M,0.046892497200447934,0.04630969609261939 +2010,Fla,77,F,0.02553553695559654,0.0352760736196319 +2010,Fla,78,M,0.0498746990319886,0.05015197568389058 +2010,Fla,78,F,0.02837857453912034,0.03461538461538462 +2010,Fla,79,M,0.057879171947613016,0.05583756345177665 +2010,Fla,79,F,0.03492087358568583,0.036243822075782535 +2010,Fla,80,M,0.0636603149316831,0.06804123711340206 +2010,Fla,80,F,0.0412607211258223,0.03950103950103951 +2010,Fla,81,M,0.07164018314031781,0.06896551724137931 +2010,Fla,81,F,0.04517737125561935,0.05040322580645161 +2010,Fla,82,M,0.07965068132199052,0.09322033898305083 +2010,Fla,82,F,0.05491440661665705,0.05035971223021583 +2010,Fla,83,M,0.09049850873455476,0.07692307692307693 +2010,Fla,83,F,0.06276299112801012,0.05735660847880299 +2010,Fla,84,M,0.1038803179055633,0.1028938906752412 +2010,Fla,84,F,0.07408415437374123,0.06489675516224189 +2010,Fla,85,M,0.1138937282229965,0.1260504201680672 +2010,Fla,85,F,0.08142616237051313,0.07419354838709677 +2010,Fla,86,M,0.1280643513789581,0.1176470588235294 +2010,Fla,86,F,0.0913788592360021,0.08223684210526316 +2010,Fla,87,M,0.1463866584311303,0.130952380952381 +2010,Fla,87,F,0.1065876558411575,0.09813084112149532 +2010,Fla,88,M,0.1593655589123867,0.1408450704225352 +2010,Fla,88,F,0.1262608695652174,0.1483516483516484 +2010,Fla,89,M,0.1770142180094787,0.1531531531531532 +2010,Fla,89,F,0.13476341989120402,0.1069182389937107 +2010,Fla,90,M,0.2056901191849289,0.2121212121212121 +2010,Fla,90,F,0.1540674444622023,0.1511627906976744 +2010,Fla,91,M,0.2046130952380952,0.1707317073170732 +2010,Fla,91,F,0.1771642991155186,0.1842105263157895 +2010,Fla,92,M,0.2392638036809816,0.07407407407407407 +2010,Fla,92,F,0.1778385772913817,0.1076923076923077 +2010,Fla,93,M,0.2380382775119617,0.2692307692307692 +2010,Fla,93,F,0.2169603524229075,0.163265306122449 +2010,Fla,94,M,0.2809706257982121,0.05555555555555555 +2010,Fla,94,F,0.2308617234468938,0.1333333333333333 +2010,Fla,95,M,0.3270223752151463,0.375 +2010,Fla,95,F,0.2530009233610342,0.2790697674418605 +2010,Fla,96,M,0.2698412698412699,0.4545454545454545 +2010,Fla,96,F,0.2786377708978328,0.2258064516129032 +2010,Fla,97,M,0.3146551724137931,0.0 +2010,Fla,97,F,0.2982456140350877,0.3076923076923077 +2010,Fla,98,M,0.3266666666666667,0.0 +2010,Fla,98,F,0.2983354673495519,0.0 +2010,Fla,99,M,0.3977272727272727,0.0 +2010,Fla,99,F,0.3436213991769547,0.3 +2010,Fla,100,M,0.4285714285714286,0.3333333333333333 +2010,Fla,100,F,0.3258064516129033,0.2 +2010,Fla,101,M,0.3947368421052632,0.0 +2010,Fla,101,F,0.4484536082474227,0.6666666666666666 +2010,Fla,102,M,0.3333333333333333,0.0 +2010,Fla,102,F,0.3893805309734513,0.0 +2010,Fla,103,M,0.2857142857142857,0.0 +2010,Fla,103,F,0.3469387755102041,1.0 +2010,Fla,104,M,0.5,1.0 +2010,Fla,104,F,0.5294117647058824,1.0 +2010,Fla,105,M,1.0,0.0 +2010,Fla,105,F,0.3333333333333333,0.0 +2010,Fla,106,M,0.0,0.0 +2010,Fla,106,F,0.4285714285714286,0.0 +2010,Fla,107,M,0.0,0.0 +2010,Fla,107,F,0.3333333333333333,0.0 +2010,Fla,108,M,0.0,0.0 +2010,Fla,108,F,0.5,0.0 +2010,Fla,109,M,0.0,0.0 +2010,Fla,109,F,0.0,0.0 +2010,Fla,110,M,0.0,0.0 +2010,Fla,110,F,0.0,0.0 +2010,Fla,111,M,0.0,0.0 +2010,Fla,111,F,0.0,0.0 +2010,Fla,112,M,0.0,0.0 +2010,Fla,112,F,0.0,0.0 +2010,Fla,113,M,0.0,0.0 +2010,Fla,113,F,0.0,0.0 +2010,Fla,114,M,0.0,0.0 +2010,Fla,114,F,0.0,0.0 +2010,Fla,115,M,0.0,0.0 +2010,Fla,115,F,0.0,0.0 +2010,Fla,116,M,0.0,0.0 +2010,Fla,116,F,0.0,0.0 +2010,Fla,117,M,0.0,0.0 +2010,Fla,117,F,0.0,0.0 +2010,Fla,118,M,0.0,0.0 +2010,Fla,118,F,0.0,0.0 +2010,Fla,119,M,0.0,0.0 +2010,Fla,119,F,0.0,0.0 +2010,Fla,120,M,0.0,0.0 +2010,Fla,120,F,0.0,0.0 +2010,Wal,0,M,0.000725990458411118,0.0008733624454148473 +2010,Wal,0,F,0.0006955963400931027,0.001876172607879925 +2010,Wal,1,M,0.0002513320599175631,0.0008873114463176574 +2010,Wal,1,F,5.329638117571817e-05,0.0 +2010,Wal,2,M,0.0001005935016597928,0.0009293680297397768 +2010,Wal,2,F,5.313496280552604e-05,0.0 +2010,Wal,3,M,0.0001504890895410083,0.0009643201542912248 +2010,Wal,3,F,0.0003631082062454612,0.0 +2010,Wal,4,M,0.0002022449185964203,0.0009560229445506693 +2010,Wal,4,F,0.0,0.0 +2010,Wal,5,M,0.0001516683518705763,0.0 +2010,Wal,5,F,5.325948018747337e-05,0.0 +2010,Wal,6,M,0.0002048550650414832,0.0 +2010,Wal,6,F,0.00010559662090813092,0.0 +2010,Wal,7,M,0.0001016518424396442,0.0 +2010,Wal,7,F,0.0001072098633074243,0.0 +2010,Wal,8,M,0.0,0.0 +2010,Wal,8,F,5.1179691898254774e-05,0.0 +2010,Wal,9,M,0.0,0.0 +2010,Wal,9,F,0.000101864113272894,0.0 +2010,Wal,10,M,9.942334460131238e-05,0.0009407337723424273 +2010,Wal,10,F,0.0001566579634464752,0.0 +2010,Wal,11,M,9.924573243350536e-05,0.0 +2010,Wal,11,F,0.0001039176971838304,0.0 +2010,Wal,12,M,9.88972951589774e-05,0.0009099181073703367 +2010,Wal,12,F,5.1535765821480104e-05,0.0 +2010,Wal,13,M,0.0001957234427753584,0.0 +2010,Wal,13,F,5.114043162524292e-05,0.0 +2010,Wal,14,M,0.0001505797319680771,0.0 +2010,Wal,14,F,5.233683990160674e-05,0.0 +2010,Wal,15,M,0.00029819591471596835,0.0 +2010,Wal,15,F,0.00015603869759700411,0.0 +2010,Wal,16,M,0.0002865740077374982,0.002626970227670753 +2010,Wal,16,F,0.00030278562777553487,0.0 +2010,Wal,17,M,0.0005470958329534056,0.0 +2010,Wal,17,F,0.0001908305901436,0.0 +2010,Wal,18,M,0.0006686279753944905,0.0007396449704142013 +2010,Wal,18,F,0.00023151363615316948,0.0 +2010,Wal,19,M,0.0004526115687516973,0.001451378809869376 +2010,Wal,19,F,0.0004239883167663824,0.0 +2010,Wal,20,M,0.0013150138303178714,0.0 +2010,Wal,20,F,0.00023739435951001807,0.0 +2010,Wal,21,M,0.0007829050382241871,0.0006361323155216285 +2010,Wal,21,F,0.0003386222910216719,0.0 +2010,Wal,22,M,0.001103223330775134,0.0006053268765133173 +2010,Wal,22,F,0.00045060832123366523,0.0004923682914820286 +2010,Wal,23,M,0.0007750811413069807,0.0 +2010,Wal,23,F,0.0003552037347135536,0.0 +2010,Wal,24,M,0.001232285890326556,0.0 +2010,Wal,24,F,0.0004257357245489864,0.00043290043290043285 +2010,Wal,25,M,0.000997480050398992,0.0014457831325301214 +2010,Wal,25,F,0.0003798361278419882,0.0 +2010,Wal,26,M,0.0016017940092904052,0.0009119927040583676 +2010,Wal,26,F,0.0002833824529585128,0.000427715996578272 +2010,Wal,27,M,0.0009049292025976793,0.0 +2010,Wal,27,F,0.0004924760601915185,0.0 +2010,Wal,28,M,0.001009993621092919,0.0008385744234800838 +2010,Wal,28,F,0.0007477833564790088,0.0003770739064856712 +2010,Wal,29,M,0.0008471435378832001,0.001176009408075265 +2010,Wal,29,F,0.0006911952360697575,0.0 +2010,Wal,30,M,0.001286725284151834,0.0 +2010,Wal,30,F,0.00027454425653415334,0.0 +2010,Wal,31,M,0.0009233108842059526,0.0007334066740007334 +2010,Wal,31,F,0.0006049274087109547,0.0003680529996319471 +2010,Wal,32,M,0.0017754344434282032,0.001124437781109445 +2010,Wal,32,F,0.0002712232167073502,0.0 +2010,Wal,33,M,0.001058929422354,0.0003795066413662239 +2010,Wal,33,F,0.0006834191988224161,0.0003858024691358025 +2010,Wal,34,M,0.001466736511262441,0.00072992700729927 +2010,Wal,34,F,0.0008336372635856823,0.0011235955056179776 +2010,Wal,35,M,0.001104584023698348,0.001024940211820977 +2010,Wal,35,F,0.001109709962168979,0.0003549875754348599 +2010,Wal,36,M,0.001731518445481218,0.0009609224855861627 +2010,Wal,36,F,0.0009144287226874578,0.0006891798759476222 +2010,Wal,37,M,0.001616926914903446,0.0006391818472355385 +2010,Wal,37,F,0.001021450459652707,0.0 +2010,Wal,38,M,0.0017414417304431509,0.0027881040892193307 +2010,Wal,38,F,0.001223879243914601,0.0 +2010,Wal,39,M,0.001895252623306985,0.003188775510204082 +2010,Wal,39,F,0.0009779723373538863,0.001009421265141319 +2010,Wal,40,M,0.0021941085850333787,0.0018963337547408352 +2010,Wal,40,F,0.001206384558277654,0.0 +2010,Wal,41,M,0.0019607843137254893,0.0009699321047526674 +2010,Wal,41,F,0.0015422722811609107,0.0 +2010,Wal,42,M,0.003124708515996642,0.001592356687898089 +2010,Wal,42,F,0.00115606936416185,0.001061946902654867 +2010,Wal,43,M,0.002801249081557678,0.0023391812865497076 +2010,Wal,43,F,0.002267059623668103,0.00065359477124183 +2010,Wal,44,M,0.0027898326100433968,0.0005815644082582148 +2010,Wal,44,F,0.001755772100781319,0.00137646249139711 +2010,Wal,45,M,0.004473310680029249,0.002440512507626602 +2010,Wal,45,F,0.002283298097251586,0.001026342798494697 +2010,Wal,46,M,0.004308639261376128,0.0036708473539308656 +2010,Wal,46,F,0.002222507159037484,0.0007077140835102619 +2010,Wal,47,M,0.004037013517191327,0.001581277672359266 +2010,Wal,47,F,0.002358284566337672,0.001165501165501166 +2010,Wal,48,M,0.0050921006021962464,0.0029220779220779213 +2010,Wal,48,F,0.0026560424966799467,0.0003846153846153846 +2010,Wal,49,M,0.00400962309542903,0.004507211538461538 +2010,Wal,49,F,0.003052503052503053,0.002706883217324053 +2010,Wal,50,M,0.005901287553648069,0.002899484536082475 +2010,Wal,50,F,0.003343207786711807,0.00206953642384106 +2010,Wal,51,M,0.006766951671162727,0.0038772213247172853 +2010,Wal,51,F,0.002555661439833666,0.002927645336679214 +2010,Wal,52,M,0.006420097697138871,0.006544502617801047 +2010,Wal,52,F,0.0048707049238398865,0.0038543897216274095 +2010,Wal,53,M,0.0075141188858045375,0.0035483870967741938 +2010,Wal,53,F,0.0040337038365005394,0.0030303030303030307 +2010,Wal,54,M,0.008605600933488914,0.005351170568561873 +2010,Wal,54,F,0.0047344214987825785,0.002642007926023778 +2010,Wal,55,M,0.008604673902415176,0.007231404958677686 +2010,Wal,55,F,0.004718493746850521,0.004117108874656907 +2010,Wal,56,M,0.0103531976024174,0.0075053609721229455 +2010,Wal,56,F,0.004514777751919944,0.005253104106972301 +2010,Wal,57,M,0.01188068756319515,0.008354522339266255 +2010,Wal,57,F,0.005547126872747961,0.005255613951266125 +2010,Wal,58,M,0.010700236034618407,0.00651840490797546 +2010,Wal,58,F,0.006370348921384103,0.003911980440097799 +2010,Wal,59,M,0.01339035690647116,0.01196911196911197 +2010,Wal,59,F,0.007288348296167584,0.004755111745126011 +2010,Wal,60,M,0.01391609112462633,0.009988014382740707 +2010,Wal,60,F,0.006903210234129858,0.0041906757464641176 +2010,Wal,61,M,0.01436430317848411,0.01341222879684418 +2010,Wal,61,F,0.008535722706908748,0.004821600771456123 +2010,Wal,62,M,0.01632484372578396,0.01342554922701384 +2010,Wal,62,F,0.008585543671159289,0.00835509138381201 +2010,Wal,63,M,0.01754104497566715,0.01426101987899741 +2010,Wal,63,F,0.008751994584401141,0.006806579693703914 +2010,Wal,64,M,0.01844589687726943,0.0143014301430143 +2010,Wal,64,F,0.009204011679573442,0.007994670219853431 +2010,Wal,65,M,0.01885402857563706,0.01331853496115427 +2010,Wal,65,F,0.01108358325726953,0.005964214711729622 +2010,Wal,66,M,0.01907968574635241,0.01719745222929936 +2010,Wal,66,F,0.01141584296255047,0.011611030478955007 +2010,Wal,67,M,0.021885677347862214,0.01560379918588874 +2010,Wal,67,F,0.01076555023923445,0.01041666666666667 +2010,Wal,68,M,0.02664640324214792,0.02347083926031295 +2010,Wal,68,F,0.01212121212121212,0.01092896174863388 +2010,Wal,69,M,0.028425189653596562,0.021656050955414008 +2010,Wal,69,F,0.013906930541758998,0.009265387160820648 +2010,Wal,70,M,0.02742906276870164,0.02159244264507422 +2010,Wal,70,F,0.014758340910680559,0.009186351706036744 +2010,Wal,71,M,0.03101048365782752,0.03330809992429978 +2010,Wal,71,F,0.015942634363687,0.021710526315789482 +2010,Wal,72,M,0.031212261960055738,0.03134328358208955 +2010,Wal,72,F,0.01671371267270836,0.012987012987012991 +2010,Wal,73,M,0.03286754575870892,0.03970223325062035 +2010,Wal,73,F,0.01889348889725254,0.01620029455081002 +2010,Wal,74,M,0.03826609976148501,0.03722504230118443 +2010,Wal,74,F,0.0216320246343341,0.01948051948051948 +2010,Wal,75,M,0.04659021093590007,0.04359430604982206 +2010,Wal,75,F,0.02465319662243667,0.02217453505007153 +2010,Wal,76,M,0.04911758452051882,0.049760765550239235 +2010,Wal,76,F,0.03123809523809524,0.02794117647058824 +2010,Wal,77,M,0.056978845540554914,0.05888125613346418 +2010,Wal,77,F,0.02784900284900285,0.03791469194312797 +2010,Wal,78,M,0.0633848834676541,0.05729729729729729 +2010,Wal,78,F,0.036099525384726015,0.028548770816812064 +2010,Wal,79,M,0.06777073056142824,0.07387580299785867 +2010,Wal,79,F,0.04117041611527717,0.03885804916732752 +2010,Wal,80,M,0.0724734934908066,0.08795180722891566 +2010,Wal,80,F,0.04456713074091855,0.04145077720207254 +2010,Wal,81,M,0.09100294985250736,0.08426966292134831 +2010,Wal,81,F,0.059769923307769264,0.058039961941008564 +2010,Wal,82,M,0.1000161838485192,0.1071953010279001 +2010,Wal,82,F,0.059341637010676164,0.07461240310077519 +2010,Wal,83,M,0.1080934274850625,0.1191626409017714 +2010,Wal,83,F,0.06770296844273807,0.06206206206206207 +2010,Wal,84,M,0.1156,0.1372549019607843 +2010,Wal,84,F,0.07445156280333916,0.07809110629067245 +2010,Wal,85,M,0.1314192343604108,0.1230769230769231 +2010,Wal,85,F,0.0851384847505119,0.07858048162230671 +2010,Wal,86,M,0.1471412556053812,0.1443298969072165 +2010,Wal,86,F,0.0939954089646007,0.09801136363636363 +2010,Wal,87,M,0.1567038162782844,0.1924528301886793 +2010,Wal,87,F,0.1109030100334448,0.1091205211726384 +2010,Wal,88,M,0.156124899919936,0.1409090909090909 +2010,Wal,88,F,0.1296928327645051,0.127789046653144 +2010,Wal,89,M,0.1805915931499741,0.225609756097561 +2010,Wal,89,F,0.14559053748478,0.1359447004608295 +2010,Wal,90,M,0.1867469879518072,0.1473684210526316 +2010,Wal,90,F,0.162739118380926,0.1730769230769231 +2010,Wal,91,M,0.2405660377358491,0.3333333333333333 +2010,Wal,91,F,0.1917148362235068,0.15 +2010,Wal,92,M,0.222707423580786,0.34375 +2010,Wal,92,F,0.1944777911164466,0.1949152542372882 +2010,Wal,93,M,0.2537688442211055,0.3333333333333333 +2010,Wal,93,F,0.2044960116026106,0.2692307692307692 +2010,Wal,94,M,0.2906574394463668,0.1428571428571429 +2010,Wal,94,F,0.2494529540481401,0.3404255319148936 +2010,Wal,95,M,0.3531746031746032,0.4166666666666667 +2010,Wal,95,F,0.2401315789473684,0.2891566265060241 +2010,Wal,96,M,0.3241758241758242,0.4 +2010,Wal,96,F,0.2661782661782662,0.4262295081967213 +2010,Wal,97,M,0.3484848484848485,0.125 +2010,Wal,97,F,0.3141831238779174,0.2222222222222222 +2010,Wal,98,M,0.4576271186440678,0.0 +2010,Wal,98,F,0.30693069306930704,0.4285714285714286 +2010,Wal,99,M,0.3888888888888889,0.5 +2010,Wal,99,F,0.3346456692913386,0.36 +2010,Wal,100,M,0.375,0.0 +2010,Wal,100,F,0.3888888888888889,0.2727272727272727 +2010,Wal,101,M,0.5,0.0 +2010,Wal,101,F,0.49,0.2 +2010,Wal,102,M,0.625,0.0 +2010,Wal,102,F,0.3833333333333334,0.6666666666666666 +2010,Wal,103,M,1.0,0.0 +2010,Wal,103,F,0.34375,0.0 +2010,Wal,104,M,0.0,0.0 +2010,Wal,104,F,0.38095238095238093,0.5 +2010,Wal,105,M,0.0,0.0 +2010,Wal,105,F,0.3333333333333333,0.0 +2010,Wal,106,M,0.0,0.0 +2010,Wal,106,F,0.3333333333333333,0.0 +2010,Wal,107,M,0.0,0.0 +2010,Wal,107,F,0.5,0.0 +2010,Wal,108,M,0.0,0.0 +2010,Wal,108,F,1.0,0.0 +2010,Wal,109,M,0.0,0.0 +2010,Wal,109,F,0.5,0.0 +2010,Wal,110,M,0.0,0.0 +2010,Wal,110,F,0.5,0.0 +2010,Wal,111,M,0.0,0.0 +2010,Wal,111,F,0.0,0.0 +2010,Wal,112,M,0.0,0.0 +2010,Wal,112,F,0.0,0.0 +2010,Wal,113,M,0.0,0.0 +2010,Wal,113,F,0.0,0.0 +2010,Wal,114,M,0.0,0.0 +2010,Wal,114,F,0.0,0.0 +2010,Wal,115,M,0.0,0.0 +2010,Wal,115,F,0.0,0.0 +2010,Wal,116,M,0.0,0.0 +2010,Wal,116,F,0.0,0.0 +2010,Wal,117,M,0.0,0.0 +2010,Wal,117,F,0.0,0.0 +2010,Wal,118,M,0.0,0.0 +2010,Wal,118,F,0.0,0.0 +2010,Wal,119,M,0.0,0.0 +2010,Wal,119,F,0.0,0.0 +2010,Wal,120,M,0.0,0.0 +2010,Wal,120,F,0.0,0.0 +2011,BruCap,0,M,0.000447227191413238,0.0003718854592785422 +2011,BruCap,0,F,0.0004719949653870358,0.0007704160246533128 +2011,BruCap,1,M,0.00015108022359873092,0.0 +2011,BruCap,1,F,0.0,0.0004199916001679967 +2011,BruCap,2,M,0.00015971889474524842,0.0 +2011,BruCap,2,F,0.0003343363423604147,0.0 +2011,BruCap,3,M,0.0,0.0 +2011,BruCap,3,F,0.0,0.0 +2011,BruCap,4,M,0.0001648261084555794,0.0 +2011,BruCap,4,F,0.00017418568193694486,0.0 +2011,BruCap,5,M,0.00017433751743375168,0.0 +2011,BruCap,5,F,0.00036010082823190496,0.0 +2011,BruCap,6,M,0.0,0.0 +2011,BruCap,6,F,0.000375234521575985,0.0 +2011,BruCap,7,M,0.0,0.0 +2011,BruCap,7,F,0.0,0.0012666244458518052 +2011,BruCap,8,M,0.0,0.0 +2011,BruCap,8,F,0.0,0.0 +2011,BruCap,9,M,0.0,0.0 +2011,BruCap,9,F,0.0,0.0007042253521126763 +2011,BruCap,10,M,0.0,0.0 +2011,BruCap,10,F,0.0,0.0 +2011,BruCap,11,M,0.0,0.0 +2011,BruCap,11,F,0.0,0.0007225433526011558 +2011,BruCap,12,M,0.00021468441391155,0.0 +2011,BruCap,12,F,0.0,0.0 +2011,BruCap,13,M,0.0,0.0007320644216691067 +2011,BruCap,13,F,0.0002255299954894001,0.0 +2011,BruCap,14,M,0.0004326195111399524,0.0 +2011,BruCap,14,F,0.00044984255510571296,0.0 +2011,BruCap,15,M,0.0004361098996947232,0.0 +2011,BruCap,15,F,0.00045892611289582384,0.0 +2011,BruCap,16,M,0.0,0.0 +2011,BruCap,16,F,0.0,0.0008045052292839902 +2011,BruCap,17,M,0.0002154708037060978,0.0 +2011,BruCap,17,F,0.00022326412145568208,0.0007692307692307692 +2011,BruCap,18,M,0.0010477787091366301,0.0 +2011,BruCap,18,F,0.00021649707728945656,0.0 +2011,BruCap,19,M,0.00020781379883624268,0.0 +2011,BruCap,19,F,0.0,0.0005470459518599561 +2011,BruCap,20,M,0.0002073398299813394,0.001013684744044602 +2011,BruCap,20,F,0.0002104377104377104,0.0 +2011,BruCap,21,M,0.0008269588587967747,0.0004899559039686428 +2011,BruCap,21,F,0.000206996481059822,0.0 +2011,BruCap,22,M,0.000202020202020202,0.0 +2011,BruCap,22,F,0.0004144218814753419,0.0 +2011,BruCap,23,M,0.0002053388090349076,0.0008090614886731393 +2011,BruCap,23,F,0.0,0.00028563267637817766 +2011,BruCap,24,M,0.00020060180541624868,0.0018011527377521622 +2011,BruCap,24,F,0.00038543071882829065,0.0 +2011,BruCap,25,M,0.0009788566953797962,0.0006277463904582549 +2011,BruCap,25,F,0.0003842459173871278,0.0002419549963706751 +2011,BruCap,26,M,0.0003823360734085261,0.0 +2011,BruCap,26,F,0.0007090941322460556,0.0 +2011,BruCap,27,M,0.0007568590350047304,0.0 +2011,BruCap,27,F,0.0008926977325477591,0.0 +2011,BruCap,28,M,0.0007346189164370982,0.0006947660954145438 +2011,BruCap,28,F,0.0008903133903133902,0.0 +2011,BruCap,29,M,0.0001820830298616169,0.00046264168401572976 +2011,BruCap,29,F,0.0006991784653032686,0.000211595429538722 +2011,BruCap,30,M,0.00070859167404783,0.0006315789473684211 +2011,BruCap,30,F,0.00017313019390581717,0.0001990049751243781 +2011,BruCap,31,M,0.0005390835579514825,0.0004273504273504274 +2011,BruCap,31,F,0.0003676470588235294,0.0 +2011,BruCap,32,M,0.0009290226681531028,0.0004276245456489203 +2011,BruCap,32,F,0.0003718854592785422,0.0004282655246252677 +2011,BruCap,33,M,0.0005574136008918619,0.0004320587599913589 +2011,BruCap,33,F,0.0005585552038726494,0.00045320643553138477 +2011,BruCap,34,M,0.0007720517274657403,0.0002123142250530786 +2011,BruCap,34,F,0.00019588638589618015,0.0002331002331002331 +2011,BruCap,35,M,0.0003888024883359254,0.0006795016987542467 +2011,BruCap,35,F,0.0004127115146512588,0.0 +2011,BruCap,36,M,0.0007792713812585232,0.001140250855188142 +2011,BruCap,36,F,0.0008331597583836701,0.001982160555004955 +2011,BruCap,37,M,0.0007607455306200076,0.0007119126720455624 +2011,BruCap,37,F,0.0004043671653861706,0.00026990553306342784 +2011,BruCap,38,M,0.002112946600076834,0.000744047619047619 +2011,BruCap,38,F,0.00101667344448963,0.0008203445447087777 +2011,BruCap,39,M,0.001157407407407408,0.001046572475143904 +2011,BruCap,39,F,0.00103327133705311,0.0005861664712778429 +2011,BruCap,40,M,0.0017058377558756641,0.001263902932254803 +2011,BruCap,40,F,0.001203610832497493,0.000304228780042592 +2011,BruCap,41,M,0.0009718172983479103,0.001866666666666667 +2011,BruCap,41,F,0.0012575979878432198,0.001237240952675534 +2011,BruCap,42,M,0.001789976133651552,0.001374003847210772 +2011,BruCap,42,F,0.0006446067898581865,0.000975609756097561 +2011,BruCap,43,M,0.002487046632124352,0.002657218777679362 +2011,BruCap,43,F,0.001532399299474606,0.001775568181818182 +2011,BruCap,44,M,0.001861812163839471,0.0018489984591679512 +2011,BruCap,44,F,0.0018895653999580105,0.001883948756593821 +2011,BruCap,45,M,0.0034034034034034037,0.002649006622516557 +2011,BruCap,45,F,0.002259190798932019,0.0019290123456790129 +2011,BruCap,46,M,0.002815768302493967,0.001653439153439154 +2011,BruCap,46,F,0.001427406199021207,0.002372479240806643 +2011,BruCap,47,M,0.002933165723863398,0.001859427296392711 +2011,BruCap,47,F,0.003154574132492114,0.0008431703204047218 +2011,BruCap,48,M,0.003444564047362756,0.002344665885111372 +2011,BruCap,48,F,0.002119093028183937,0.0009004952723998199 +2011,BruCap,49,M,0.0017785682525566925,0.002043318348998774 +2011,BruCap,49,F,0.002325581395348837,0.002810304449648712 +2011,BruCap,50,M,0.006628180457558264,0.002615518744551003 +2011,BruCap,50,F,0.002392821535393819,0.002376425855513308 +2011,BruCap,51,M,0.002417582417582418,0.001407789770061005 +2011,BruCap,51,F,0.00308641975308642,0.0019714144898965013 +2011,BruCap,52,M,0.006395614435815441,0.004878048780487805 +2011,BruCap,52,F,0.002504173622704508,0.003229278794402584 +2011,BruCap,53,M,0.009163533834586466,0.0043383947939262466 +2011,BruCap,53,F,0.002561912894961572,0.001683501683501684 +2011,BruCap,54,M,0.008678881388621022,0.006355932203389831 +2011,BruCap,54,F,0.002114611968703743,0.00297441998810232 +2011,BruCap,55,M,0.006964457252641691,0.005691519635742743 +2011,BruCap,55,F,0.006219172206733862,0.0023952095808383238 +2011,BruCap,56,M,0.008144126357354392,0.003192848020434228 +2011,BruCap,56,F,0.006578947368421052,0.001241464928615767 +2011,BruCap,57,M,0.008068459657701709,0.0056338028169014105 +2011,BruCap,57,F,0.006370826010544815,0.0027874564459930322 +2011,BruCap,58,M,0.012655086848635241,0.008275862068965517 +2011,BruCap,58,F,0.005770084332001775,0.001965923984272608 +2011,BruCap,59,M,0.009922231161169212,0.005559968228752979 +2011,BruCap,59,F,0.0061949011198475104,0.0038343558282208593 +2011,BruCap,60,M,0.01223729715349827,0.007473841554559044 +2011,BruCap,60,F,0.0075774971297359345,0.002915451895043732 +2011,BruCap,61,M,0.009988901220865706,0.006700167504187605 +2011,BruCap,61,F,0.006479481641468682,0.003292181069958848 +2011,BruCap,62,M,0.01524562394127612,0.010204081632653059 +2011,BruCap,62,F,0.007498790517658442,0.003415883859948762 +2011,BruCap,63,M,0.01347477064220184,0.006481481481481481 +2011,BruCap,63,F,0.009137769447047795,0.006381039197812215 +2011,BruCap,64,M,0.0200232153221126,0.006862745098039216 +2011,BruCap,64,F,0.01249387555120039,0.002824858757062147 +2011,BruCap,65,M,0.01677735057672143,0.005952380952380952 +2011,BruCap,65,F,0.009641873278236915,0.01167728237791932 +2011,BruCap,66,M,0.01645819618169849,0.008838383838383838 +2011,BruCap,66,F,0.008994276369582993,0.00736842105263158 +2011,BruCap,67,M,0.02075134168157424,0.01315789473684211 +2011,BruCap,67,F,0.013302486986697507,0.01893491124260355 +2011,BruCap,68,M,0.01882258710452543,0.01523545706371191 +2011,BruCap,68,F,0.0123899576133029,0.00880503144654088 +2011,BruCap,69,M,0.02304368698991839,0.01926163723916533 +2011,BruCap,69,F,0.01381112355356477,0.008426966292134831 +2011,BruCap,70,M,0.024522028262676642,0.02008608321377331 +2011,BruCap,70,F,0.013247172859450727,0.01158748551564311 +2011,BruCap,71,M,0.02525252525252525,0.02034428794992175 +2011,BruCap,71,F,0.015897755610972567,0.01036269430051814 +2011,BruCap,72,M,0.02788339670468948,0.03453947368421053 +2011,BruCap,72,F,0.01977040816326531,0.014608233731739709 +2011,BruCap,73,M,0.030139451192082767,0.04308797127468582 +2011,BruCap,73,F,0.01888667992047714,0.02222222222222222 +2011,BruCap,74,M,0.03443588581785228,0.02330097087378641 +2011,BruCap,74,F,0.02366666666666667,0.012328767123287673 +2011,BruCap,75,M,0.04168663152850982,0.033126293995859216 +2011,BruCap,75,F,0.02302204928664073,0.03148425787106447 +2011,BruCap,76,M,0.04613166746756367,0.03225806451612903 +2011,BruCap,76,F,0.030243261012491782,0.03094462540716613 +2011,BruCap,77,M,0.0531062124248497,0.0703883495145631 +2011,BruCap,77,F,0.030293159609120518,0.02616822429906542 +2011,BruCap,78,M,0.06206554121151937,0.04975124378109453 +2011,BruCap,78,F,0.03607594936708861,0.02922755741127349 +2011,BruCap,79,M,0.06203605514316012,0.051987767584097865 +2011,BruCap,79,F,0.03876478318002629,0.02777777777777778 +2011,BruCap,80,M,0.05845629965947785,0.06936416184971098 +2011,BruCap,80,F,0.04520464263897373,0.03171641791044777 +2011,BruCap,81,M,0.06881587104773712,0.09634551495016612 +2011,BruCap,81,F,0.04409814323607427,0.0427807486631016 +2011,BruCap,82,M,0.08601444517399869,0.0735930735930736 +2011,BruCap,82,F,0.04673539518900344,0.07180851063829788 +2011,BruCap,83,M,0.0858765081618169,0.04022988505747127 +2011,BruCap,83,F,0.05759539236861051,0.04643962848297214 +2011,BruCap,84,M,0.0950920245398773,0.07262569832402235 +2011,BruCap,84,F,0.07607497243660419,0.03985507246376812 +2011,BruCap,85,M,0.1139575971731449,0.09090909090909093 +2011,BruCap,85,F,0.06823438704703161,0.09745762711864407 +2011,BruCap,86,M,0.09442446043165467,0.0990990990990991 +2011,BruCap,86,F,0.08027709861450692,0.1009174311926606 +2011,BruCap,87,M,0.1270983213429257,0.1041666666666667 +2011,BruCap,87,F,0.09944037882049074,0.03664921465968586 +2011,BruCap,88,M,0.1639549436795995,0.1 +2011,BruCap,88,F,0.111218103033221,0.14 +2011,BruCap,89,M,0.1666666666666667,0.140625 +2011,BruCap,89,F,0.1291028446389497,0.05982905982905984 +2011,BruCap,90,M,0.1796296296296297,0.2181818181818182 +2011,BruCap,90,F,0.13727959697733,0.1323529411764706 +2011,BruCap,91,M,0.1818181818181818,0.1290322580645161 +2011,BruCap,91,F,0.1558823529411765,0.1604938271604938 +2011,BruCap,92,M,0.2,0.09090909090909093 +2011,BruCap,92,F,0.1688524590163935,0.1111111111111111 +2011,BruCap,93,M,0.2450331125827815,0.07142857142857142 +2011,BruCap,93,F,0.2067594433399603,0.1 +2011,BruCap,94,M,0.2135922330097087,0.4 +2011,BruCap,94,F,0.2175925925925926,0.0975609756097561 +2011,BruCap,95,M,0.2837837837837838,0.2 +2011,BruCap,95,F,0.2323232323232323,0.2916666666666667 +2011,BruCap,96,M,0.3246753246753247,0.3636363636363637 +2011,BruCap,96,F,0.2365591397849463,0.3125 +2011,BruCap,97,M,0.2553191489361702,0.25 +2011,BruCap,97,F,0.2875536480686695,0.2857142857142857 +2011,BruCap,98,M,0.3103448275862069,0.2 +2011,BruCap,98,F,0.3016759776536313,0.1428571428571429 +2011,BruCap,99,M,0.3181818181818182,0.1666666666666667 +2011,BruCap,99,F,0.3185840707964602,0.2727272727272727 +2011,BruCap,100,M,0.4615384615384616,0.0 +2011,BruCap,100,F,0.325,0.2222222222222222 +2011,BruCap,101,M,0.75,0.0 +2011,BruCap,101,F,0.4146341463414634,0.3 +2011,BruCap,102,M,1.0,0.0 +2011,BruCap,102,F,0.2580645161290323,0.0 +2011,BruCap,103,M,0.0,0.0 +2011,BruCap,103,F,0.2941176470588236,0.0 +2011,BruCap,104,M,0.5,0.0 +2011,BruCap,104,F,0.3636363636363637,0.0 +2011,BruCap,105,M,0.0,0.0 +2011,BruCap,105,F,0.3333333333333333,0.0 +2011,BruCap,106,M,0.0,0.0 +2011,BruCap,106,F,0.0,0.0 +2011,BruCap,107,M,0.0,0.0 +2011,BruCap,107,F,0.0,0.0 +2011,BruCap,108,M,0.0,0.0 +2011,BruCap,108,F,0.0,1.0 +2011,BruCap,109,M,0.0,0.0 +2011,BruCap,109,F,0.0,0.0 +2011,BruCap,110,M,0.0,0.0 +2011,BruCap,110,F,0.0,0.0 +2011,BruCap,111,M,0.0,0.0 +2011,BruCap,111,F,0.0,0.0 +2011,BruCap,112,M,0.0,0.0 +2011,BruCap,112,F,0.0,0.0 +2011,BruCap,113,M,0.0,0.0 +2011,BruCap,113,F,0.0,0.0 +2011,BruCap,114,M,0.0,0.0 +2011,BruCap,114,F,0.0,0.0 +2011,BruCap,115,M,0.0,0.0 +2011,BruCap,115,F,0.0,0.0 +2011,BruCap,116,M,0.0,0.0 +2011,BruCap,116,F,0.0,0.0 +2011,BruCap,117,M,0.0,0.0 +2011,BruCap,117,F,0.0,0.0 +2011,BruCap,118,M,0.0,0.0 +2011,BruCap,118,F,0.0,0.0 +2011,BruCap,119,M,0.0,0.0 +2011,BruCap,119,F,0.0,0.0 +2011,BruCap,120,M,0.0,0.0 +2011,BruCap,120,F,0.0,0.0 +2011,Fla,0,M,0.0006406149903907751,0.001297016861219196 +2011,Fla,0,F,0.0007637231503579953,0.00165892501658925 +2011,Fla,1,M,0.00033228612856452404,0.001396160558464224 +2011,Fla,1,F,0.00016038492381716118,0.0003604902667627974 +2011,Fla,2,M,0.0003554291807357385,0.0007140307033202428 +2011,Fla,2,F,0.000124335581735103,0.0007836990595611285 +2011,Fla,3,M,0.0001523832744118006,0.0 +2011,Fla,3,F,0.0,0.0 +2011,Fla,4,M,3.056982147224261e-05,0.0003982477100756671 +2011,Fla,4,F,6.363549587960165e-05,0.0 +2011,Fla,5,M,3.084325458022331e-05,0.0 +2011,Fla,5,F,0.0001307232262492238,0.0 +2011,Fla,6,M,6.274706657463764e-05,0.0004271678769756515 +2011,Fla,6,F,6.616601052039566e-05,0.0 +2011,Fla,7,M,0.00012997140629061608,0.0004315925766076824 +2011,Fla,7,F,6.801564359802755e-05,0.0 +2011,Fla,8,M,0.00019526800533732549,0.0008726003490401396 +2011,Fla,8,F,6.8299013079261e-05,0.0004591368227731864 +2011,Fla,9,M,0.0001608803372051868,0.0 +2011,Fla,9,F,0.000100677897845493,0.0004791566842357451 +2011,Fla,10,M,0.0001258059443308696,0.0 +2011,Fla,10,F,3.275574044351273e-05,0.0 +2011,Fla,11,M,9.459246413369069e-05,0.00046425255338904364 +2011,Fla,11,F,9.756414842759114e-05,0.0 +2011,Fla,12,M,9.186954524575104e-05,0.0 +2011,Fla,12,F,6.436456087278345e-05,0.0 +2011,Fla,13,M,6.008532115604158e-05,0.0 +2011,Fla,13,F,0.00015596730925198081,0.0 +2011,Fla,14,M,5.997541008186643e-05,0.0 +2011,Fla,14,F,6.226843924157041e-05,0.0 +2011,Fla,15,M,0.00023896290100961832,0.001029866117404737 +2011,Fla,15,F,0.0001241349346739906,0.0005449591280653951 +2011,Fla,16,M,0.0003832434185312933,0.0 +2011,Fla,16,F,0.0001860061382025607,0.000536480686695279 +2011,Fla,17,M,0.0002548492142149229,0.001024590163934426 +2011,Fla,17,F,8.792497069167643e-05,0.0 +2011,Fla,18,M,0.0006849127421166543,0.0 +2011,Fla,18,F,0.0001428285771417145,0.0 +2011,Fla,19,M,0.0006490696668109044,0.00047846889952153117 +2011,Fla,19,F,0.0003130603067991007,0.0009302325581395347 +2011,Fla,20,M,0.0006028883834370117,0.0008760402978537013 +2011,Fla,20,F,0.0002582866982350409,0.0003993610223642173 +2011,Fla,21,M,0.0009659639752258653,0.0 +2011,Fla,21,F,0.0002677376171352075,0.0 +2011,Fla,22,M,0.0004904364884747426,0.0007005253940455343 +2011,Fla,22,F,0.0003590234561991384,0.0 +2011,Fla,23,M,0.0006426922964564285,0.0009699321047526674 +2011,Fla,23,F,0.0003371647509578545,0.0005002501250625311 +2011,Fla,24,M,0.0006148620952157872,0.001189060642092747 +2011,Fla,24,F,0.0003371337501532426,0.0004721435316336166 +2011,Fla,25,M,0.0009096697898662783,0.0005376344086021505 +2011,Fla,25,F,0.00028162843821384983,0.0004317789291882556 +2011,Fla,26,M,0.0007145834573929614,0.0007380073800738008 +2011,Fla,26,F,0.00021498771498771496,0.0 +2011,Fla,27,M,0.0009008747202929297,0.0004772130756382725 +2011,Fla,27,F,0.000178295495067158,0.0 +2011,Fla,28,M,0.0009356924123851652,0.0002269632319564231 +2011,Fla,28,F,0.00026364355391510685,0.0 +2011,Fla,29,M,0.0007127974558613883,0.0006950880444856349 +2011,Fla,29,F,0.0004855062116235898,0.0006430868167202572 +2011,Fla,30,M,0.0008641355856609242,0.0008563476771569258 +2011,Fla,30,F,0.00028058361391694733,0.0 +2011,Fla,31,M,0.0006030701754385965,0.0006580390436499232 +2011,Fla,31,F,0.0003673354054817745,0.0 +2011,Fla,32,M,0.000839442610106889,0.0002179598953792502 +2011,Fla,32,F,0.000536981036090778,0.0008845643520566123 +2011,Fla,33,M,0.0006565051093223727,0.0008892841262783459 +2011,Fla,33,F,0.0004013646397752358,0.0002281542322610085 +2011,Fla,34,M,0.001041335223163924,0.001070663811563169 +2011,Fla,34,F,0.0005294740557712672,0.0004739336492890995 +2011,Fla,35,M,0.0008283288465520813,0.0004481290611696169 +2011,Fla,35,F,0.0004212173180491621,0.0 +2011,Fla,36,M,0.001107482606843675,0.0008892841262783459 +2011,Fla,36,F,0.0005173008391769169,0.0 +2011,Fla,37,M,0.001203896246032615,0.0009205983889528193 +2011,Fla,37,F,0.0005581914596706671,0.001 +2011,Fla,38,M,0.001151621430627896,0.0011150758251561106 +2011,Fla,38,F,0.0005016104334970167,0.000731528895391368 +2011,Fla,39,M,0.001153257953719257,0.001589825119236884 +2011,Fla,39,F,0.0004523977078516135,0.00025746652935118445 +2011,Fla,40,M,0.001631678924553115,0.0002198285337436799 +2011,Fla,40,F,0.0006659924520855433,0.001986590514030296 +2011,Fla,41,M,0.001337581166857171,0.001842044669583237 +2011,Fla,41,F,0.0007162439181012128,0.0 +2011,Fla,42,M,0.0017591633130105786,0.0009126169290440338 +2011,Fla,42,F,0.0006362412822708919,0.0018676627534685167 +2011,Fla,43,M,0.001421116391762185,0.0009905894006934127 +2011,Fla,43,F,0.0010131467856712099,0.0002910360884749709 +2011,Fla,44,M,0.001719301420685911,0.001701507049100632 +2011,Fla,44,F,0.0013846260355848893,0.0002925687536571096 +2011,Fla,45,M,0.00201696884660075,0.0004955401387512386 +2011,Fla,45,F,0.0013024342046169053,0.00182370820668693 +2011,Fla,46,M,0.002220718243729115,0.0012794268167860801 +2011,Fla,46,F,0.001287691812426226,0.0006367398917542183 +2011,Fla,47,M,0.002342319322005026,0.00137211855104281 +2011,Fla,47,F,0.001737581720640299,0.001040582726326743 +2011,Fla,48,M,0.002416449114328249,0.001716738197424893 +2011,Fla,48,F,0.002163259900225156,0.001075654356400143 +2011,Fla,49,M,0.0029756044196477412,0.002749770852428964 +2011,Fla,49,F,0.002240477968633309,0.0019305019305019308 +2011,Fla,50,M,0.003122421214621853,0.00185356811862836 +2011,Fla,50,F,0.002523261315249961,0.001172791243158718 +2011,Fla,51,M,0.003489784649364992,0.002043596730245232 +2011,Fla,51,F,0.002432167083184577,0.002508361204013378 +2011,Fla,52,M,0.004109929318248539,0.002024291497975709 +2011,Fla,52,F,0.0030288428443587807,0.003258845437616388 +2011,Fla,53,M,0.004761576150714236,0.0036886757654002217 +2011,Fla,53,F,0.002550244495917269,0.0023889154323936943 +2011,Fla,54,M,0.005417735956658112,0.005470887065259868 +2011,Fla,54,F,0.003490525715913948,0.0005002501250625311 +2011,Fla,55,M,0.005159883720930233,0.006732673267326733 +2011,Fla,55,F,0.0037103963377906283,0.001567398119122257 +2011,Fla,56,M,0.006997171356260235,0.0058260507698709935 +2011,Fla,56,F,0.004365404171937397,0.0047669491525423715 +2011,Fla,57,M,0.006643249847281612,0.0035413899955732634 +2011,Fla,57,F,0.004304678437943034,0.001701644923425979 +2011,Fla,58,M,0.006982415607752535,0.009350163627863487 +2011,Fla,58,F,0.004864724245577524,0.005257009345794392 +2011,Fla,59,M,0.009193910386414643,0.008079847908745247 +2011,Fla,59,F,0.00488122356003905,0.006301197227473221 +2011,Fla,60,M,0.009019943177116376,0.006937561942517344 +2011,Fla,60,F,0.005826458656647336,0.007100591715976331 +2011,Fla,61,M,0.010285050734054021,0.011310084825636193 +2011,Fla,61,F,0.005799022450501201,0.0024691358024691358 +2011,Fla,62,M,0.0102894428643132,0.01090188305252725 +2011,Fla,62,F,0.0055459934978007285,0.003846153846153847 +2011,Fla,63,M,0.010578399590513559,0.009268795056642637 +2011,Fla,63,F,0.0068487453209482895,0.0071151358344113845 +2011,Fla,64,M,0.01293838200363281,0.01571503404924044 +2011,Fla,64,F,0.005869124019527179,0.0035385704175513095 +2011,Fla,65,M,0.01531359439668895,0.012795905310300709 +2011,Fla,65,F,0.007788399865611924,0.006504065040650407 +2011,Fla,66,M,0.013980102737499191,0.01383399209486166 +2011,Fla,66,F,0.007891560672175285,0.008390541571319604 +2011,Fla,67,M,0.01647559552412988,0.02188328912466844 +2011,Fla,67,F,0.008444962143273152,0.008658008658008658 +2011,Fla,68,M,0.017577970002380768,0.01145912910618793 +2011,Fla,68,F,0.008303854030906721,0.009623797025371828 +2011,Fla,69,M,0.01875785316819243,0.01468189233278956 +2011,Fla,69,F,0.01056151368103413,0.014 +2011,Fla,70,M,0.0216986210609135,0.02640264026402641 +2011,Fla,70,F,0.01106505810080675,0.010924369747899159 +2011,Fla,71,M,0.02524942440521873,0.02101576182136603 +2011,Fla,71,F,0.01280722287242936,0.01857585139318886 +2011,Fla,72,M,0.024522749566135968,0.02545454545454546 +2011,Fla,72,F,0.014437689969604869,0.01149425287356322 +2011,Fla,73,M,0.02811085523703645,0.029411764705882363 +2011,Fla,73,F,0.01435439798000761,0.01564245810055866 +2011,Fla,74,M,0.0314518871132268,0.02854006586169045 +2011,Fla,74,F,0.015423613838409081,0.01796407185628743 +2011,Fla,75,M,0.03376978353833268,0.02520045819014891 +2011,Fla,75,F,0.01865604057236008,0.0171957671957672 +2011,Fla,76,M,0.03893933233952207,0.031331592689295036 +2011,Fla,76,F,0.02181608032940837,0.028497409326424868 +2011,Fla,77,M,0.04402903639037814,0.0398936170212766 +2011,Fla,77,F,0.02372067245520045,0.03167420814479638 +2011,Fla,78,M,0.0523765235694356,0.03963414634146342 +2011,Fla,78,F,0.02725817017250164,0.04501607717041802 +2011,Fla,79,M,0.052873920016555435,0.05203252032520325 +2011,Fla,79,F,0.03380144916710242,0.0337972166998012 +2011,Fla,80,M,0.06283280085197017,0.062043795620437964 +2011,Fla,80,F,0.04183872224386443,0.03496503496503497 +2011,Fla,81,M,0.07122283320240902,0.05726872246696035 +2011,Fla,81,F,0.043580171889921,0.04867256637168142 +2011,Fla,82,M,0.08100072516316173,0.07304785894206549 +2011,Fla,82,F,0.05069726225455902,0.053078556263269634 +2011,Fla,83,M,0.08682855040470934,0.075 +2011,Fla,83,F,0.05975386493083808,0.06666666666666668 +2011,Fla,84,M,0.09476940382452194,0.1286764705882353 +2011,Fla,84,F,0.06668470906630583,0.07008086253369272 +2011,Fla,85,M,0.1166771029012732,0.1345454545454546 +2011,Fla,85,F,0.07924107142857142,0.09032258064516127 +2011,Fla,86,M,0.1224214145383104,0.1619047619047619 +2011,Fla,86,F,0.08430175300374236,0.1197183098591549 +2011,Fla,87,M,0.1349926793557833,0.1942857142857143 +2011,Fla,87,F,0.1033563814462691,0.1148148148148148 +2011,Fla,88,M,0.1454150841020076,0.1376811594202899 +2011,Fla,88,F,0.1198966408268734,0.1036269430051813 +2011,Fla,89,M,0.1623566449291658,0.1967213114754098 +2011,Fla,89,F,0.1313272220007971,0.1038961038961039 +2011,Fla,90,M,0.1949812518027113,0.2065217391304348 +2011,Fla,90,F,0.1460087771320128,0.15 +2011,Fla,91,M,0.2105773896166909,0.2941176470588236 +2011,Fla,91,F,0.1640802422407267,0.1388888888888889 +2011,Fla,92,M,0.2199440820130475,0.2121212121212121 +2011,Fla,92,F,0.1845102505694761,0.1451612903225807 +2011,Fla,93,M,0.2695417789757412,0.36 +2011,Fla,93,F,0.20875,0.06779661016949153 +2011,Fla,94,M,0.2728706624605679,0.4117647058823529 +2011,Fla,94,F,0.2018779342723005,0.2195121951219512 +2011,Fla,95,M,0.2864768683274022,0.2352941176470588 +2011,Fla,95,F,0.2398331595411888,0.2631578947368421 +2011,Fla,96,M,0.2710997442455243,0.4 +2011,Fla,96,F,0.2667079207920792,0.21875 +2011,Fla,97,M,0.3357664233576642,0.3333333333333333 +2011,Fla,97,F,0.2731958762886598,0.1818181818181818 +2011,Fla,98,M,0.3207547169811321,0.0 +2011,Fla,98,F,0.2969924812030076,0.1666666666666667 +2011,Fla,99,M,0.2772277227722773,0.5 +2011,Fla,99,F,0.3345521023765997,0.1666666666666667 +2011,Fla,100,M,0.4150943396226416,1.0 +2011,Fla,100,F,0.3793103448275862,0.1428571428571429 +2011,Fla,101,M,0.3571428571428572,0.0 +2011,Fla,101,F,0.2701421800947868,0.25 +2011,Fla,102,M,0.4782608695652174,0.0 +2011,Fla,102,F,0.3518518518518519,1.0 +2011,Fla,103,M,0.7,0.0 +2011,Fla,103,F,0.5,0.0 +2011,Fla,104,M,1.0,0.0 +2011,Fla,104,F,0.28125,0.0 +2011,Fla,105,M,0.5,0.0 +2011,Fla,105,F,0.4583333333333333,0.0 +2011,Fla,106,M,0.0,0.0 +2011,Fla,106,F,0.6666666666666666,0.0 +2011,Fla,107,M,0.0,0.0 +2011,Fla,107,F,0.5,0.0 +2011,Fla,108,M,0.0,0.0 +2011,Fla,108,F,0.0,0.0 +2011,Fla,109,M,0.0,0.0 +2011,Fla,109,F,1.0,0.0 +2011,Fla,110,M,0.0,0.0 +2011,Fla,110,F,0.0,0.0 +2011,Fla,111,M,0.0,0.0 +2011,Fla,111,F,0.0,0.0 +2011,Fla,112,M,0.0,0.0 +2011,Fla,112,F,0.0,0.0 +2011,Fla,113,M,0.0,0.0 +2011,Fla,113,F,0.0,0.0 +2011,Fla,114,M,0.0,0.0 +2011,Fla,114,F,0.0,0.0 +2011,Fla,115,M,0.0,0.0 +2011,Fla,115,F,0.0,0.0 +2011,Fla,116,M,0.0,0.0 +2011,Fla,116,F,0.0,0.0 +2011,Fla,117,M,0.0,0.0 +2011,Fla,117,F,0.0,0.0 +2011,Fla,118,M,0.0,0.0 +2011,Fla,118,F,0.0,0.0 +2011,Fla,119,M,0.0,0.0 +2011,Fla,119,F,0.0,0.0 +2011,Fla,120,M,0.0,0.0 +2011,Fla,120,F,0.0,0.0 +2011,Wal,0,M,0.0004597466285247242,0.001582278481012658 +2011,Wal,0,F,0.0004298071240530812,0.001597444089456869 +2011,Wal,1,M,0.00025511505689065764,0.0 +2011,Wal,1,F,0.00026297796244674704,0.001716738197424893 +2011,Wal,2,M,0.0003476188111436658,0.0 +2011,Wal,2,F,0.00026350461133069827,0.0 +2011,Wal,3,M,0.0002984629159826892,0.0 +2011,Wal,3,F,5.260112566408921e-05,0.0 +2011,Wal,4,M,9.933939303630854e-05,0.0 +2011,Wal,4,F,0.0001028859509234014,0.0 +2011,Wal,5,M,0.0001504438092372499,0.0 +2011,Wal,5,F,0.0001567725752508361,0.0 +2011,Wal,6,M,0.00020083345885424508,0.0 +2011,Wal,6,F,0.00015842002429107042,0.0 +2011,Wal,7,M,0.0001018018935152194,0.0 +2011,Wal,7,F,5.251825009190694e-05,0.0 +2011,Wal,8,M,0.00010117361392148928,0.0008576329331046312 +2011,Wal,8,F,0.0001596678907871627,0.0 +2011,Wal,9,M,4.8952418249461515e-05,0.0 +2011,Wal,9,F,0.00010177081213108079,0.0 +2011,Wal,10,M,0.00033666794921123513,0.0 +2011,Wal,10,F,0.0,0.0 +2011,Wal,11,M,0.0001483019427554501,0.0008695652173913044 +2011,Wal,11,F,0.0,0.0 +2011,Wal,12,M,0.00014800197335964482,0.0 +2011,Wal,12,F,0.00010326311441553079,0.0 +2011,Wal,13,M,0.0001967826044177695,0.0 +2011,Wal,13,F,0.0002053809817210926,0.0 +2011,Wal,14,M,0.00024392623670602007,0.0 +2011,Wal,14,F,0.0,0.0 +2011,Wal,15,M,0.0002497502497502498,0.0 +2011,Wal,15,F,0.0003131033762980744,0.0 +2011,Wal,16,M,0.0005440158259149356,0.0 +2011,Wal,16,F,0.0002590807813876367,0.0008628127696289905 +2011,Wal,17,M,0.0006664445184938353,0.0008116883116883117 +2011,Wal,17,F,0.0003017046311660884,0.0007668711656441718 +2011,Wal,18,M,0.0004540707442219498,0.0 +2011,Wal,18,F,0.0002846840007591574,0.0 +2011,Wal,19,M,0.0009783430426468626,0.0007215007215007215 +2011,Wal,19,F,0.00032344515294335086,0.0 +2011,Wal,20,M,0.0006333408731056322,0.0006583278472679394 +2011,Wal,20,F,0.0002822201317027281,0.0005733944954128443 +2011,Wal,21,M,0.001089423513390831,0.000643915003219575 +2011,Wal,21,F,0.0002843197649623277,0.0 +2011,Wal,22,M,0.0009682327447092996,0.001166180758017493 +2011,Wal,22,F,9.693209906460523e-05,0.0 +2011,Wal,23,M,0.001156793753313732,0.0 +2011,Wal,23,F,0.00030164395957970935,0.00043994720633523996 +2011,Wal,24,M,0.0007793472966390648,0.00246791707798618 +2011,Wal,24,F,0.0005120589891955554,0.0 +2011,Wal,25,M,0.0008269588587967747,0.0004923682914820286 +2011,Wal,25,F,0.0003733731598037123,0.0 +2011,Wal,26,M,0.0011064278187565859,0.0008904719501335707 +2011,Wal,26,F,0.00032559149120902985,0.0 +2011,Wal,27,M,0.0013869625520110964,0.0004219409282700422 +2011,Wal,27,F,0.0003952122854561879,0.0004006410256410257 +2011,Wal,28,M,0.0018030439624542609,0.001596169193934557 +2011,Wal,28,F,0.00027191646726125744,0.0003491620111731844 +2011,Wal,29,M,0.0013712356943199199,0.000782472613458529 +2011,Wal,29,F,0.0006347862886161659,0.0003624501631025734 +2011,Wal,30,M,0.001365976673321425,0.00036656891495601184 +2011,Wal,30,F,0.0004750092362907057,0.001022146507666099 +2011,Wal,31,M,0.001063264221158958,0.0 +2011,Wal,31,F,0.0005979560774081323,0.0003568879371877232 +2011,Wal,32,M,0.001768488745980708,0.0003498950314905528 +2011,Wal,32,F,0.000434593654932638,0.001061571125265393 +2011,Wal,33,M,0.001599147121535181,0.0007069635913750442 +2011,Wal,33,F,0.00064246707356248,0.00036010082823190496 +2011,Wal,34,M,0.001099534007016074,0.001477104874446086 +2011,Wal,34,F,0.0007291666666666668,0.0003680529996319471 +2011,Wal,35,M,0.001658031088082902,0.001060820367751061 +2011,Wal,35,F,0.0006703449698344763,0.0010737294201861134 +2011,Wal,36,M,0.001344019114938524,0.001990049751243781 +2011,Wal,36,F,0.0006504553187231063,0.0003494060097833683 +2011,Wal,37,M,0.001524971406786123,0.0006188118811881187 +2011,Wal,37,F,0.0008115720628252256,0.00101763907734057 +2011,Wal,38,M,0.002027276078142278,0.0009293680297397768 +2011,Wal,38,F,0.000876222099243682,0.000980071871937275 +2011,Wal,39,M,0.001682353476106034,0.0021173623714458556 +2011,Wal,39,F,0.001215997117636462,0.0 +2011,Wal,40,M,0.001747528167394804,0.0024585125998770733 +2011,Wal,40,F,0.0012041496850685438,0.0006589785831960461 +2011,Wal,41,M,0.002044229697082327,0.001242621932277105 +2011,Wal,41,F,0.0008769500600018463,0.0010377032168799722 +2011,Wal,42,M,0.002278336814125688,0.0028717294192724947 +2011,Wal,42,F,0.001720130172013017,0.001009081735620585 +2011,Wal,43,M,0.0032995631564271787,0.001868576767362193 +2011,Wal,43,F,0.001566387174053257,0.001384083044982699 +2011,Wal,44,M,0.00348080974626729,0.0014459224985540779 +2011,Wal,44,F,0.001446393057313325,0.001982815598149372 +2011,Wal,45,M,0.0036223881256350217,0.0040114613180515755 +2011,Wal,45,F,0.001530121535367667,0.00103555402140145 +2011,Wal,46,M,0.0036499484713156992,0.0018270401948842871 +2011,Wal,46,F,0.002317741255794353,0.001364721937905152 +2011,Wal,47,M,0.003649474563601988,0.0021328458257160268 +2011,Wal,47,F,0.002515347885402456,0.001781261132882081 +2011,Wal,48,M,0.004162895927601811,0.0034428794992175282 +2011,Wal,48,F,0.0028347143480157,0.002738654147104852 +2011,Wal,49,M,0.0046084991359064105,0.004569190600522193 +2011,Wal,49,F,0.002652633380396184,0.002309468822170901 +2011,Wal,50,M,0.0061840993015082075,0.0036210018105009047 +2011,Wal,50,F,0.0026577204600906237,0.002324680356450988 +2011,Wal,51,M,0.004698407016287811,0.004231770833333333 +2011,Wal,51,F,0.0037662392619863742,0.0025 +2011,Wal,52,M,0.007420980302336235,0.0035959463877084023 +2011,Wal,52,F,0.00419659081076404,0.002522068095838588 +2011,Wal,53,M,0.008003722661703117,0.005940594059405941 +2011,Wal,53,F,0.003721095065119164,0.004317789291882556 +2011,Wal,54,M,0.0076420263385561845,0.007194244604316547 +2011,Wal,54,F,0.005342072185311546,0.003046127067014796 +2011,Wal,55,M,0.008486976880304361,0.0064189189189189175 +2011,Wal,55,F,0.004823513501329847,0.003157419936851602 +2011,Wal,56,M,0.01068313241203568,0.007069635913750442 +2011,Wal,56,F,0.005091509563781478,0.001831501831501832 +2011,Wal,57,M,0.01071624383192942,0.009836065573770493 +2011,Wal,57,F,0.005126293223972411,0.0024142926122646072 +2011,Wal,58,M,0.01201629327902241,0.008139104698483167 +2011,Wal,58,F,0.00564891294028292,0.003389830508474576 +2011,Wal,59,M,0.012465666596239171,0.010963194988253721 +2011,Wal,59,F,0.006784589290041192,0.0034465780403742 +2011,Wal,60,M,0.014783146183166791,0.009932459276916964 +2011,Wal,60,F,0.007231254549866537,0.0052656773575873615 +2011,Wal,61,M,0.01496194348868731,0.01344743276283619 +2011,Wal,61,F,0.007218992248062016,0.0053390282968499726 +2011,Wal,62,M,0.01678163286317307,0.01499797324685854 +2011,Wal,62,F,0.008630910039360744,0.00490677134445535 +2011,Wal,63,M,0.014662756598240468,0.016352201257861642 +2011,Wal,63,F,0.008445130778882348,0.004828326180257511 +2011,Wal,64,M,0.01648679429470145,0.01248884924174844 +2011,Wal,64,F,0.009109952745164905,0.007523148148148149 +2011,Wal,65,M,0.02012977436956201,0.01734104046242775 +2011,Wal,65,F,0.009594473583216068,0.006793478260869565 +2011,Wal,66,M,0.02103450857100082,0.01550832854681218 +2011,Wal,66,F,0.01038858570583207,0.009427609427609429 +2011,Wal,67,M,0.0243126376764298,0.01946787800129786 +2011,Wal,67,F,0.013135712278729979,0.014847809948032668 +2011,Wal,68,M,0.02572559366754618,0.01406469760900141 +2011,Wal,68,F,0.01183003380009657,0.009870918754745635 +2011,Wal,69,M,0.02130755638706995,0.0249266862170088 +2011,Wal,69,F,0.015424386040499791,0.01682692307692308 +2011,Wal,70,M,0.026740476637267783,0.0291583830351226 +2011,Wal,70,F,0.013689095127610207,0.015312916111850868 +2011,Wal,71,M,0.0291604263941503,0.0252808988764045 +2011,Wal,71,F,0.0176283185840708,0.010645375914836993 +2011,Wal,72,M,0.03364469030561349,0.02715654952076677 +2011,Wal,72,F,0.018211336203854032,0.02113156100886162 +2011,Wal,73,M,0.036165327210103335,0.04012588512981904 +2011,Wal,73,F,0.01892340168878166,0.02210759027266028 +2011,Wal,74,M,0.03944833181218943,0.03116883116883117 +2011,Wal,74,F,0.02006586505322815,0.02103681442524418 +2011,Wal,75,M,0.04285099052540913,0.04946043165467626 +2011,Wal,75,F,0.022503737508852,0.020756115641215718 +2011,Wal,76,M,0.04540100653174858,0.048204158790170135 +2011,Wal,76,F,0.025652912996445683,0.02490842490842491 +2011,Wal,77,M,0.05013398838767307,0.04012345679012346 +2011,Wal,77,F,0.03250628140703518,0.01820940819423369 +2011,Wal,78,M,0.05723602833689419,0.055789473684210535 +2011,Wal,78,F,0.03419491835688658,0.04122011541632317 +2011,Wal,79,M,0.06730880816989672,0.06148491879350348 +2011,Wal,79,F,0.04084675014907573,0.03165584415584416 +2011,Wal,80,M,0.06927332159919537,0.06198830409356725 +2011,Wal,80,F,0.046255169244907336,0.04108463434675432 +2011,Wal,81,M,0.07368877329865628,0.07989347536617843 +2011,Wal,81,F,0.048459993304318716,0.04774774774774775 +2011,Wal,82,M,0.09585492227979274,0.08166409861325115 +2011,Wal,82,F,0.06295378076854967,0.059063136456211814 +2011,Wal,83,M,0.101506456241033,0.08542713567839195 +2011,Wal,83,F,0.06795841209829867,0.05416666666666667 +2011,Wal,84,M,0.1173365814047909,0.09461966604823747 +2011,Wal,84,F,0.07808109193095142,0.08858057630736392 +2011,Wal,85,M,0.1169683257918552,0.1435185185185185 +2011,Wal,85,F,0.08962264150943396,0.08508158508158509 +2011,Wal,86,M,0.1415119720204466,0.1360201511335013 +2011,Wal,86,F,0.09802538787023976,0.0963855421686747 +2011,Wal,87,M,0.14430960970810094,0.1842900302114804 +2011,Wal,87,F,0.1158861096327834,0.1217257318952234 +2011,Wal,88,M,0.1682018422106528,0.1880733944954129 +2011,Wal,88,F,0.1247179178576802,0.1123188405797101 +2011,Wal,89,M,0.190814393939394,0.1587301587301587 +2011,Wal,89,F,0.1445558009172754,0.1583710407239819 +2011,Wal,90,M,0.1925269157694744,0.2283464566929134 +2011,Wal,90,F,0.1560787497462959,0.193029490616622 +2011,Wal,91,M,0.1947368421052632,0.2658227848101266 +2011,Wal,91,F,0.1740569159497022,0.1889400921658986 +2011,Wal,92,M,0.234927234927235,0.2666666666666667 +2011,Wal,92,F,0.1891731112433076,0.1983471074380165 +2011,Wal,93,M,0.2395543175487465,0.4 +2011,Wal,93,F,0.2143916913946588,0.1855670103092784 +2011,Wal,94,M,0.2779661016949153,0.3333333333333333 +2011,Wal,94,F,0.2330009066183137,0.225 +2011,Wal,95,M,0.3349514563106797,0.6111111111111112 +2011,Wal,95,F,0.2766990291262136,0.3428571428571429 +2011,Wal,96,M,0.2576687116564418,0.2 +2011,Wal,96,F,0.2740021574973031,0.1785714285714286 +2011,Wal,97,M,0.2845528455284553,0.5 +2011,Wal,97,F,0.2809917355371901,0.3611111111111111 +2011,Wal,98,M,0.38095238095238093,0.0 +2011,Wal,98,F,0.2898172323759791,0.3793103448275862 +2011,Wal,99,M,0.40625,0.0 +2011,Wal,99,F,0.2759856630824373,0.2777777777777778 +2011,Wal,100,M,0.3636363636363637,0.0 +2011,Wal,100,F,0.3136094674556213,0.25 +2011,Wal,101,M,0.8,0.5 +2011,Wal,101,F,0.4545454545454545,0.25 +2011,Wal,102,M,0.75,0.0 +2011,Wal,102,F,0.3846153846153847,1.0 +2011,Wal,103,M,1.0,0.0 +2011,Wal,103,F,0.368421052631579,0.5 +2011,Wal,104,M,0.0,0.0 +2011,Wal,104,F,0.6666666666666666,1.0 +2011,Wal,105,M,1.0,1.0 +2011,Wal,105,F,0.6153846153846154,0.0 +2011,Wal,106,M,0.0,0.0 +2011,Wal,106,F,0.5,0.0 +2011,Wal,107,M,0.0,0.0 +2011,Wal,107,F,0.0,0.0 +2011,Wal,108,M,0.0,0.0 +2011,Wal,108,F,1.0,0.0 +2011,Wal,109,M,0.0,0.0 +2011,Wal,109,F,0.0,0.0 +2011,Wal,110,M,0.0,0.0 +2011,Wal,110,F,0.0,0.0 +2011,Wal,111,M,0.0,0.0 +2011,Wal,111,F,1.0,0.0 +2011,Wal,112,M,0.0,0.0 +2011,Wal,112,F,0.0,0.0 +2011,Wal,113,M,0.0,0.0 +2011,Wal,113,F,0.0,0.0 +2011,Wal,114,M,0.0,0.0 +2011,Wal,114,F,0.0,0.0 +2011,Wal,115,M,0.0,0.0 +2011,Wal,115,F,0.0,0.0 +2011,Wal,116,M,0.0,0.0 +2011,Wal,116,F,0.0,0.0 +2011,Wal,117,M,0.0,0.0 +2011,Wal,117,F,0.0,0.0 +2011,Wal,118,M,0.0,0.0 +2011,Wal,118,F,0.0,0.0 +2011,Wal,119,M,0.0,0.0 +2011,Wal,119,F,0.0,0.0 +2011,Wal,120,M,0.0,0.0 +2011,Wal,120,F,0.0,0.0 +2012,BruCap,0,M,0.0006211180124223603,0.0014194464158978 +2012,BruCap,0,F,0.0006545573555882834,0.00037453183520599247 +2012,BruCap,1,M,0.00045427013930950935,0.001428061406640486 +2012,BruCap,1,F,0.00016116035455278,0.0003713330857779428 +2012,BruCap,2,M,0.00031138097462245066,0.0 +2012,BruCap,2,F,0.0,0.00040453074433656965 +2012,BruCap,3,M,0.0,0.001269572577232332 +2012,BruCap,3,F,0.0,0.0 +2012,BruCap,4,M,0.0003339455668725998,0.0 +2012,BruCap,4,F,0.0,0.0 +2012,BruCap,5,M,0.0003360779700890607,0.00048262548262548253 +2012,BruCap,5,F,0.0,0.0 +2012,BruCap,6,M,0.000532103582830791,0.0005162622612287042 +2012,BruCap,6,F,0.0005518763796909492,0.0 +2012,BruCap,7,M,0.0,0.0 +2012,BruCap,7,F,0.0,0.0 +2012,BruCap,8,M,0.0,0.0 +2012,BruCap,8,F,0.00020181634712411708,0.0 +2012,BruCap,9,M,0.0,0.0006199628022318662 +2012,BruCap,9,F,0.0,0.0006381620931716656 +2012,BruCap,10,M,0.0,0.0006353240152477764 +2012,BruCap,10,F,0.0,0.0 +2012,BruCap,11,M,0.0002028809089064719,0.0 +2012,BruCap,11,F,0.00021598272138228941,0.0 +2012,BruCap,12,M,0.0,0.0 +2012,BruCap,12,F,0.0,0.0 +2012,BruCap,13,M,0.0,0.0 +2012,BruCap,13,F,0.00022461814914645107,0.0 +2012,BruCap,14,M,0.00021052631578947367,0.0 +2012,BruCap,14,F,0.0002254283137962128,0.0 +2012,BruCap,15,M,0.0,0.0 +2012,BruCap,15,F,0.0,0.0 +2012,BruCap,16,M,0.00021910604732690615,0.0 +2012,BruCap,16,F,0.0006898137502874223,0.0 +2012,BruCap,17,M,0.0008453085376162299,0.0006752194463200541 +2012,BruCap,17,F,0.00023299161230195707,0.0 +2012,BruCap,18,M,0.0004299226139294927,0.0 +2012,BruCap,18,F,0.00022158209616662968,0.0 +2012,BruCap,19,M,0.00020777062123415746,0.0006027727546714887 +2012,BruCap,19,F,0.0006444683136412459,0.0005099439061703213 +2012,BruCap,20,M,0.00041511000415110015,0.0005063291139240507 +2012,BruCap,20,F,0.0006280092108017584,0.0 +2012,BruCap,21,M,0.0006156371844859427,0.00045766590389016015 +2012,BruCap,21,F,0.00041433602651750565,0.0003633720930232558 +2012,BruCap,22,M,0.0006137479541734861,0.0 +2012,BruCap,22,F,0.0002030869212022746,0.00032123353678124 +2012,BruCap,23,M,0.0001987281399046105,0.00040080160320641277 +2012,BruCap,23,F,0.0,0.0 +2012,BruCap,24,M,0.0009964129135113591,0.0006927606511950121 +2012,BruCap,24,F,0.0,0.0002469135802469136 +2012,BruCap,25,M,0.0003852080123266564,0.0006216972334473111 +2012,BruCap,25,F,0.0001839249586168843,0.0002361275088547816 +2012,BruCap,26,M,0.0,0.0002804262478968032 +2012,BruCap,26,F,0.0,0.0 +2012,BruCap,27,M,0.001129943502824859,0.0 +2012,BruCap,27,F,0.0,0.0 +2012,BruCap,28,M,0.0007614696363982486,0.0 +2012,BruCap,28,F,0.0007220216606498197,0.0 +2012,BruCap,29,M,0.0005542213190467394,0.0004318721658389117 +2012,BruCap,29,F,0.000178826895565093,0.0 +2012,BruCap,30,M,0.0007309941520467836,0.000437636761487965 +2012,BruCap,30,F,0.0007103534008169063,0.0002047082906857728 +2012,BruCap,31,M,0.001442741208295762,0.0006022886970487852 +2012,BruCap,31,F,0.0005293806246691371,0.0001957330201605011 +2012,BruCap,32,M,0.000731528895391368,0.00102124183006536 +2012,BruCap,32,F,0.0005605381165919282,0.0 +2012,BruCap,33,M,0.000751597143930853,0.00041254125412541276 +2012,BruCap,33,F,0.0,0.0006278777731268312 +2012,BruCap,34,M,0.0005645464809936018,0.001261564339781329 +2012,BruCap,34,F,0.0003789314134141722,0.0006669630947087594 +2012,BruCap,35,M,0.0005871990604815032,0.0004161464835622138 +2012,BruCap,35,F,0.0003996003996003996,0.0006863417982155112 +2012,BruCap,36,M,0.001760219049481714,0.0006596306068601582 +2012,BruCap,36,F,0.001243265644426026,0.0007356547327121137 +2012,BruCap,37,M,0.00098405825624877,0.001115822361080116 +2012,BruCap,37,F,0.0008394543546694647,0.0009982530571499876 +2012,BruCap,38,M,0.000967305088024763,0.001155001155001155 +2012,BruCap,38,F,0.0002047082906857728,0.0008088433540037746 +2012,BruCap,39,M,0.001180405272476884,0.0007365578197888534 +2012,BruCap,39,F,0.001028383381324558,0.0005425935973955506 +2012,BruCap,40,M,0.0007791195948578108,0.0010224948875255618 +2012,BruCap,40,F,0.001461988304093567,0.0005778676683039584 +2012,BruCap,41,M,0.001739130434782609,0.001484413656605641 +2012,BruCap,41,F,0.00120870265914585,0.0006045949214026603 +2012,BruCap,42,M,0.0013776815587482779,0.0020768431983385267 +2012,BruCap,42,F,0.001258389261744967,0.0009160305343511447 +2012,BruCap,43,M,0.0036108324974924782,0.001348435814455232 +2012,BruCap,43,F,0.0002154708037060978,0.0009630818619582664 +2012,BruCap,44,M,0.002295492487479132,0.001727613014684711 +2012,BruCap,44,F,0.0017663943475380878,0.001402524544179523 +2012,BruCap,45,M,0.0018687707641196016,0.002426448286320898 +2012,BruCap,45,F,0.0014808546646921938,0.0007459903021260724 +2012,BruCap,46,M,0.003422589087980673,0.0026289845547157412 +2012,BruCap,46,F,0.001849948612538541,0.001891789632992811 +2012,BruCap,47,M,0.003646677471636953,0.003287310979618672 +2012,BruCap,47,F,0.0018476698829809077,0.001950838860710105 +2012,BruCap,48,M,0.002548311743469951,0.001465738365701722 +2012,BruCap,48,F,0.001263689974726201,0.001663201663201663 +2012,BruCap,49,M,0.003247456159341849,0.0015402387370042358 +2012,BruCap,49,F,0.002336448598130841,0.001327433628318584 +2012,BruCap,50,M,0.005377548734035402,0.001224489795918367 +2012,BruCap,50,F,0.0027530707327403647,0.0018298261665141808 +2012,BruCap,51,M,0.005878510777269758,0.003857693956279469 +2012,BruCap,51,F,0.004587155963302753,0.002352941176470588 +2012,BruCap,52,M,0.006875138611665558,0.0018544274455261941 +2012,BruCap,52,F,0.003943545039435451,0.001913875598086125 +2012,BruCap,53,M,0.005981136415919025,0.0053268765133171895 +2012,BruCap,53,F,0.004393305439330545,0.001061571125265393 +2012,BruCap,54,M,0.008583690987124462,0.00486749594375338 +2012,BruCap,54,F,0.003874300473525614,0.002782415136338342 +2012,BruCap,55,M,0.009554140127388536,0.006369426751592357 +2012,BruCap,55,F,0.004691831947110258,0.003529411764705883 +2012,BruCap,56,M,0.005845104724792986,0.001729106628242075 +2012,BruCap,56,F,0.006266205704407953,0.003556609365737997 +2012,BruCap,57,M,0.0102731145076422,0.007092198581560284 +2012,BruCap,57,F,0.0035351303579319493,0.006191950464396285 +2012,BruCap,58,M,0.01018380526577248,0.00414651002073255 +2012,BruCap,58,F,0.005973451327433628,0.002079002079002079 +2012,BruCap,59,M,0.01209677419354839,0.008310249307479225 +2012,BruCap,59,F,0.005861136158701533,0.007284768211920529 +2012,BruCap,60,M,0.01370238421485339,0.006546644844517185 +2012,BruCap,60,F,0.009150012039489529,0.003072196620583718 +2012,BruCap,61,M,0.01190476190476191,0.007716049382716048 +2012,BruCap,61,F,0.009626672927917352,0.0022205773501110288 +2012,BruCap,62,M,0.01750917819824908,0.0101867572156197 +2012,BruCap,62,F,0.008254430687059966,0.007512520868113524 +2012,BruCap,63,M,0.01332174920359108,0.01194539249146758 +2012,BruCap,63,F,0.008333333333333333,0.004366812227074236 +2012,BruCap,64,M,0.015249266862170091,0.01338432122370937 +2012,BruCap,64,F,0.007842205323193916,0.004659832246039142 +2012,BruCap,65,M,0.01862980769230769,0.012618296529968459 +2012,BruCap,65,F,0.007996001999000498,0.0115718418514947 +2012,BruCap,66,M,0.021879483500717358,0.01248439450686642 +2012,BruCap,66,F,0.010300668151447659,0.0010845986984815619 +2012,BruCap,67,M,0.01885521885521886,0.022164276401564542 +2012,BruCap,67,F,0.01620879120879121,0.009836065573770493 +2012,BruCap,68,M,0.0213078618662748,0.01634877384196185 +2012,BruCap,68,F,0.0138438880706922,0.008588957055214725 +2012,BruCap,69,M,0.02257799671592775,0.0249266862170088 +2012,BruCap,69,F,0.01488587495865035,0.007662835249042145 +2012,BruCap,70,M,0.0345679012345679,0.028571428571428567 +2012,BruCap,70,F,0.01819560272934041,0.0157819225251076 +2012,BruCap,71,M,0.028559249786871268,0.033773861967694566 +2012,BruCap,71,F,0.0209013716525147,0.015457788347205709 +2012,BruCap,72,M,0.03416955017301039,0.01963993453355156 +2012,BruCap,72,F,0.01972637607381483,0.007957559681697613 +2012,BruCap,73,M,0.04302477183833117,0.03521126760563381 +2012,BruCap,73,F,0.022135416666666668,0.021680216802168015 +2012,BruCap,74,M,0.03799814643188138,0.03300970873786408 +2012,BruCap,74,F,0.020359687818120118,0.01671732522796353 +2012,BruCap,75,M,0.04703668861712135,0.028 +2012,BruCap,75,F,0.02363013698630137,0.0182328190743338 +2012,BruCap,76,M,0.04536390827517447,0.04989154013015185 +2012,BruCap,76,F,0.02922617070740618,0.02843601895734597 +2012,BruCap,77,M,0.046370967741935484,0.04555808656036447 +2012,BruCap,77,F,0.027100271002710032,0.04130808950086059 +2012,BruCap,78,M,0.0646186440677966,0.05333333333333334 +2012,BruCap,78,F,0.03464513958964008,0.01968503937007874 +2012,BruCap,79,M,0.058948486457780135,0.06720430107526881 +2012,BruCap,79,F,0.04007884362680683,0.03921568627450981 +2012,BruCap,80,M,0.0686164229471316,0.07516339869281045 +2012,BruCap,80,F,0.04739010989010989,0.042986425339366516 +2012,BruCap,81,M,0.07021791767554479,0.05279503105590062 +2012,BruCap,81,F,0.05030438961871195,0.04365079365079365 +2012,BruCap,82,M,0.0733822548365577,0.08856088560885607 +2012,BruCap,82,F,0.05067684831655675,0.03977272727272727 +2012,BruCap,83,M,0.08166189111747851,0.06310679611650485 +2012,BruCap,83,F,0.06304347826086956,0.07038123167155426 +2012,BruCap,84,M,0.1145752143413874,0.1077844311377246 +2012,BruCap,84,F,0.06794625719769674,0.0594059405940594 +2012,BruCap,85,M,0.1072340425531915,0.1333333333333333 +2012,BruCap,85,F,0.07643057222889156,0.08527131782945736 +2012,BruCap,86,M,0.1330685203574975,0.07751937984496124 +2012,BruCap,86,F,0.09007506255212676,0.08755760368663594 +2012,BruCap,87,M,0.1306081754735793,0.1176470588235294 +2012,BruCap,87,F,0.1031429836210713,0.08994708994708994 +2012,BruCap,88,M,0.1700960219478738,0.1707317073170732 +2012,BruCap,88,F,0.1244614648157013,0.1098901098901099 +2012,BruCap,89,M,0.1525925925925926,0.1590909090909091 +2012,BruCap,89,F,0.1424657534246575,0.109375 +2012,BruCap,90,M,0.153968253968254,0.05882352941176471 +2012,BruCap,90,F,0.1452937460518004,0.07964601769911504 +2012,BruCap,91,M,0.2013574660633484,0.1555555555555556 +2012,BruCap,91,F,0.1839587932303164,0.1322314049586777 +2012,BruCap,92,M,0.2519083969465649,0.2222222222222222 +2012,BruCap,92,F,0.1777777777777778,0.164179104477612 +2012,BruCap,93,M,0.2,0.1904761904761905 +2012,BruCap,93,F,0.202,0.1702127659574468 +2012,BruCap,94,M,0.2432432432432433,0.2307692307692308 +2012,BruCap,94,F,0.1948717948717949,0.2857142857142857 +2012,BruCap,95,M,0.3827160493827161,0.0 +2012,BruCap,95,F,0.2650602409638555,0.1891891891891892 +2012,BruCap,96,M,0.2307692307692308,0.0 +2012,BruCap,96,F,0.2675585284280937,0.2222222222222222 +2012,BruCap,97,M,0.3333333333333333,0.0 +2012,BruCap,97,F,0.2872340425531915,0.3333333333333333 +2012,BruCap,98,M,0.3428571428571429,0.3333333333333333 +2012,BruCap,98,F,0.283132530120482,0.0 +2012,BruCap,99,M,0.25,0.25 +2012,BruCap,99,F,0.3387096774193548,0.3 +2012,BruCap,100,M,0.2666666666666667,0.0 +2012,BruCap,100,F,0.3552631578947369,0.5 +2012,BruCap,101,M,0.375,0.0 +2012,BruCap,101,F,0.4807692307692308,0.1428571428571429 +2012,BruCap,102,M,1.0,0.0 +2012,BruCap,102,F,0.44,0.1428571428571429 +2012,BruCap,103,M,0.0,1.0 +2012,BruCap,103,F,0.3181818181818182,0.2 +2012,BruCap,104,M,0.0,0.0 +2012,BruCap,104,F,0.4166666666666667,0.0 +2012,BruCap,105,M,0.0,0.0 +2012,BruCap,105,F,0.2857142857142857,0.0 +2012,BruCap,106,M,0.0,0.0 +2012,BruCap,106,F,0.6666666666666666,0.0 +2012,BruCap,107,M,0.0,0.0 +2012,BruCap,107,F,1.0,0.0 +2012,BruCap,108,M,0.0,0.0 +2012,BruCap,108,F,0.0,0.0 +2012,BruCap,109,M,0.0,0.0 +2012,BruCap,109,F,0.0,0.0 +2012,BruCap,110,M,0.0,0.0 +2012,BruCap,110,F,0.0,0.0 +2012,BruCap,111,M,0.0,0.0 +2012,BruCap,111,F,0.0,0.0 +2012,BruCap,112,M,0.0,0.0 +2012,BruCap,112,F,0.0,0.0 +2012,BruCap,113,M,0.0,0.0 +2012,BruCap,113,F,0.0,0.0 +2012,BruCap,114,M,0.0,0.0 +2012,BruCap,114,F,0.0,0.0 +2012,BruCap,115,M,0.0,0.0 +2012,BruCap,115,F,0.0,0.0 +2012,BruCap,116,M,0.0,0.0 +2012,BruCap,116,F,0.0,0.0 +2012,BruCap,117,M,0.0,0.0 +2012,BruCap,117,F,0.0,0.0 +2012,BruCap,118,M,0.0,0.0 +2012,BruCap,118,F,0.0,0.0 +2012,BruCap,119,M,0.0,0.0 +2012,BruCap,119,F,0.0,0.0 +2012,BruCap,120,M,0.0,0.0 +2012,BruCap,120,F,0.0,0.0 +2012,Fla,0,M,0.0007419314949919624,0.001208459214501511 +2012,Fla,0,F,0.0006183889340927582,0.0006357279084551813 +2012,Fla,1,M,0.0003022609116189096,0.0003098853424233034 +2012,Fla,1,F,0.00022078536508437157,0.0003170577045022194 +2012,Fla,2,M,8.985802432157193e-05,0.0 +2012,Fla,2,F,0.0001905306277984186,0.0 +2012,Fla,3,M,5.8849492423127846e-05,0.0 +2012,Fla,3,F,6.184674376894056e-05,0.0 +2012,Fla,4,M,9.09394040437722e-05,0.0 +2012,Fla,4,F,9.427143889639567e-05,0.0 +2012,Fla,5,M,9.114385538508276e-05,0.0 +2012,Fla,5,F,6.328513115843431e-05,0.0003865481252415926 +2012,Fla,6,M,0.00015366175973447252,0.0 +2012,Fla,6,F,0.0001302210502327701,0.0 +2012,Fla,7,M,9.365634365634368e-05,0.0 +2012,Fla,7,F,3.293807641633729e-05,0.0 +2012,Fla,8,M,0.000129487553008967,0.0 +2012,Fla,8,F,0.0001355794326000746,0.0 +2012,Fla,9,M,9.71534052268532e-05,0.0 +2012,Fla,9,F,3.402517863218782e-05,0.0 +2012,Fla,10,M,9.616001025706777e-05,0.0 +2012,Fla,10,F,6.68985817500669e-05,0.0 +2012,Fla,11,M,0.00047036688617121367,0.0008071025020177562 +2012,Fla,11,F,0.0002286460885187,0.001720430107526882 +2012,Fla,12,M,0.0001257505737369927,0.0 +2012,Fla,12,F,3.242016534284325e-05,0.0004616805170821791 +2012,Fla,13,M,0.00015267175572519092,0.0 +2012,Fla,13,F,9.628036843287654e-05,0.0 +2012,Fla,14,M,0.000209781826900024,0.0004510599909788002 +2012,Fla,14,F,0.0001245368784831408,0.0 +2012,Fla,15,M,0.00023939910823832182,0.0 +2012,Fla,15,F,0.00015525057442712542,0.0 +2012,Fla,16,M,0.000298053709278412,0.0004791566842357451 +2012,Fla,16,F,0.0001548994702438118,0.0 +2012,Fla,17,M,0.0004412154013589434,0.00045024763619990995 +2012,Fla,17,F,0.00021638330757341585,0.0004982561036372695 +2012,Fla,18,M,0.0005650675255693058,0.0004591368227731864 +2012,Fla,18,F,0.00029223530786989685,0.00048332527791203475 +2012,Fla,19,M,0.0008756088217588793,0.0008669267446900738 +2012,Fla,19,F,0.00011403158674952958,0.0004452359750667853 +2012,Fla,20,M,0.0004597701149425287,0.0 +2012,Fla,20,F,0.0002272791840677292,0.0 +2012,Fla,21,M,0.0007670182166826463,0.0003714710252600297 +2012,Fla,21,F,0.0002579018253718085,0.00032289312237649337 +2012,Fla,22,M,0.0005971677188193143,0.001046389954656435 +2012,Fla,22,F,0.0003269527999048865,0.0 +2012,Fla,23,M,0.0006066383568766791,0.0002959455460195324 +2012,Fla,23,F,0.0002992399305763361,0.0 +2012,Fla,24,M,0.0008486480159194662,0.0 +2012,Fla,24,F,0.000184020855696979,0.00044424700133274093 +2012,Fla,25,M,0.0008521141245261952,0.0005208333333333333 +2012,Fla,25,F,0.00027556644213104714,0.0004172751929897768 +2012,Fla,26,M,0.0007309718880394722,0.00047180938900684123 +2012,Fla,26,F,0.0001562011871290222,0.0001996805111821086 +2012,Fla,27,M,0.0005075535916880637,0.00021944261575597985 +2012,Fla,27,F,0.0002141589671418956,0.0003950227138060439 +2012,Fla,28,M,0.000640148980126284,0.0008654262224145391 +2012,Fla,28,F,0.0001182312603452353,0.0002005615724027276 +2012,Fla,29,M,0.0006802913914793503,0.0006268282490597576 +2012,Fla,29,F,0.0002914347331915018,0.0001969667126255663 +2012,Fla,30,M,0.001069284127985085,0.001264488935721813 +2012,Fla,30,F,0.000255507608448785,0.0002039567611666327 +2012,Fla,31,M,0.0009453109795089943,0.0005951200158698671 +2012,Fla,31,F,0.0003342990862491643,0.0 +2012,Fla,32,M,0.0006826870562534135,0.0014391447368421052 +2012,Fla,32,F,0.000562129345962506,0.0002058036633052068 +2012,Fla,33,M,0.0008368200836820082,0.0002044571662236762 +2012,Fla,33,F,0.0003928721762312334,0.0006343835906111228 +2012,Fla,34,M,0.0008529027122306247,0.00020673971469919368 +2012,Fla,34,F,0.00034235827793786203,0.0002157962883038412 +2012,Fla,35,M,0.0008639557654648082,0.0008297033810412777 +2012,Fla,35,F,0.0005553444597082982,0.0009031384059607132 +2012,Fla,36,M,0.0009724759827901221,0.000637213254035684 +2012,Fla,36,F,0.0003894430963721878,0.0004499437570303712 +2012,Fla,37,M,0.001020003400011333,0.001487778958554729 +2012,Fla,37,F,0.0005150509328144672,0.0002372479240806643 +2012,Fla,38,M,0.0008185985592665358,0.0008800880088008801 +2012,Fla,38,F,0.0006675196083884964,0.0004813477737665463 +2012,Fla,39,M,0.00130476762088672,0.0004296455424274973 +2012,Fla,39,F,0.0007620749461291847,0.0 +2012,Fla,40,M,0.001101928374655647,0.001531393568147014 +2012,Fla,40,F,0.0006766069414860293,0.0005018820577164366 +2012,Fla,41,M,0.0015309097978227061,0.0006311803071744162 +2012,Fla,41,F,0.0006885528095413746,0.00048402710551790896 +2012,Fla,42,M,0.0014580093312597199,0.001107910480833149 +2012,Fla,42,F,0.001084144388320808,0.0012906556530717607 +2012,Fla,43,M,0.0014706591446067801,0.0008826125330979699 +2012,Fla,43,F,0.0007565588773642465,0.0010449320794148381 +2012,Fla,44,M,0.001794202628390344,0.001442307692307693 +2012,Fla,44,F,0.001107766405779651,0.001728608470181504 +2012,Fla,45,M,0.0018794013087878988,0.003082029397818872 +2012,Fla,45,F,0.001199372635852016,0.002036067481093659 +2012,Fla,46,M,0.00214992431388895,0.002431315341599806 +2012,Fla,46,F,0.001302171033429874,0.0015188335358444721 +2012,Fla,47,M,0.002201850401202549,0.002018672722684835 +2012,Fla,47,F,0.0016090622385273859,0.001256676091737355 +2012,Fla,48,M,0.00266564305973173,0.0013502565487442618 +2012,Fla,48,F,0.001586542641050161,0.0024021962937542897 +2012,Fla,49,M,0.002616385927735853,0.00226628895184136 +2012,Fla,49,F,0.0019450952654612968,0.001412429378531074 +2012,Fla,50,M,0.0033786007327614572,0.004232164449818622 +2012,Fla,50,F,0.002441438469152095,0.0015384615384615393 +2012,Fla,51,M,0.0034437263802857853,0.002465331278890601 +2012,Fla,51,F,0.002368332017593324,0.001542614731970691 +2012,Fla,52,M,0.0038124792197716953,0.0030303030303030307 +2012,Fla,52,F,0.003083041040191238,0.001244296972210701 +2012,Fla,53,M,0.00466665156423442,0.005710446758481693 +2012,Fla,53,F,0.003012810192957844,0.002779064381658175 +2012,Fla,54,M,0.005333518043914941,0.0036886757654002217 +2012,Fla,54,F,0.0031176015564567173,0.004326923076923077 +2012,Fla,55,M,0.0046772461520105,0.002718446601941748 +2012,Fla,55,F,0.0031415107810938174,0.004515805318615153 +2012,Fla,56,M,0.00601207282640444,0.0056247488951386105 +2012,Fla,56,F,0.003915597128562106,0.003089598352214212 +2012,Fla,57,M,0.007363586441016425,0.006722689075630253 +2012,Fla,57,F,0.0036099285483108014,0.004782146652497344 +2012,Fla,58,M,0.007841529354483253,0.007210455159981973 +2012,Fla,58,F,0.004731494169661557,0.002275312855517634 +2012,Fla,59,M,0.00772829486417328,0.00619933237958989 +2012,Fla,59,F,0.004647762285236827,0.008886255924170616 +2012,Fla,60,M,0.00887784090909091,0.006262042389210019 +2012,Fla,60,F,0.005036617570989083,0.002570694087403599 +2012,Fla,61,M,0.00984892746849178,0.006030150753768844 +2012,Fla,61,F,0.004979616405373608,0.007079646017699116 +2012,Fla,62,M,0.01016305561760107,0.007827788649706456 +2012,Fla,62,F,0.0057710448920703615,0.003125 +2012,Fla,63,M,0.012723076056972359,0.01221374045801527 +2012,Fla,63,F,0.006613611416026346,0.0058631921824104215 +2012,Fla,64,M,0.013128034242049929,0.00949868073878628 +2012,Fla,64,F,0.006863073317710077,0.003978779840848807 +2012,Fla,65,M,0.01304950887423218,0.01505376344086022 +2012,Fla,65,F,0.007140887786049077,0.006484149855907781 +2012,Fla,66,M,0.01625884862785661,0.01253298153034301 +2012,Fla,66,F,0.008927471986208595,0.009925558312655085 +2012,Fla,67,M,0.01499176276771005,0.008097165991902834 +2012,Fla,67,F,0.008887087218185787,0.0046547711404189285 +2012,Fla,68,M,0.01907784598214286,0.01790633608815427 +2012,Fla,68,F,0.009262581129121686,0.01063829787234043 +2012,Fla,69,M,0.02048319327731093,0.01631701631701632 +2012,Fla,69,F,0.01095849283194476,0.008912655971479501 +2012,Fla,70,M,0.021171521331565232,0.01593959731543624 +2012,Fla,70,F,0.01305708872230003,0.0134297520661157 +2012,Fla,71,M,0.023474178403755867,0.01878736122971819 +2012,Fla,71,F,0.01207883026064844,0.01628106255355613 +2012,Fla,72,M,0.026199842643587733,0.02372262773722628 +2012,Fla,72,F,0.014190402004944631,0.01462904911180774 +2012,Fla,73,M,0.028822346022903133,0.02455146364494807 +2012,Fla,73,F,0.0155841544339433,0.02231668437832094 +2012,Fla,74,M,0.030389674046238064,0.03571428571428571 +2012,Fla,74,F,0.01662982843911167,0.017221584385763492 +2012,Fla,75,M,0.03514082653329824,0.03546910755148741 +2012,Fla,75,F,0.01837089644177114,0.01861042183622829 +2012,Fla,76,M,0.03951090427958756,0.057347670250896064 +2012,Fla,76,F,0.02174234034699151,0.02546916890080429 +2012,Fla,77,M,0.04385428907168038,0.04161073825503357 +2012,Fla,77,F,0.02414709791758972,0.02677376171352075 +2012,Fla,78,M,0.05008430030744818,0.04231311706629055 +2012,Fla,78,F,0.02853790545399493,0.02852614896988907 +2012,Fla,79,M,0.05458019208922855,0.04983922829581994 +2012,Fla,79,F,0.03330090548529522,0.03389830508474577 +2012,Fla,80,M,0.06531949754232659,0.05594405594405594 +2012,Fla,80,F,0.03857004830917874,0.02127659574468085 +2012,Fla,81,M,0.06624813153961136,0.0594059405940594 +2012,Fla,81,F,0.04400878548767592,0.05244122965641953 +2012,Fla,82,M,0.08014379361387186,0.06904761904761905 +2012,Fla,82,F,0.04992737835875091,0.06496519721577726 +2012,Fla,83,M,0.09055739775777673,0.09562841530054644 +2012,Fla,83,F,0.0595202988302369,0.07918552036199095 +2012,Fla,84,M,0.1001700832512756,0.09246575342465753 +2012,Fla,84,F,0.07014223135579471,0.08498583569405099 +2012,Fla,85,M,0.1152770585189021,0.141025641025641 +2012,Fla,85,F,0.07887258597691818,0.1124260355029586 +2012,Fla,86,M,0.1289750561532096,0.1271186440677966 +2012,Fla,86,F,0.09618944277781324,0.07272727272727272 +2012,Fla,87,M,0.1490700601314502,0.1428571428571429 +2012,Fla,87,F,0.104462620175061,0.09523809523809523 +2012,Fla,88,M,0.1491198375084631,0.1811594202898551 +2012,Fla,88,F,0.1240353697749196,0.1176470588235294 +2012,Fla,89,M,0.1791392834428662,0.1440677966101695 +2012,Fla,89,F,0.1375868480281828,0.1046511627906977 +2012,Fla,90,M,0.1834542035992479,0.2291666666666667 +2012,Fla,90,F,0.1494608855242028,0.2014925373134328 +2012,Fla,91,M,0.2208676945141628,0.2112676056338028 +2012,Fla,91,F,0.1723132463204666,0.1551724137931035 +2012,Fla,92,M,0.2606023355869699,0.1714285714285714 +2012,Fla,92,F,0.1912097870412325,0.1186440677966102 +2012,Fla,93,M,0.2577937649880096,0.2857142857142857 +2012,Fla,93,F,0.2230187176423736,0.1568627450980392 +2012,Fla,94,M,0.3038674033149172,0.0625 +2012,Fla,94,F,0.2542016806722689,0.3035714285714286 +2012,Fla,95,M,0.2683982683982684,0.2222222222222222 +2012,Fla,95,F,0.2545561434450324,0.3548387096774194 +2012,Fla,96,M,0.3316708229426434,0.3333333333333333 +2012,Fla,96,F,0.2674897119341564,0.1481481481481482 +2012,Fla,97,M,0.3797909407665505,0.3333333333333333 +2012,Fla,97,F,0.3248945147679325,0.2800000000000001 +2012,Fla,98,M,0.4120879120879121,0.0 +2012,Fla,98,F,0.3274021352313168,0.1666666666666667 +2012,Fla,99,M,0.4259259259259261,0.0 +2012,Fla,99,F,0.3255813953488373,0.4666666666666667 +2012,Fla,100,M,0.410958904109589,0.0 +2012,Fla,100,F,0.3342541436464088,0.2 +2012,Fla,101,M,0.6129032258064516,0.0 +2012,Fla,101,F,0.3807106598984772,0.6666666666666666 +2012,Fla,102,M,0.3888888888888889,1.0 +2012,Fla,102,F,0.3947368421052632,1.0 +2012,Fla,103,M,0.5,0.0 +2012,Fla,103,F,0.3768115942028986,0.0 +2012,Fla,104,M,0.6666666666666666,0.0 +2012,Fla,104,F,0.6176470588235294,0.0 +2012,Fla,105,M,0.0,0.0 +2012,Fla,105,F,0.6086956521739131,0.0 +2012,Fla,106,M,0.0,0.0 +2012,Fla,106,F,0.4615384615384616,0.0 +2012,Fla,107,M,0.0,0.0 +2012,Fla,107,F,0.75,0.0 +2012,Fla,108,M,0.0,0.0 +2012,Fla,108,F,0.5,0.0 +2012,Fla,109,M,0.0,0.0 +2012,Fla,109,F,0.5,0.0 +2012,Fla,110,M,0.0,0.0 +2012,Fla,110,F,0.0,0.0 +2012,Fla,111,M,1.0,0.0 +2012,Fla,111,F,0.0,0.0 +2012,Fla,112,M,0.0,0.0 +2012,Fla,112,F,0.0,0.0 +2012,Fla,113,M,0.0,0.0 +2012,Fla,113,F,0.0,0.0 +2012,Fla,114,M,0.0,0.0 +2012,Fla,114,F,0.0,0.0 +2012,Fla,115,M,0.0,0.0 +2012,Fla,115,F,0.0,0.0 +2012,Fla,116,M,0.0,0.0 +2012,Fla,116,F,0.0,1.0 +2012,Fla,117,M,0.0,0.0 +2012,Fla,117,F,0.0,0.0 +2012,Fla,118,M,0.0,0.0 +2012,Fla,118,F,0.0,0.0 +2012,Fla,119,M,0.0,0.0 +2012,Fla,119,F,0.0,0.0 +2012,Fla,120,M,0.0,0.0 +2012,Fla,120,F,0.0,0.0 +2012,Wal,0,M,0.000942211055276382,0.0 +2012,Wal,0,F,0.0005991938119620872,0.0 +2012,Wal,1,M,0.00020205081578016868,0.0007507507507507507 +2012,Wal,1,F,0.0002651113467656416,0.0 +2012,Wal,2,M,0.0002520415364452062,0.0007751937984496124 +2012,Wal,2,F,0.0003129400719762166,0.0008285004142502071 +2012,Wal,3,M,0.00014784151389710232,0.0007867820613690008 +2012,Wal,3,F,5.229851995188536e-05,0.0 +2012,Wal,4,M,0.0001483312731767614,0.0 +2012,Wal,4,F,0.0001044932079414838,0.0 +2012,Wal,5,M,9.891196834817011e-05,0.0 +2012,Wal,5,F,0.00015357051446122352,0.0008361204013377926 +2012,Wal,6,M,9.982530571499875e-05,0.0008438818565400844 +2012,Wal,6,F,5.190760446405398e-05,0.0 +2012,Wal,7,M,0.0001001452105553052,0.0 +2012,Wal,7,F,0.0,0.0 +2012,Wal,8,M,5.075626839914729e-05,0.0 +2012,Wal,8,F,0.0003661279355614833,0.0 +2012,Wal,9,M,0.0,0.0 +2012,Wal,9,F,5.2988554472234004e-05,0.0 +2012,Wal,10,M,0.0001464057391049729,0.0 +2012,Wal,10,F,0.0,0.0 +2012,Wal,11,M,4.791796444487038e-05,0.0 +2012,Wal,11,F,5.0522912140655794e-05,0.0 +2012,Wal,12,M,0.0,0.0008110300081103001 +2012,Wal,12,F,0.0,0.0 +2012,Wal,13,M,9.8405825624877e-05,0.0 +2012,Wal,13,F,5.142710208279763e-05,0.0 +2012,Wal,14,M,0.0002945218927940311,0.0 +2012,Wal,14,F,0.0001024013107367774,0.000846740050804403 +2012,Wal,15,M,0.0001947419668938656,0.0 +2012,Wal,15,F,0.00010157956219208691,0.001679261125104954 +2012,Wal,16,M,0.0002489667878305034,0.0007692307692307692 +2012,Wal,16,F,0.0002079218213951554,0.0 +2012,Wal,17,M,0.0004438964241676941,0.0 +2012,Wal,17,F,0.000103268446326225,0.0 +2012,Wal,18,M,0.0003793626707132018,0.0 +2012,Wal,18,F,0.00025030036043251897,0.0006702412868632707 +2012,Wal,19,M,0.0006807969863386737,0.0 +2012,Wal,19,F,0.0001418640941977586,0.0 +2012,Wal,20,M,0.0008000711174326608,0.0 +2012,Wal,20,F,0.0005536843076639137,0.0 +2012,Wal,21,M,0.0008154759208082273,0.0024464831804281357 +2012,Wal,21,F,0.0001413560759553315,0.0 +2012,Wal,22,M,0.0006386861313868612,0.0 +2012,Wal,22,F,0.0001422812425895186,0.0 +2012,Wal,23,M,0.0007866000370164723,0.0 +2012,Wal,23,F,0.0004369568383745206,0.0 +2012,Wal,24,M,0.000680801400505738,0.001472754050073638 +2012,Wal,24,F,0.00030433679939132635,0.0 +2012,Wal,25,M,0.001128335949764521,0.0 +2012,Wal,25,F,0.00015493466921448132,0.00037664783427495286 +2012,Wal,26,M,0.001301744337412132,0.0 +2012,Wal,26,F,0.0002676802826703785,0.0003852080123266564 +2012,Wal,27,M,0.001109819258006553,0.0 +2012,Wal,27,F,0.0004340513265693669,0.0 +2012,Wal,28,M,0.0008010253123998717,0.0007818608287724785 +2012,Wal,28,F,0.0002806466097889538,0.0007686395080707147 +2012,Wal,29,M,0.001112936562615931,0.0007521624670928919 +2012,Wal,29,F,0.0004864601913410086,0.00033921302578019 +2012,Wal,30,M,0.00042063199957936804,0.001494768310911809 +2012,Wal,30,F,0.0005242189138184106,0.0 +2012,Wal,31,M,0.001514993208651134,0.0003480682213713888 +2012,Wal,31,F,0.0004712782112373671,0.0003314550878355983 +2012,Wal,32,M,0.001055019254101387,0.001033057851239669 +2012,Wal,32,F,0.0005386770092652446,0.0 +2012,Wal,33,M,0.001439539347408829,0.00033613445378151267 +2012,Wal,33,F,0.0006989247311827957,0.0 +2012,Wal,34,M,0.001536423841059603,0.000346860908775581 +2012,Wal,34,F,0.00047801147227533465,0.0 +2012,Wal,35,M,0.001195488330994335,0.002511661284535343 +2012,Wal,35,F,0.00036164496796858863,0.0007233273056057866 +2012,Wal,36,M,0.0018568186507117808,0.001715854495538779 +2012,Wal,36,F,0.001022547164987985,0.0010611956137247973 +2012,Wal,37,M,0.001435359334785191,0.0009775171065493646 +2012,Wal,37,F,0.0005469099587331577,0.00034094783498124785 +2012,Wal,38,M,0.001990804379769636,0.0018382352941176468 +2012,Wal,38,F,0.000947867298578199,0.0 +2012,Wal,39,M,0.001977193305131506,0.001820388349514563 +2012,Wal,39,F,0.001052920710492584,0.000326797385620915 +2012,Wal,40,M,0.00199122052767344,0.002403124061279664 +2012,Wal,40,F,0.001075847229693383,0.0010312822275696108 +2012,Wal,41,M,0.002934164679992665,0.0018192844147968468 +2012,Wal,41,F,0.0012453300124533,0.000977198697068404 +2012,Wal,42,M,0.002684688020736901,0.001857010213556175 +2012,Wal,42,F,0.001148527587632655,0.001395673412421493 +2012,Wal,43,M,0.003307972213033411,0.00124494242141301 +2012,Wal,43,F,0.0013888888888888892,0.0016863406408094439 +2012,Wal,44,M,0.002186148192939207,0.003098853424233034 +2012,Wal,44,F,0.00179137384594185,0.00034482758620689663 +2012,Wal,45,M,0.003108145168662584,0.0054410080183276074 +2012,Wal,45,F,0.0021626492453255238,0.000992063492063492 +2012,Wal,46,M,0.003536224196614065,0.002018454440599769 +2012,Wal,46,F,0.00222590782122905,0.0013888888888888892 +2012,Wal,47,M,0.004208718058836161,0.003318250377073907 +2012,Wal,47,F,0.002017484868863484,0.001383125864453666 +2012,Wal,48,M,0.003601704221021654,0.0036821110770174897 +2012,Wal,48,F,0.0022141792633595912,0.001075654356400143 +2012,Wal,49,M,0.004345661128966547,0.006005056890012643 +2012,Wal,49,F,0.002528334786399303,0.001189532117367169 +2012,Wal,50,M,0.0056740103728002145,0.002609262883235486 +2012,Wal,50,F,0.003162393162393163,0.001572327044025158 +2012,Wal,51,M,0.006863050938098846,0.003945371775417299 +2012,Wal,51,F,0.003960654596100279,0.0023809523809523807 +2012,Wal,52,M,0.00744261119081779,0.007215480485405052 +2012,Wal,52,F,0.0036853475663997967,0.0008417508417508418 +2012,Wal,53,M,0.007598084361760914,0.004267892317793829 +2012,Wal,53,F,0.003507404520654716,0.001710863986313088 +2012,Wal,54,M,0.009072627788430059,0.004721753794266442 +2012,Wal,54,F,0.004340700713115118,0.003068829460762823 +2012,Wal,55,M,0.009203045196106771,0.006034193764666443 +2012,Wal,55,F,0.004590045900459004,0.004016064257028112 +2012,Wal,56,M,0.009796718099436693,0.009329647546648235 +2012,Wal,56,F,0.005550291051847841,0.0009161704076958314 +2012,Wal,57,M,0.009236848604593726,0.01080302484695715 +2012,Wal,57,F,0.005833716123105191,0.003272557269752221 +2012,Wal,58,M,0.01244043140205669,0.009774436090225564 +2012,Wal,58,F,0.00724096047837055,0.003904343582235237 +2012,Wal,59,M,0.01438183779341518,0.007202426080363912 +2012,Wal,59,F,0.006228900194950312,0.00496031746031746 +2012,Wal,60,M,0.01338666666666667,0.011665325824617859 +2012,Wal,60,F,0.006566467240624544,0.005063291139240506 +2012,Wal,61,M,0.016277977774299582,0.012746710526315793 +2012,Wal,61,F,0.007017885861884107,0.0068762278978389 +2012,Wal,62,M,0.01440785307156428,0.00880503144654088 +2012,Wal,62,F,0.007742500973899493,0.006043956043956044 +2012,Wal,63,M,0.017629876903818068,0.01145038167938931 +2012,Wal,63,F,0.008163849899742195,0.006033182503770739 +2012,Wal,64,M,0.01821551495896214,0.01141352063213345 +2012,Wal,64,F,0.009213014595354702,0.002757859900717044 +2012,Wal,65,M,0.01835870939372286,0.01395348837209303 +2012,Wal,65,F,0.008979391560353288,0.005970149253731343 +2012,Wal,66,M,0.02181572831546593,0.01881067961165049 +2012,Wal,66,F,0.01051205984780085,0.009097270818754373 +2012,Wal,67,M,0.02143892576485847,0.01806140878988561 +2012,Wal,67,F,0.01128143871524322,0.005442176870748299 +2012,Wal,68,M,0.0229664272590613,0.01825557809330629 +2012,Wal,68,F,0.01398551753514128,0.01064638783269962 +2012,Wal,69,M,0.02667822402003275,0.027007299270073 +2012,Wal,69,F,0.01219908913467795,0.01486697965571205 +2012,Wal,70,M,0.030226167829211587,0.02482544608223429 +2012,Wal,70,F,0.01509730342961864,0.016528925619834708 +2012,Wal,71,M,0.03137632338787296,0.023028611304954642 +2012,Wal,71,F,0.01628180039138944,0.01865929509329648 +2012,Wal,72,M,0.03321868211440985,0.03254437869822485 +2012,Wal,72,F,0.016667864070694732,0.01705320600272851 +2012,Wal,73,M,0.03598467146462287,0.043225270157938485 +2012,Wal,73,F,0.019200458518412386,0.0170697012802276 +2012,Wal,74,M,0.03803109834604338,0.03949579831932773 +2012,Wal,74,F,0.02210283960092095,0.01746393318147305 +2012,Wal,75,M,0.04288724973656481,0.04792043399638336 +2012,Wal,75,F,0.02253411306042885,0.01934984520123839 +2012,Wal,76,M,0.04399057344854674,0.04615384615384616 +2012,Wal,76,F,0.02769971898835809,0.02496217851739789 +2012,Wal,77,M,0.0519306099608282,0.060422960725075525 +2012,Wal,77,F,0.03166561114629513,0.033383915022761765 +2012,Wal,78,M,0.05906528886801315,0.05434782608695652 +2012,Wal,78,F,0.03419773095623987,0.03115264797507788 +2012,Wal,79,M,0.06452380952380952,0.0798650168728909 +2012,Wal,79,F,0.0410450586898902,0.03602058319039452 +2012,Wal,80,M,0.07249440437702064,0.07644110275689223 +2012,Wal,80,F,0.04347488549025697,0.03672787979966611 +2012,Wal,81,M,0.08624645701174248,0.08080808080808081 +2012,Wal,81,F,0.0499599679743795,0.05258620689655173 +2012,Wal,82,M,0.08788303002022088,0.08708272859216255 +2012,Wal,82,F,0.06314772527665555,0.06320754716981132 +2012,Wal,83,M,0.09896391568417293,0.1137521222410866 +2012,Wal,83,F,0.06734578381437464,0.06964091403699674 +2012,Wal,84,M,0.1183738541251495,0.1074074074074074 +2012,Wal,84,F,0.07580204432749722,0.07917570498915401 +2012,Wal,85,M,0.1270059605685466,0.1363636363636364 +2012,Wal,85,F,0.08843980877879183,0.08670520231213873 +2012,Wal,86,M,0.134152585765489,0.1297297297297297 +2012,Wal,86,F,0.1016773897058824,0.1036662452591656 +2012,Wal,87,M,0.1588345864661654,0.1574344023323615 +2012,Wal,87,F,0.1137872672829059,0.1304985337243402 +2012,Wal,88,M,0.1765607047108388,0.2036363636363637 +2012,Wal,88,F,0.1385632702134055,0.1316239316239316 +2012,Wal,89,M,0.1908433734939759,0.2111111111111111 +2012,Wal,89,F,0.1427101200686107,0.1474103585657371 +2012,Wal,90,M,0.1960326721120187,0.2264150943396227 +2012,Wal,90,F,0.1611496531219029,0.1883289124668435 +2012,Wal,91,M,0.2351097178683386,0.26 +2012,Wal,91,F,0.1883257266394427,0.2292358803986711 +2012,Wal,92,M,0.2552356020942409,0.3050847457627119 +2012,Wal,92,F,0.2036814725890356,0.1630434782608696 +2012,Wal,93,M,0.2899728997289973,0.4166666666666667 +2012,Wal,93,F,0.2209985315712188,0.25 +2012,Wal,94,M,0.3211678832116789,0.3333333333333333 +2012,Wal,94,F,0.2144873000940734,0.3076923076923077 +2012,Wal,95,M,0.330188679245283,0.3636363636363637 +2012,Wal,95,F,0.2596944770857814,0.2 +2012,Wal,96,M,0.2877697841726619,0.8571428571428571 +2012,Wal,96,F,0.3146666666666667,0.2340425531914894 +2012,Wal,97,M,0.3416666666666667,0.3333333333333333 +2012,Wal,97,F,0.2744807121661721,0.3555555555555556 +2012,Wal,98,M,0.3068181818181818,0.3333333333333333 +2012,Wal,98,F,0.3112128146453089,0.3846153846153847 +2012,Wal,99,M,0.4615384615384616,0.1428571428571429 +2012,Wal,99,F,0.347985347985348,0.4444444444444444 +2012,Wal,100,M,0.5789473684210527,1.0 +2012,Wal,100,F,0.3645320197044335,0.5384615384615384 +2012,Wal,101,M,0.6428571428571429,1.0 +2012,Wal,101,F,0.4491525423728814,0.3076923076923077 +2012,Wal,102,M,0.5,0.0 +2012,Wal,102,F,0.4583333333333333,0.5714285714285714 +2012,Wal,103,M,0.5,0.0 +2012,Wal,103,F,0.4242424242424243,0.0 +2012,Wal,104,M,0.0,0.0 +2012,Wal,104,F,0.3333333333333333,1.0 +2012,Wal,105,M,0.0,0.0 +2012,Wal,105,F,0.2857142857142857,0.0 +2012,Wal,106,M,0.0,0.0 +2012,Wal,106,F,0.5,0.0 +2012,Wal,107,M,0.0,0.0 +2012,Wal,107,F,0.5,1.0 +2012,Wal,108,M,0.0,0.0 +2012,Wal,108,F,1.0,0.0 +2012,Wal,109,M,0.0,0.0 +2012,Wal,109,F,0.0,0.0 +2012,Wal,110,M,0.0,0.0 +2012,Wal,110,F,0.0,0.0 +2012,Wal,111,M,0.0,0.0 +2012,Wal,111,F,1.0,0.0 +2012,Wal,112,M,0.0,0.0 +2012,Wal,112,F,0.0,0.0 +2012,Wal,113,M,0.0,0.0 +2012,Wal,113,F,0.0,0.0 +2012,Wal,114,M,0.0,0.0 +2012,Wal,114,F,0.0,0.0 +2012,Wal,115,M,0.0,0.0 +2012,Wal,115,F,0.0,0.0 +2012,Wal,116,M,0.0,0.0 +2012,Wal,116,F,0.0,0.0 +2012,Wal,117,M,0.0,0.0 +2012,Wal,117,F,0.0,0.0 +2012,Wal,118,M,0.0,0.0 +2012,Wal,118,F,0.0,0.0 +2012,Wal,119,M,0.0,0.0 +2012,Wal,119,F,0.0,0.0 +2012,Wal,120,M,0.0,0.0 +2012,Wal,120,F,0.0,0.0 +2013,BruCap,0,M,0.0009262117937635072,0.0003498950314905528 +2013,BruCap,0,F,0.0004855940433797345,0.0 +2013,BruCap,1,M,0.0004699248120300752,0.0 +2013,BruCap,1,F,0.00016420361247947458,0.0 +2013,BruCap,2,M,0.0004601226993865031,0.0 +2013,BruCap,2,F,0.0001636125654450262,0.0 +2013,BruCap,3,M,0.0001578531965272297,0.0 +2013,BruCap,3,F,0.00033461602810774636,0.0 +2013,BruCap,4,M,0.0,0.0 +2013,BruCap,4,F,0.0,0.0 +2013,BruCap,5,M,0.00016801075268817208,0.0 +2013,BruCap,5,F,0.0003541076487252125,0.0 +2013,BruCap,6,M,0.0001708233686368295,0.0 +2013,BruCap,6,F,0.00017995321216483708,0.0 +2013,BruCap,7,M,0.0,0.0 +2013,BruCap,7,F,0.0001861850679575498,0.0 +2013,BruCap,8,M,0.0001833180568285976,0.0 +2013,BruCap,8,F,0.0,0.0005878894767783657 +2013,BruCap,9,M,0.0001946282600233554,0.0 +2013,BruCap,9,F,0.0,0.0 +2013,BruCap,10,M,0.0,0.0 +2013,BruCap,10,F,0.0,0.0 +2013,BruCap,11,M,0.0002030044660982542,0.0 +2013,BruCap,11,F,0.0002058460271716756,0.0006858710562414268 +2013,BruCap,12,M,0.0,0.0 +2013,BruCap,12,F,0.0,0.0 +2013,BruCap,13,M,0.0,0.0 +2013,BruCap,13,F,0.0002153316106804479,0.0 +2013,BruCap,14,M,0.0004336513443191674,0.0 +2013,BruCap,14,F,0.0,0.0 +2013,BruCap,15,M,0.0,0.0 +2013,BruCap,15,F,0.0,0.0 +2013,BruCap,16,M,0.0,0.0 +2013,BruCap,16,F,0.0006801178871004308,0.0 +2013,BruCap,17,M,0.00021843599825251202,0.0006968641114982577 +2013,BruCap,17,F,0.000228937728937729,0.0 +2013,BruCap,18,M,0.0010475591870940713,0.0006131207847946045 +2013,BruCap,18,F,0.0002281542322610085,0.0 +2013,BruCap,19,M,0.0004254413954477772,0.0005662514156285391 +2013,BruCap,19,F,0.0,0.0 +2013,BruCap,20,M,0.0008238928939237897,0.0 +2013,BruCap,20,F,0.0,0.000426075841499787 +2013,BruCap,21,M,0.0020512820512820517,0.0 +2013,BruCap,21,F,0.0002055498458376156,0.0003703703703703704 +2013,BruCap,22,M,0.00020283975659229209,0.0008107012565869478 +2013,BruCap,22,F,0.0002043735949315349,0.0009375 +2013,BruCap,23,M,0.0006027727546714887,0.0003865481252415926 +2013,BruCap,23,F,0.0001968891514077574,0.0 +2013,BruCap,24,M,0.0007667241709794901,0.0006851661527920522 +2013,BruCap,24,F,0.0,0.0002482005460412013 +2013,BruCap,25,M,0.0003827751196172248,0.0005959475566150177 +2013,BruCap,25,F,0.0007174887892376681,0.0 +2013,BruCap,26,M,0.000373761913660998,0.0002708559046587216 +2013,BruCap,26,F,0.00017537706068046299,0.0002179598953792502 +2013,BruCap,27,M,0.0009264406151565683,0.0 +2013,BruCap,27,F,0.0005456529647144416,0.0 +2013,BruCap,28,M,0.0003741814780168382,0.0006730984967466907 +2013,BruCap,28,F,0.0003486142583231654,0.000394399526720568 +2013,BruCap,29,M,0.001320007542900245,0.00022416498542927597 +2013,BruCap,29,F,0.00018244845831052726,0.0 +2013,BruCap,30,M,0.001300631735414344,0.0008421052631578947 +2013,BruCap,30,F,0.0001791151710549884,0.00019120458891013392 +2013,BruCap,31,M,0.0003673094582185491,0.0002110149820637265 +2013,BruCap,31,F,0.0001791472590469366,0.0006171569635877391 +2013,BruCap,32,M,0.0003658982802780826,0.0001961938395134393 +2013,BruCap,32,F,0.0007075888908544138,0.0001933114247052001 +2013,BruCap,33,M,0.0007374631268436577,0.0006050826946349334 +2013,BruCap,33,F,0.00018875047187617969,0.0 +2013,BruCap,34,M,0.000942507068803016,0.0008249123530624871 +2013,BruCap,34,F,0.001131435036771639,0.000429000429000429 +2013,BruCap,35,M,0.0009509319132750091,0.0010471204188481679 +2013,BruCap,35,F,0.0001907668828691339,0.0 +2013,BruCap,36,M,0.0011730205278592382,0.0004152823920265781 +2013,BruCap,36,F,0.0007925500297206263,0.0006942837306179125 +2013,BruCap,37,M,0.001168451801363194,0.0004411116012351125 +2013,BruCap,37,F,0.0006274837900020916,0.0009883864591055099 +2013,BruCap,38,M,0.0007880220646178094,0.0008845643520566123 +2013,BruCap,38,F,0.0010528532322594231,0.000503651473180559 +2013,BruCap,39,M,0.0009718172983479103,0.001391465677179963 +2013,BruCap,39,F,0.001636996112134234,0.0008282716731087798 +2013,BruCap,40,M,0.0011848341232227491,0.0014687882496940028 +2013,BruCap,40,F,0.0006158899609936358,0.000277623542476402 +2013,BruCap,41,M,0.001362928348909657,0.001293995859213251 +2013,BruCap,41,F,0.0006280092108017584,0.0008680555555555555 +2013,BruCap,42,M,0.0017277788443079288,0.001002255073916312 +2013,BruCap,42,F,0.0004035512510088781,0.000608457560085184 +2013,BruCap,43,M,0.001380670611439842,0.0005206977349648532 +2013,BruCap,43,F,0.0016732901066722446,0.0006093845216331506 +2013,BruCap,44,M,0.001798561151079137,0.0026809651474530827 +2013,BruCap,44,F,0.001282051282051282,0.0013153567905294311 +2013,BruCap,45,M,0.001259445843828716,0.002326934264107039 +2013,BruCap,45,F,0.002203613926840018,0.001430103682516983 +2013,BruCap,46,M,0.002087246921310791,0.001222867624579639 +2013,BruCap,46,F,0.001691689574962994,0.001111111111111111 +2013,BruCap,47,M,0.003821399839098954,0.003320053120849934 +2013,BruCap,47,F,0.003274662300450266,0.0007763975155279503 +2013,BruCap,48,M,0.003848490986429006,0.001666666666666667 +2013,BruCap,48,F,0.0028682646998565873,0.001956181533646323 +2013,BruCap,49,M,0.003803888419273035,0.0032679738562091517 +2013,BruCap,49,F,0.001685985247629084,0.001674340728338217 +2013,BruCap,50,M,0.0043383947939262466,0.0038402457757296467 +2013,BruCap,50,F,0.003608575673954575,0.0017746228926353148 +2013,BruCap,51,M,0.003591470258136925,0.0028747433264887053 +2013,BruCap,51,F,0.003807911994922785,0.001374255611543747 +2013,BruCap,52,M,0.006567425569176883,0.00684931506849315 +2013,BruCap,52,F,0.0027960854803275427,0.002807674309780066 +2013,BruCap,53,M,0.004910714285714286,0.002815579540122009 +2013,BruCap,53,F,0.004171011470281543,0.0009657170449058426 +2013,BruCap,54,M,0.007868548947003009,0.003911980440097799 +2013,BruCap,54,F,0.0046267087276551,0.002675227394328518 +2013,BruCap,55,M,0.006002400960384154,0.003854625550660793 +2013,BruCap,55,F,0.0047464940668824175,0.006307339449541285 +2013,BruCap,56,M,0.01167701863354037,0.005344735435595938 +2013,BruCap,56,F,0.00556149732620321,0.003003003003003003 +2013,BruCap,57,M,0.010086100861008607,0.005917159763313609 +2013,BruCap,57,F,0.005691768826619965,0.0023852116875372692 +2013,BruCap,58,M,0.01091647626301092,0.007962840079628402 +2013,BruCap,58,F,0.005545696539485359,0.004533678756476684 +2013,BruCap,59,M,0.009326947315351651,0.007790368271954674 +2013,BruCap,59,F,0.005129348795718109,0.003536067892503536 +2013,BruCap,60,M,0.01669663498587208,0.01087744742567078 +2013,BruCap,60,F,0.0070438536696205405,0.005590496156533892 +2013,BruCap,61,M,0.01203133743704533,0.00676818950930626 +2013,BruCap,61,F,0.00757760938645808,0.005595523581135092 +2013,BruCap,62,M,0.01155751238304898,0.012 +2013,BruCap,62,F,0.005945303210463734,0.003076923076923077 +2013,BruCap,63,M,0.0168262257035103,0.013309671694764859 +2013,BruCap,63,F,0.0061743640405038285,0.001755926251097454 +2013,BruCap,64,M,0.017109144542772858,0.00980392156862745 +2013,BruCap,64,F,0.0101711734061027,0.007252946509519492 +2013,BruCap,65,M,0.02039592081583683,0.01427115188583079 +2013,BruCap,65,F,0.011167759164845841,0.004887585532746823 +2013,BruCap,66,M,0.02167853824713534,0.0154015401540154 +2013,BruCap,66,F,0.01016260162601626,0.009081735620585271 +2013,BruCap,67,M,0.01796187683284458,0.01181102362204725 +2013,BruCap,67,F,0.01323570825119685,0.01 +2013,BruCap,68,M,0.02892561983471075,0.01267605633802817 +2013,BruCap,68,F,0.01261564339781329,0.008888888888888889 +2013,BruCap,69,M,0.019962335216572508,0.02288984263233191 +2013,BruCap,69,F,0.01854066985645933,0.00641025641025641 +2013,BruCap,70,M,0.02723083368244659,0.029827315541601264 +2013,BruCap,70,F,0.01399533488837055,0.006631299734748011 +2013,BruCap,71,M,0.030179028132992333,0.01444043321299639 +2013,BruCap,71,F,0.02324680356450988,0.01212121212121212 +2013,BruCap,72,M,0.034786437692646416,0.018957345971563986 +2013,BruCap,72,F,0.01692665117822768,0.008905852417302799 +2013,BruCap,73,M,0.03875278396436526,0.02622377622377623 +2013,BruCap,73,F,0.01591425787593374,0.0110041265474553 +2013,BruCap,74,M,0.0372557928214448,0.03564727954971858 +2013,BruCap,74,F,0.016273663234805717,0.01884057971014493 +2013,BruCap,75,M,0.04116222760290557,0.04294478527607362 +2013,BruCap,75,F,0.023941707147814014,0.01751592356687898 +2013,BruCap,76,M,0.04197530864197531,0.04421052631578947 +2013,BruCap,76,F,0.02483385799230501,0.028358208955223882 +2013,BruCap,77,M,0.04295442640125721,0.05594405594405594 +2013,BruCap,77,F,0.030136986301369868,0.02356902356902357 +2013,BruCap,78,M,0.05848261327713384,0.03482587064676617 +2013,BruCap,78,F,0.03630017452006981,0.03442028985507247 +2013,BruCap,79,M,0.04829545454545454,0.043478260869565216 +2013,BruCap,79,F,0.03673897830650805,0.03512396694214876 +2013,BruCap,80,M,0.06182643221781055,0.037900874635568516 +2013,BruCap,80,F,0.03848797250859107,0.03255813953488372 +2013,BruCap,81,M,0.06871609403254972,0.07380073800738007 +2013,BruCap,81,F,0.04075009015506671,0.03422982885085575 +2013,BruCap,82,M,0.07937540663630449,0.0903010033444816 +2013,BruCap,82,F,0.0597165991902834,0.04301075268817205 +2013,BruCap,83,M,0.1108711303095752,0.07563025210084033 +2013,BruCap,83,F,0.06382978723404255,0.04573170731707317 +2013,BruCap,84,M,0.09561128526645768,0.09473684210526316 +2013,BruCap,84,F,0.0704828660436137,0.07692307692307693 +2013,BruCap,85,M,0.118421052631579,0.1027397260273973 +2013,BruCap,85,F,0.08091286307053942,0.07913669064748201 +2013,BruCap,86,M,0.1202290076335878,0.1323529411764706 +2013,BruCap,86,F,0.09079061685490876,0.1017699115044248 +2013,BruCap,87,M,0.145475372279496,0.1166666666666667 +2013,BruCap,87,F,0.1073394495412844,0.07526881720430108 +2013,BruCap,88,M,0.1572254335260116,0.18604651162790695 +2013,BruCap,88,F,0.1219390304847576,0.09036144578313253 +2013,BruCap,89,M,0.1685950413223141,0.1692307692307693 +2013,BruCap,89,F,0.1173864894795128,0.1548387096774194 +2013,BruCap,90,M,0.1607142857142857,0.2028985507246377 +2013,BruCap,90,F,0.1382636655948553,0.07017543859649122 +2013,BruCap,91,M,0.2022684310018904,0.1041666666666667 +2013,BruCap,91,F,0.1445603576751118,0.1456310679611651 +2013,BruCap,92,M,0.2285714285714286,0.05555555555555555 +2013,BruCap,92,F,0.1713255184851217,0.1683168316831683 +2013,BruCap,93,M,0.2447916666666667,0.09090909090909093 +2013,BruCap,93,F,0.191304347826087,0.2641509433962264 +2013,BruCap,94,M,0.2233009708737864,0.0 +2013,BruCap,94,F,0.2208436724565757,0.1315789473684211 +2013,BruCap,95,M,0.2804878048780488,0.2 +2013,BruCap,95,F,0.21103896103896105,0.32 +2013,BruCap,96,M,0.2549019607843137,0.0 +2013,BruCap,96,F,0.2190082644628099,0.07142857142857142 +2013,BruCap,97,M,0.3055555555555556,0.5 +2013,BruCap,97,F,0.273972602739726,0.08333333333333333 +2013,BruCap,98,M,0.3823529411764706,0.6 +2013,BruCap,98,F,0.3118811881188119,0.2666666666666667 +2013,BruCap,99,M,0.3478260869565218,1.0 +2013,BruCap,99,F,0.4117647058823529,0.1428571428571429 +2013,BruCap,100,M,0.2142857142857143,0.0 +2013,BruCap,100,F,0.325,0.1428571428571429 +2013,BruCap,101,M,0.2,0.0 +2013,BruCap,101,F,0.3061224489795919,0.5 +2013,BruCap,102,M,0.8,0.0 +2013,BruCap,102,F,0.5384615384615384,0.4 +2013,BruCap,103,M,0.0,0.0 +2013,BruCap,103,F,0.2142857142857143,0.2 +2013,BruCap,104,M,1.0,0.0 +2013,BruCap,104,F,0.4666666666666667,0.0 +2013,BruCap,105,M,0.0,0.0 +2013,BruCap,105,F,0.2857142857142857,0.0 +2013,BruCap,106,M,1.0,0.0 +2013,BruCap,106,F,0.6,0.0 +2013,BruCap,107,M,0.0,0.0 +2013,BruCap,107,F,0.0,0.0 +2013,BruCap,108,M,0.0,0.0 +2013,BruCap,108,F,0.0,0.0 +2013,BruCap,109,M,0.0,0.0 +2013,BruCap,109,F,0.0,0.0 +2013,BruCap,110,M,0.0,0.0 +2013,BruCap,110,F,0.0,0.0 +2013,BruCap,111,M,0.0,0.0 +2013,BruCap,111,F,0.0,0.0 +2013,BruCap,112,M,0.0,0.0 +2013,BruCap,112,F,0.0,0.0 +2013,BruCap,113,M,0.0,0.0 +2013,BruCap,113,F,0.0,0.0 +2013,BruCap,114,M,0.0,0.0 +2013,BruCap,114,F,0.0,0.0 +2013,BruCap,115,M,0.0,0.0 +2013,BruCap,115,F,0.0,0.0 +2013,BruCap,116,M,0.0,0.0 +2013,BruCap,116,F,0.0,0.0 +2013,BruCap,117,M,0.0,0.0 +2013,BruCap,117,F,0.0,0.0 +2013,BruCap,118,M,0.0,0.0 +2013,BruCap,118,F,0.0,0.0 +2013,BruCap,119,M,0.0,0.0 +2013,BruCap,119,F,0.0,0.0 +2013,BruCap,120,M,0.0,0.0 +2013,BruCap,120,F,0.0,0.0 +2013,Fla,0,M,0.0009177796063041963,0.001161103047895501 +2013,Fla,0,F,0.0007945967421533573,0.001198681450404555 +2013,Fla,1,M,0.0003671633570969618,0.0003008423586040915 +2013,Fla,1,F,0.0001931496265773886,0.0 +2013,Fla,2,M,0.00011976047904191621,0.0 +2013,Fla,2,F,9.37529297790556e-05,0.0 +2013,Fla,3,M,8.923525387429727e-05,0.0006561679790026247 +2013,Fla,3,F,0.00012584156546907452,0.0006727211570803902 +2013,Fla,4,M,0.00014610057563626798,0.0 +2013,Fla,4,F,6.138358602909582e-05,0.0 +2013,Fla,5,M,6.0239149423210144e-05,0.0 +2013,Fla,5,F,0.0001249141215414403,0.0 +2013,Fla,6,M,3.0242545212605104e-05,0.0 +2013,Fla,6,F,9.436336185203825e-05,0.0 +2013,Fla,7,M,9.178522257916476e-05,0.0 +2013,Fla,7,F,6.480671397556787e-05,0.0 +2013,Fla,8,M,0.00018654976214905333,0.0 +2013,Fla,8,F,3.278258589037504e-05,0.0004060089321965083 +2013,Fla,9,M,9.674298613350533e-05,0.0 +2013,Fla,9,F,3.372112628561794e-05,0.0 +2013,Fla,10,M,0.0001611863313990974,0.0 +2013,Fla,10,F,3.3921302578019e-05,0.0 +2013,Fla,11,M,6.392227051904884e-05,0.0 +2013,Fla,11,F,6.653581290129412e-05,0.0 +2013,Fla,12,M,0.0001248127808287569,0.0 +2013,Fla,12,F,0.0,0.0 +2013,Fla,13,M,6.264486625321055e-05,0.0 +2013,Fla,13,F,9.702457956015524e-05,0.0 +2013,Fla,14,M,0.0001828042166839315,0.0 +2013,Fla,14,F,3.200102403276905e-05,0.000925925925925926 +2013,Fla,15,M,0.0001493250507705173,0.000447227191413238 +2013,Fla,15,F,0.000124057935055671,0.000469704086425552 +2013,Fla,16,M,0.0002982403817476886,0.0 +2013,Fla,16,F,9.286775631500742e-05,0.0 +2013,Fla,17,M,0.00029716798906421804,0.0008733624454148473 +2013,Fla,17,F,0.00021620286005497727,0.0 +2013,Fla,18,M,0.0004396763981709462,0.0008230452674897119 +2013,Fla,18,F,0.00030802402587401816,0.0 +2013,Fla,19,M,0.0005078576869903789,0.0 +2013,Fla,19,F,0.00017477934108188408,0.0 +2013,Fla,20,M,0.0006021787923578037,0.0011650485436893213 +2013,Fla,20,F,0.00017072615524698392,0.0 +2013,Fla,21,M,0.0005138746145940392,0.0003608805485384338 +2013,Fla,21,F,0.0003125,0.0 +2013,Fla,22,M,0.0006574441857279824,0.0006583278472679394 +2013,Fla,22,F,0.0001716198049254884,0.0 +2013,Fla,23,M,0.0007109543851666478,0.0005980861244019139 +2013,Fla,23,F,0.0002968856693287415,0.0 +2013,Fla,24,M,0.0005505650536076499,0.0007932310946589106 +2013,Fla,24,F,0.00023955681988321607,0.0 +2013,Fla,25,M,0.0007040807345908997,0.00125250501002004 +2013,Fla,25,F,0.0003065134099616858,0.0002058036633052068 +2013,Fla,26,M,0.0006191950464396285,0.0004673989249824728 +2013,Fla,26,F,0.0004288296014947775,0.0001951981260979895 +2013,Fla,27,M,0.0008849557522123895,0.0004268032437046522 +2013,Fla,27,F,0.00015568563955660732,0.0 +2013,Fla,28,M,0.001043654580152672,0.0010366991499066972 +2013,Fla,28,F,0.0003958707634215415,0.0 +2013,Fla,29,M,0.0006989341254586755,0.00020354162426216158 +2013,Fla,29,F,0.0005585442572831231,0.000384172109104879 +2013,Fla,30,M,0.000820855387924934,0.0009777082518576457 +2013,Fla,30,F,0.0001737921445950643,0.0007693787266782072 +2013,Fla,31,M,0.0005197789571592713,0.0004028197381671702 +2013,Fla,31,F,0.0003383808476440234,0.0003980891719745223 +2013,Fla,32,M,0.0008305877792851407,0.0003828483920367535 +2013,Fla,32,F,0.00030461632189637513,0.0001947798987144527 +2013,Fla,33,M,0.0006805869381754826,0.0003971405877680699 +2013,Fla,33,F,0.0003068682698209005,0.0 +2013,Fla,34,M,0.0008618532625316245,0.0004043671653861706 +2013,Fla,34,F,0.0003901568988100215,0.0006231823847112587 +2013,Fla,35,M,0.001216682700469696,0.0004037141703673799 +2013,Fla,35,F,0.00045391358620102697,0.0 +2013,Fla,36,M,0.0008608815426997245,0.0008161599673536013 +2013,Fla,36,F,0.0005528720246755515,0.0004434589800443459 +2013,Fla,37,M,0.0009981211836542978,0.0 +2013,Fla,37,F,0.0007145196344041204,0.0006612298875909191 +2013,Fla,38,M,0.000903010977227192,0.0012626262626262634 +2013,Fla,38,F,0.0008251764170270888,0.0006997900629811056 +2013,Fla,39,M,0.0011684147600673881,0.0015158077089649196 +2013,Fla,39,F,0.0007469912851016737,0.0004769854519437157 +2013,Fla,40,M,0.001456550576117773,0.0006369426751592356 +2013,Fla,40,F,0.000864281598659054,0.0002414292612264607 +2013,Fla,41,M,0.001225674120766422,0.000649772579597141 +2013,Fla,41,F,0.0009496438835436713,0.0007479431563201198 +2013,Fla,42,M,0.001431205123229187,0.00251414204902577 +2013,Fla,42,F,0.0009559057820044607,0.0007290400972053463 +2013,Fla,43,M,0.001650245109935446,0.0015398152221733393 +2013,Fla,43,F,0.000884933998672599,0.0007739938080495358 +2013,Fla,44,M,0.001493615996145507,0.0017722640673460352 +2013,Fla,44,F,0.0010720725110862036,0.00130821559392988 +2013,Fla,45,M,0.001888464049239952,0.0009594627008875028 +2013,Fla,45,F,0.001298888728532256,0.001158748551564311 +2013,Fla,46,M,0.002534796876768134,0.002141837220371252 +2013,Fla,46,F,0.0018423416161941829,0.0011782032400589099 +2013,Fla,47,M,0.001974376974376975,0.001219512195121951 +2013,Fla,47,F,0.001391132651229582,0.001217285453438832 +2013,Fla,48,M,0.002773602083377443,0.0020320040640081282 +2013,Fla,48,F,0.001587608075347021,0.0009603072983354674 +2013,Fla,49,M,0.00254246341202863,0.0016064257028112448 +2013,Fla,49,F,0.002456201365039343,0.001373154823206317 +2013,Fla,50,M,0.0029215720221606647,0.002290950744558992 +2013,Fla,50,F,0.002100793878950045,0.00181422351233672 +2013,Fla,51,M,0.003278255703944908,0.003376304481276857 +2013,Fla,51,F,0.0020703477743761424,0.001942501942501943 +2013,Fla,52,M,0.0035219166404953117,0.003758221108675227 +2013,Fla,52,F,0.002235570409177129,0.003126221180148496 +2013,Fla,53,M,0.00455829052987348,0.003050847457627119 +2013,Fla,53,F,0.002663920664413154,0.002967359050445104 +2013,Fla,54,M,0.004960069167937021,0.005462615227039946 +2013,Fla,54,F,0.003273850693964126,0.0037400654511453952 +2013,Fla,55,M,0.005036906364607029,0.0055928411633109605 +2013,Fla,55,F,0.003687869961477027,0.001474926253687316 +2013,Fla,56,M,0.006349130288945326,0.004352987732489117 +2013,Fla,56,F,0.004009355162044771,0.004102564102564103 +2013,Fla,57,M,0.006434723037776473,0.005356407086938607 +2013,Fla,57,F,0.004336660529121039,0.005263157894736842 +2013,Fla,58,M,0.007283321194464677,0.0068995256576110395 +2013,Fla,58,F,0.00414440505317821,0.003829321663019694 +2013,Fla,59,M,0.00877577885037297,0.006069094304388422 +2013,Fla,59,F,0.00464561002828891,0.00351288056206089 +2013,Fla,60,M,0.008771929824561403,0.00537371763556424 +2013,Fla,60,F,0.0053192883159080785,0.001841620626151013 +2013,Fla,61,M,0.01036012454192269,0.00847457627118644 +2013,Fla,61,F,0.005689589146014552,0.005972130059721301 +2013,Fla,62,M,0.01028032133026235,0.008298755186721992 +2013,Fla,62,F,0.006182847407325986,0.006105006105006105 +2013,Fla,63,M,0.0109382047812359,0.007038712921065862 +2013,Fla,63,F,0.005743601182178108,0.007092198581560284 +2013,Fla,64,M,0.01131118582255399,0.01365546218487395 +2013,Fla,64,F,0.006652313127967318,0.007387508394895903 +2013,Fla,65,M,0.0136044513065517,0.01538461538461539 +2013,Fla,65,F,0.008000449148022346,0.0076282940360610264 +2013,Fla,66,M,0.01497590084920817,0.01068616422947132 +2013,Fla,66,F,0.009214543436025534,0.0 +2013,Fla,67,M,0.0160807655628268,0.015078821110349559 +2013,Fla,67,F,0.008570363929946591,0.007725321888412017 +2013,Fla,68,M,0.01832959828745359,0.01119664100769769 +2013,Fla,68,F,0.009777414486921527,0.006420545746388443 +2013,Fla,69,M,0.01887798634812287,0.01870503597122302 +2013,Fla,69,F,0.01046706823343537,0.006475485661424607 +2013,Fla,70,M,0.021562564419707282,0.01765650080256822 +2013,Fla,70,F,0.0117950468388516,0.01305970149253731 +2013,Fla,71,M,0.02428204529535373,0.01936619718309859 +2013,Fla,71,F,0.01130438409877779,0.00967741935483871 +2013,Fla,72,M,0.02628502143506691,0.02212389380530974 +2013,Fla,72,F,0.01468584405753218,0.02144772117962467 +2013,Fla,73,M,0.03069838833461243,0.029665071770334926 +2013,Fla,73,F,0.014497732582108009,0.01630434782608696 +2013,Fla,74,M,0.03009793773389601,0.024096385542168683 +2013,Fla,74,F,0.01699417634437898,0.02351623740201568 +2013,Fla,75,M,0.03542876378019018,0.026966292134831458 +2013,Fla,75,F,0.01851521529734936,0.02317073170731708 +2013,Fla,76,M,0.03822206062809617,0.02905569007263923 +2013,Fla,76,F,0.02281874238452166,0.01024327784891165 +2013,Fla,77,M,0.04491288040639985,0.04615384615384616 +2013,Fla,77,F,0.02458521870286576,0.01971830985915493 +2013,Fla,78,M,0.04903694968553459,0.057224606580829764 +2013,Fla,78,F,0.02708530357480613,0.037604456824512536 +2013,Fla,79,M,0.05228826384177843,0.06156156156156156 +2013,Fla,79,F,0.03162486368593239,0.03636363636363636 +2013,Fla,80,M,0.06335681905074007,0.07457627118644068 +2013,Fla,80,F,0.03619121347009871,0.04114490161001789 +2013,Fla,81,M,0.06970352610958422,0.06591337099811675 +2013,Fla,81,F,0.04565016289265173,0.05442176870748298 +2013,Fla,82,M,0.07640089657380722,0.05567451820128479 +2013,Fla,82,F,0.04933384412378155,0.04483430799220273 +2013,Fla,83,M,0.08717319635053285,0.09259259259259256 +2013,Fla,83,F,0.05695990825249678,0.045685279187817264 +2013,Fla,84,M,0.102301346070343,0.08385093167701864 +2013,Fla,84,F,0.06617185866610914,0.07035175879396985 +2013,Fla,85,M,0.1124601910828025,0.1384615384615385 +2013,Fla,85,F,0.07964395834545349,0.0778816199376947 +2013,Fla,86,M,0.1319054307116105,0.09547738693467336 +2013,Fla,86,F,0.08962085905025823,0.1140939597315436 +2013,Fla,87,M,0.1393109061313077,0.08333333333333333 +2013,Fla,87,F,0.1014625874372924,0.1365461847389558 +2013,Fla,88,M,0.1632720105124836,0.1486486486486487 +2013,Fla,88,F,0.1172607128554265,0.1277533039647577 +2013,Fla,89,M,0.1653386454183267,0.2090909090909091 +2013,Fla,89,F,0.1371648916636063,0.1374407582938389 +2013,Fla,90,M,0.1965392561983471,0.163265306122449 +2013,Fla,90,F,0.1506584922797457,0.1428571428571429 +2013,Fla,91,M,0.2100757326308858,0.273972602739726 +2013,Fla,91,F,0.16876097824618302,0.1588785046728972 +2013,Fla,92,M,0.2339935513588209,0.2181818181818182 +2013,Fla,92,F,0.18239946155140505,0.2 +2013,Fla,93,M,0.2876142975893599,0.1724137931034483 +2013,Fla,93,F,0.1994963626189144,0.22 +2013,Fla,94,M,0.260096930533118,0.1904761904761905 +2013,Fla,94,F,0.2425488180883865,0.25 +2013,Fla,95,M,0.3138297872340426,0.3571428571428572 +2013,Fla,95,F,0.2526464361326747,0.2631578947368421 +2013,Fla,96,M,0.3671641791044777,0.0 +2013,Fla,96,F,0.272655634357762,0.25 +2013,Fla,97,M,0.3370786516853933,0.4285714285714286 +2013,Fla,97,F,0.3032863849765258,0.1304347826086957 +2013,Fla,98,M,0.4022346368715084,0.0 +2013,Fla,98,F,0.30875,0.2352941176470588 +2013,Fla,99,M,0.4672897196261682,0.25 +2013,Fla,99,F,0.3421985815602837,0.3333333333333333 +2013,Fla,100,M,0.4516129032258064,1.0 +2013,Fla,100,F,0.3563829787234043,0.125 +2013,Fla,101,M,0.4318181818181818,1.0 +2013,Fla,101,F,0.3966942148760331,0.25 +2013,Fla,102,M,0.4166666666666667,0.0 +2013,Fla,102,F,0.459016393442623,0.0 +2013,Fla,103,M,0.5454545454545454,0.0 +2013,Fla,103,F,0.3846153846153847,0.0 +2013,Fla,104,M,0.6,0.0 +2013,Fla,104,F,0.5116279069767442,0.0 +2013,Fla,105,M,1.0,0.0 +2013,Fla,105,F,0.5384615384615384,0.0 +2013,Fla,106,M,0.0,0.0 +2013,Fla,106,F,0.3333333333333333,0.0 +2013,Fla,107,M,0.0,0.0 +2013,Fla,107,F,0.5714285714285714,0.0 +2013,Fla,108,M,0.0,0.0 +2013,Fla,108,F,0.0,0.0 +2013,Fla,109,M,0.0,0.0 +2013,Fla,109,F,1.0,0.0 +2013,Fla,110,M,0.0,0.0 +2013,Fla,110,F,0.0,0.0 +2013,Fla,111,M,0.0,0.0 +2013,Fla,111,F,0.0,0.0 +2013,Fla,112,M,0.0,0.0 +2013,Fla,112,F,0.0,0.0 +2013,Fla,113,M,0.0,0.0 +2013,Fla,113,F,0.0,0.0 +2013,Fla,114,M,0.0,0.0 +2013,Fla,114,F,0.0,0.0 +2013,Fla,115,M,0.0,0.0 +2013,Fla,115,F,0.0,0.0 +2013,Fla,116,M,0.0,0.0 +2013,Fla,116,F,0.0,0.0 +2013,Fla,117,M,0.0,0.0 +2013,Fla,117,F,0.0,0.0 +2013,Fla,118,M,0.0,0.0 +2013,Fla,118,F,0.0,0.0 +2013,Fla,119,M,0.0,0.0 +2013,Fla,119,F,0.0,0.0 +2013,Fla,120,M,0.0,0.0 +2013,Fla,120,F,0.0,0.0 +2013,Wal,0,M,0.0007906388361796331,0.000731528895391368 +2013,Wal,0,F,0.0008165931732810714,0.0007501875468867218 +2013,Wal,1,M,0.00030994937493542717,0.001361470388019061 +2013,Wal,1,F,0.0002149151085321298,0.0 +2013,Wal,2,M,0.0001999200319872051,0.0 +2013,Wal,2,F,0.000157076286716582,0.0 +2013,Wal,3,M,4.987779939149085e-05,0.0 +2013,Wal,3,F,0.000154822727976467,0.0 +2013,Wal,4,M,0.00014669209329617132,0.0 +2013,Wal,4,F,0.0001037290596960739,0.0 +2013,Wal,5,M,9.84348853233586e-05,0.0 +2013,Wal,5,F,0.0001558846453624318,0.0 +2013,Wal,6,M,0.000196589177765764,0.0 +2013,Wal,6,F,5.08440105755542e-05,0.0 +2013,Wal,7,M,9.934926233172718e-05,0.0 +2013,Wal,7,F,5.166089786640492e-05,0.0 +2013,Wal,8,M,4.981568197668626e-05,0.0 +2013,Wal,8,F,0.00010463534581981792,0.0 +2013,Wal,9,M,0.0,0.0 +2013,Wal,9,F,0.0,0.0008680555555555555 +2013,Wal,10,M,5.01353654868144e-05,0.0 +2013,Wal,10,F,5.2770448548812674e-05,0.0 +2013,Wal,11,M,9.733307377846992e-05,0.0 +2013,Wal,11,F,0.0,0.0 +2013,Wal,12,M,4.773041859577109e-05,0.0008230452674897119 +2013,Wal,12,F,0.0,0.0 +2013,Wal,13,M,0.0002452543287389023,0.0 +2013,Wal,13,F,0.0001548946716232962,0.0 +2013,Wal,14,M,0.0002448819668919581,0.0 +2013,Wal,14,F,0.0001024275325207416,0.0 +2013,Wal,15,M,4.893804443574435e-05,0.0 +2013,Wal,15,F,0.0001530299938788003,0.0 +2013,Wal,16,M,0.0002426477724934485,0.0 +2013,Wal,16,F,0.0002529340348037232,0.0 +2013,Wal,17,M,0.0004954910316123278,0.0 +2013,Wal,17,F,0.0003624689312344657,0.0007704160246533128 +2013,Wal,18,M,0.0006876903428627568,0.0 +2013,Wal,18,F,0.00036006378272722595,0.0 +2013,Wal,19,M,0.0007573247503194964,0.0 +2013,Wal,19,F,0.0001998001998001998,0.0 +2013,Wal,20,M,0.0008171789167839468,0.0006561679790026247 +2013,Wal,20,F,0.0002831791580139702,0.0 +2013,Wal,21,M,0.0008895610016456879,0.0 +2013,Wal,21,F,0.0003232808386828615,0.0005387931034482759 +2013,Wal,22,M,0.000499523182416784,0.001119820828667413 +2013,Wal,22,F,9.432182607055272e-05,0.0 +2013,Wal,23,M,0.000411748558880044,0.0005482456140350877 +2013,Wal,23,F,0.0004286326618088298,0.0 +2013,Wal,24,M,0.000980163360560093,0.0009713453132588633 +2013,Wal,24,F,0.0002442241000341914,0.0 +2013,Wal,25,M,0.0007327438815885888,0.0 +2013,Wal,25,F,0.0005107513151846366,0.0003862495171881035 +2013,Wal,26,M,0.000691358024691358,0.0 +2013,Wal,26,F,0.000622245268343272,0.0 +2013,Wal,27,M,0.0009924780610112828,0.0008223684210526315 +2013,Wal,27,F,0.00010708931248661379,0.000369139904023625 +2013,Wal,28,M,0.001055074910318633,0.0 +2013,Wal,28,F,0.00037811267757791815,0.0 +2013,Wal,29,M,0.0007979147827012075,0.001510574018126888 +2013,Wal,29,F,0.0004995004995004995,0.0 +2013,Wal,30,M,0.0010024269283528536,0.000361794500723589 +2013,Wal,30,F,0.0007485029940119763,0.0006763611768684477 +2013,Wal,31,M,0.001146131805157593,0.0 +2013,Wal,31,F,0.000362844702467344,0.0003425830763960261 +2013,Wal,32,M,0.0008787800465236495,0.000682360968952576 +2013,Wal,32,F,0.0005688282138794084,0.0 +2013,Wal,33,M,0.001304597401241977,0.002416292716603383 +2013,Wal,33,F,0.0004266666666666667,0.0 +2013,Wal,34,M,0.0015349600381093528,0.001643115346697338 +2013,Wal,34,F,0.000266354144470488,0.0006889424733034793 +2013,Wal,35,M,0.001471206389239176,0.0 +2013,Wal,35,F,0.0007358738501971091,0.0003531073446327684 +2013,Wal,36,M,0.001186668042513673,0.001081470800288392 +2013,Wal,36,F,0.0006151637873583843,0.0003604902667627974 +2013,Wal,37,M,0.002001950618551409,0.00103057368601855 +2013,Wal,37,F,0.0008607159131183231,0.0007135212272565109 +2013,Wal,38,M,0.00132808657156911,0.001626016260162602 +2013,Wal,38,F,0.001379854129706288,0.0006861063464837049 +2013,Wal,39,M,0.00212234117813517,0.0009219422249539028 +2013,Wal,39,F,0.0012711265947930892,0.001358695652173913 +2013,Wal,40,M,0.002103145574250183,0.0012198841110094539 +2013,Wal,40,F,0.0008178844056706652,0.001319261213720317 +2013,Wal,41,M,0.001620964473861948,0.000605143721633888 +2013,Wal,41,F,0.001024864094109259,0.000700770847932726 +2013,Wal,42,M,0.002693694927635484,0.002140018343014369 +2013,Wal,42,F,0.0014209102993078787,0.0 +2013,Wal,43,M,0.002914103335029372,0.003105590062111801 +2013,Wal,43,F,0.0019210538352467642,0.0010504201680672268 +2013,Wal,44,M,0.002924666257842351,0.0018814675446848551 +2013,Wal,44,F,0.0017969865917154308,0.0006887052341597796 +2013,Wal,45,M,0.003058529125538718,0.001558117793705204 +2013,Wal,45,F,0.001512235358812208,0.001053740779768177 +2013,Wal,46,M,0.0031945965680905447,0.002857959416976279 +2013,Wal,46,F,0.0024244601086517307,0.00168123739071957 +2013,Wal,47,M,0.0031755832929034537,0.0032286469034341057 +2013,Wal,47,F,0.002089318359885088,0.0014099400775467038 +2013,Wal,48,M,0.004637581587083476,0.00245398773006135 +2013,Wal,48,F,0.002012831802742483,0.001066098081023454 +2013,Wal,49,M,0.004873551106427819,0.0037301834006838674 +2013,Wal,49,F,0.002762078782985595,0.0018301610541727675 +2013,Wal,50,M,0.0043070227138776816,0.0025510204081632647 +2013,Wal,50,F,0.003264275766016713,0.001218026796589525 +2013,Wal,51,M,0.006180799501978746,0.0026289845547157412 +2013,Wal,51,F,0.003419534088480445,0.001602564102564103 +2013,Wal,52,M,0.006796941376380629,0.0049230769230769215 +2013,Wal,52,F,0.003699512534818942,0.003654080389768575 +2013,Wal,53,M,0.007153140183552276,0.004674457429048414 +2013,Wal,53,F,0.00356022717640078,0.0034379028792436623 +2013,Wal,54,M,0.008592811604915459,0.0023411371237458192 +2013,Wal,54,F,0.004325259515570936,0.0026246719160104987 +2013,Wal,55,M,0.00825670857571777,0.005521048999309869 +2013,Wal,55,F,0.004299454811400204,0.002256317689530686 +2013,Wal,56,M,0.00958327283287353,0.008535336292249916 +2013,Wal,56,F,0.0052693208430913355,0.004572473708276178 +2013,Wal,57,M,0.009948288598867271,0.004252303330970943 +2013,Wal,57,F,0.005521361332367849,0.004229323308270677 +2013,Wal,58,M,0.01047250347429025,0.00595459620394492 +2013,Wal,58,F,0.007272057808257007,0.005777563793933558 +2013,Wal,59,M,0.01389239706996717,0.006581494386372435 +2013,Wal,59,F,0.006103572937696605,0.004509018036072144 +2013,Wal,60,M,0.01356619366910962,0.0121283255086072 +2013,Wal,60,F,0.006402599264178891,0.00359527478171546 +2013,Wal,61,M,0.013036685880515,0.014540922309929382 +2013,Wal,61,F,0.007717481561080449,0.006263048016701462 +2013,Wal,62,M,0.014837892068856268,0.01232469188270293 +2013,Wal,62,F,0.008904980917898033,0.005096839959225281 +2013,Wal,63,M,0.015267990604313482,0.012987012987012991 +2013,Wal,63,F,0.008078335373317012,0.006207674943566591 +2013,Wal,64,M,0.01862630966239814,0.01714285714285714 +2013,Wal,64,F,0.00927126867464092,0.005200208008320333 +2013,Wal,65,M,0.02109909037084881,0.014979573309123919 +2013,Wal,65,F,0.009427050261319786,0.008576329331046312 +2013,Wal,66,M,0.02079490189501929,0.01723312589755864 +2013,Wal,66,F,0.01004304160688666,0.005555555555555557 +2013,Wal,67,M,0.021374396690416003,0.01958307012002527 +2013,Wal,67,F,0.01159156030216202,0.006517016654598118 +2013,Wal,68,M,0.02428771602055115,0.02302426882389546 +2013,Wal,68,F,0.01118628173353875,0.006983240223463687 +2013,Wal,69,M,0.02739141564979947,0.018245614035087718 +2013,Wal,69,F,0.01458542894093979,0.008620689655172414 +2013,Wal,70,M,0.02911279976315011,0.02773497688751926 +2013,Wal,70,F,0.01273519020622792,0.01211631663974152 +2013,Wal,71,M,0.02643603133159269,0.02272727272727273 +2013,Wal,71,F,0.01805469510576157,0.01192504258943782 +2013,Wal,72,M,0.03210463733650417,0.032 +2013,Wal,72,F,0.018105296593345508,0.01866475233309404 +2013,Wal,73,M,0.03669467787114846,0.029457364341085267 +2013,Wal,73,F,0.02041411490230388,0.01964912280701755 +2013,Wal,74,M,0.04048426150121066,0.0463871543264942 +2013,Wal,74,F,0.021873860736419986,0.02424687729610581 +2013,Wal,75,M,0.0440949737897009,0.04749103942652329 +2013,Wal,75,F,0.02646621251272414,0.01812450748620961 +2013,Wal,76,M,0.04825236315673775,0.05374280230326296 +2013,Wal,76,F,0.02589435104772528,0.03362690152121698 +2013,Wal,77,M,0.052619242939177316,0.05572441742654509 +2013,Wal,77,F,0.02700247729149463,0.031201248049922 +2013,Wal,78,M,0.05887210948560642,0.06399132321041215 +2013,Wal,78,F,0.0342264335892828,0.030708661417322838 +2013,Wal,79,M,0.05883819496384941,0.06395348837209303 +2013,Wal,79,F,0.04127249895353705,0.03752039151712888 +2013,Wal,80,M,0.06822513022487613,0.06296296296296296 +2013,Wal,80,F,0.04372533543804262,0.04614019520851819 +2013,Wal,81,M,0.07576974564926373,0.07397260273972603 +2013,Wal,81,F,0.052362811056172485,0.04235090751944685 +2013,Wal,82,M,0.08154823459890677,0.08194444444444443 +2013,Wal,82,F,0.05880373517287794,0.04607046070460705 +2013,Wal,83,M,0.0979020979020979,0.1025641025641026 +2013,Wal,83,F,0.06965639921355678,0.05852674066599395 +2013,Wal,84,M,0.1044510385756677,0.1211538461538462 +2013,Wal,84,F,0.07537840565085772,0.09143518518518516 +2013,Wal,85,M,0.1257620230300294,0.1380753138075314 +2013,Wal,85,F,0.09056108498304714,0.0780885780885781 +2013,Wal,86,M,0.1437565582371459,0.1421686746987952 +2013,Wal,86,F,0.1030007144558228,0.1051964512040558 +2013,Wal,87,M,0.1472592592592593,0.15625 +2013,Wal,87,F,0.1179251309569439,0.1016713091922006 +2013,Wal,88,M,0.1774553571428572,0.2252559726962458 +2013,Wal,88,F,0.1285923753665689,0.130794701986755 +2013,Wal,89,M,0.1881970260223049,0.2477477477477478 +2013,Wal,89,F,0.1498348687641231,0.1666666666666667 +2013,Wal,90,M,0.1837581505631298,0.2569444444444444 +2013,Wal,90,F,0.1573796684641502,0.1651376146788991 +2013,Wal,91,M,0.2243125904486252,0.1984126984126984 +2013,Wal,91,F,0.1804935370152762,0.1613924050632912 +2013,Wal,92,M,0.2586912065439673,0.1805555555555556 +2013,Wal,92,F,0.2018294482148126,0.1875 +2013,Wal,93,M,0.2552447552447553,0.2608695652173913 +2013,Wal,93,F,0.2291145572786394,0.2012578616352201 +2013,Wal,94,M,0.2744360902255639,0.1428571428571429 +2013,Wal,94,F,0.2617702448210923,0.24 +2013,Wal,95,M,0.3529411764705883,0.4444444444444444 +2013,Wal,95,F,0.2497027348394768,0.3090909090909091 +2013,Wal,96,M,0.3776223776223776,0.4285714285714286 +2013,Wal,96,F,0.2591414944356121,0.4150943396226416 +2013,Wal,97,M,0.27,0.5 +2013,Wal,97,F,0.2998065764023211,0.2820512820512821 +2013,Wal,98,M,0.3766233766233767,0.4444444444444444 +2013,Wal,98,F,0.3401639344262295,0.3333333333333333 +2013,Wal,99,M,0.3166666666666667,0.5 +2013,Wal,99,F,0.318936877076412,0.3125 +2013,Wal,100,M,0.4285714285714286,0.1666666666666667 +2013,Wal,100,F,0.3535911602209945,0.5454545454545454 +2013,Wal,101,M,0.625,0.0 +2013,Wal,101,F,0.3858267716535433,0.3333333333333333 +2013,Wal,102,M,0.4,0.0 +2013,Wal,102,F,0.4615384615384616,0.6666666666666666 +2013,Wal,103,M,0.0,0.0 +2013,Wal,103,F,0.4814814814814815,0.0 +2013,Wal,104,M,1.0,0.0 +2013,Wal,104,F,0.4736842105263158,0.0 +2013,Wal,105,M,0.0,0.0 +2013,Wal,105,F,0.5,0.0 +2013,Wal,106,M,0.0,0.0 +2013,Wal,106,F,0.8,0.0 +2013,Wal,107,M,0.0,0.0 +2013,Wal,107,F,0.5,0.0 +2013,Wal,108,M,0.0,0.0 +2013,Wal,108,F,0.0,0.0 +2013,Wal,109,M,0.0,0.0 +2013,Wal,109,F,0.0,0.0 +2013,Wal,110,M,0.0,0.0 +2013,Wal,110,F,0.0,0.0 +2013,Wal,111,M,0.0,0.0 +2013,Wal,111,F,0.0,0.0 +2013,Wal,112,M,0.0,0.0 +2013,Wal,112,F,0.0,0.0 +2013,Wal,113,M,0.0,0.0 +2013,Wal,113,F,0.0,0.0 +2013,Wal,114,M,0.0,0.0 +2013,Wal,114,F,0.0,0.0 +2013,Wal,115,M,0.0,0.0 +2013,Wal,115,F,0.0,0.0 +2013,Wal,116,M,0.0,0.0 +2013,Wal,116,F,0.0,0.0 +2013,Wal,117,M,0.0,0.0 +2013,Wal,117,F,0.0,0.0 +2013,Wal,118,M,0.0,0.0 +2013,Wal,118,F,0.0,0.0 +2013,Wal,119,M,0.0,0.0 +2013,Wal,119,F,0.0,0.0 +2013,Wal,120,M,0.0,0.0 +2013,Wal,120,F,0.0,0.0 +2014,BruCap,0,M,0.0007821054278116692,0.0017029972752043599 +2014,BruCap,0,F,0.0004991680532445924,0.00037453183520599247 +2014,BruCap,1,M,0.0001554001554001554,0.0 +2014,BruCap,1,F,0.000162813415825464,0.0014367816091954018 +2014,BruCap,2,M,0.0001586042823156225,0.00037023324694557584 +2014,BruCap,2,F,0.00016641704110500918,0.0 +2014,BruCap,3,M,0.0,0.0 +2014,BruCap,3,F,0.0003317299718029524,0.0 +2014,BruCap,4,M,0.0001596933886937081,0.0 +2014,BruCap,4,F,0.0001679825298168991,0.0 +2014,BruCap,5,M,0.0,0.0 +2014,BruCap,5,F,0.0003511852502194908,0.0 +2014,BruCap,6,M,0.0001686056314280897,0.0 +2014,BruCap,6,F,0.0,0.0 +2014,BruCap,7,M,0.0003441748408191362,0.0 +2014,BruCap,7,F,0.0,0.0 +2014,BruCap,8,M,0.0,0.0 +2014,BruCap,8,F,0.00018825301204819284,0.0 +2014,BruCap,9,M,0.0,0.0005770340450086555 +2014,BruCap,9,F,0.0,0.0 +2014,BruCap,10,M,0.00019588638589618015,0.0 +2014,BruCap,10,F,0.00020296326364927948,0.0 +2014,BruCap,11,M,0.0,0.0 +2014,BruCap,11,F,0.0002079434393844874,0.0 +2014,BruCap,12,M,0.0002021835826930853,0.0 +2014,BruCap,12,F,0.0004109307581672488,0.0 +2014,BruCap,13,M,0.0006108735491753207,0.0 +2014,BruCap,13,F,0.0,0.0 +2014,BruCap,14,M,0.0006176652254478072,0.00065359477124183 +2014,BruCap,14,F,0.000216076058772688,0.0006896551724137933 +2014,BruCap,15,M,0.0004337453914552158,0.0 +2014,BruCap,15,F,0.0,0.0006802721088435374 +2014,BruCap,16,M,0.0004161464835622138,0.0006854009595613432 +2014,BruCap,16,F,0.00044632894443204636,0.0 +2014,BruCap,17,M,0.000213857998289136,0.0006863417982155112 +2014,BruCap,17,F,0.0,0.0006770480704129992 +2014,BruCap,18,M,0.001077354018530489,0.0006377551020408162 +2014,BruCap,18,F,0.0002254283137962128,0.0 +2014,BruCap,19,M,0.00041493775933609963,0.0 +2014,BruCap,19,F,0.0,0.0 +2014,BruCap,20,M,0.0006325110689437065,0.0004916420845624387 +2014,BruCap,20,F,0.00043290043290043285,0.0 +2014,BruCap,21,M,0.0008130081300813008,0.001403837154890033 +2014,BruCap,21,F,0.0002081598667776853,0.0 +2014,BruCap,22,M,0.0004050222762251924,0.0 +2014,BruCap,22,F,0.0,0.0003255208333333333 +2014,BruCap,23,M,0.0003971405877680699,0.0003703703703703704 +2014,BruCap,23,F,0.0,0.0 +2014,BruCap,24,M,0.0001937608990505716,0.0 +2014,BruCap,24,F,0.00018653236336504386,0.0 +2014,BruCap,25,M,0.00018301610541727667,0.0003027550711474417 +2014,BruCap,25,F,0.0001789869339538214,0.0 +2014,BruCap,26,M,0.0009293680297397768,0.0002724053391446473 +2014,BruCap,26,F,0.00034891835310537326,0.0 +2014,BruCap,27,M,0.0005492493592090809,0.0005058168942842691 +2014,BruCap,27,F,0.0005174197999310106,0.0002063131834124201 +2014,BruCap,28,M,0.0005553498704183637,0.0 +2014,BruCap,28,F,0.000364963503649635,0.0001964250638381458 +2014,BruCap,29,M,0.0007425283088917764,0.0 +2014,BruCap,29,F,0.0001747946163258172,0.0 +2014,BruCap,30,M,0.0009444654325651682,0.0004379242391066346 +2014,BruCap,30,F,0.0005520794994479205,0.0003992015968063872 +2014,BruCap,31,M,0.000187793427230047,0.0 +2014,BruCap,31,F,0.000541809644211667,0.0003873716831299632 +2014,BruCap,32,M,0.000744047619047619,0.0002116850127011008 +2014,BruCap,32,F,0.000180766449746927,0.0 +2014,BruCap,33,M,0.001294378698224852,0.0009926543577526306 +2014,BruCap,33,F,0.0003560619547801318,0.0002002402883460152 +2014,BruCap,34,M,0.001670998886000743,0.0002044989775051125 +2014,BruCap,34,F,0.0003779289493575208,0.0 +2014,BruCap,35,M,0.0007555723460521345,0.0002087682672233821 +2014,BruCap,35,F,0.0,0.000437636761487965 +2014,BruCap,36,M,0.0005751533742331289,0.0010590976488032199 +2014,BruCap,36,F,0.001153624303018651,0.00023468669326449188 +2014,BruCap,37,M,0.0005847953216374268,0.0008424599831508003 +2014,BruCap,37,F,0.0001991238550378335,0.00118962645729241 +2014,BruCap,38,M,0.0005877742946708464,0.0008976660682226213 +2014,BruCap,38,F,0.001258917331095258,0.000510986203372509 +2014,BruCap,39,M,0.001566784175479828,0.0002262955419778231 +2014,BruCap,39,F,0.00020916126333403058,0.00026075619295958284 +2014,BruCap,40,M,0.0013666536509176108,0.001421464108031272 +2014,BruCap,40,F,0.0006142506142506142,0.0002846569883290635 +2014,BruCap,41,M,0.0009867771857114665,0.001000750562922192 +2014,BruCap,41,F,0.001026483268322726,0.0008505812305075135 +2014,BruCap,42,M,0.00273224043715847,0.00026567481402763017 +2014,BruCap,42,F,0.001254180602006689,0.0003017501508750755 +2014,BruCap,43,M,0.002099637335369345,0.001298701298701299 +2014,BruCap,43,F,0.0008032128514056224,0.0006277463904582549 +2014,BruCap,44,M,0.001770607908715326,0.001614639397201292 +2014,BruCap,44,F,0.001875390706397166,0.0003123048094940662 +2014,BruCap,45,M,0.00320962888665998,0.0008248556502612042 +2014,BruCap,45,F,0.0002113271344040575,0.001337792642140468 +2014,BruCap,46,M,0.0031374189500104573,0.002390914524805738 +2014,BruCap,46,F,0.0006587615283267457,0.0010972933430870519 +2014,BruCap,47,M,0.0025078369905956123,0.002182725288431556 +2014,BruCap,47,F,0.0021101498206372647,0.001912045889101339 +2014,BruCap,48,M,0.003223856538384042,0.001022843504943744 +2014,BruCap,48,F,0.0028747433264887053,0.0003960396039603961 +2014,BruCap,49,M,0.002441505595116989,0.004475043029259897 +2014,BruCap,49,F,0.002673246966892865,0.0023952095808383238 +2014,BruCap,50,M,0.004232804232804233,0.001845699520118125 +2014,BruCap,50,F,0.003341687552213868,0.002554278416347382 +2014,BruCap,51,M,0.004339336081579518,0.004752475247524752 +2014,BruCap,51,F,0.0025521054870267968,0.001806684733514002 +2014,BruCap,52,M,0.005387205387205387,0.002887788778877888 +2014,BruCap,52,F,0.003805496828752643,0.0018726591760299628 +2014,BruCap,53,M,0.005278205410160546,0.002232142857142857 +2014,BruCap,53,F,0.0035978412952228657,0.00288322921672273 +2014,BruCap,54,M,0.00631626438078051,0.00241196333815726 +2014,BruCap,54,F,0.004612159329140462,0.002472799208704253 +2014,BruCap,55,M,0.007459207459207459,0.004048582995951417 +2014,BruCap,55,F,0.004026276753549481,0.0021893814997263287 +2014,BruCap,56,M,0.009739469198928655,0.008561643835616438 +2014,BruCap,56,F,0.0045563028856584935,0.002347417840375587 +2014,BruCap,57,M,0.009813789632611978,0.005518763796909493 +2014,BruCap,57,F,0.004097476816907485,0.00243605359317905 +2014,BruCap,58,M,0.008485150985774894,0.0043076923076923075 +2014,BruCap,58,F,0.006181015452538631,0.007398273736128238 +2014,BruCap,59,M,0.01129073646394663,0.004807692307692308 +2014,BruCap,59,F,0.004240124972104441,0.00205620287868403 +2014,BruCap,60,M,0.0133401744484351,0.009767092411720512 +2014,BruCap,60,F,0.003389064618165387,0.006731488406881077 +2014,BruCap,61,M,0.01053463260468791,0.00677710843373494 +2014,BruCap,61,F,0.006925207756232687,0.0014981273408239699 +2014,BruCap,62,M,0.011133314302026829,0.00985663082437276 +2014,BruCap,62,F,0.007926678226405746,0.008488964346349746 +2014,BruCap,63,M,0.01212633953750705,0.013322231473771859 +2014,BruCap,63,F,0.005792903692976104,0.0008163265306122449 +2014,BruCap,64,M,0.01543942992874109,0.01588785046728972 +2014,BruCap,64,F,0.009987515605493134,0.003700277520814061 +2014,BruCap,65,M,0.01556301495270064,0.009699321047526674 +2014,BruCap,65,F,0.01262945188178833,0.007858546168958742 +2014,BruCap,66,M,0.01335818577197888,0.01459034792368126 +2014,BruCap,66,F,0.009396636993076165,0.0072992700729927 +2014,BruCap,67,M,0.01665598975016015,0.02004716981132075 +2014,BruCap,67,F,0.010564287554753929,0.002141327623126339 +2014,BruCap,68,M,0.02592036063110444,0.01683029453015428 +2014,BruCap,68,F,0.01314661331809089,0.01060070671378092 +2014,BruCap,69,M,0.02576950608446672,0.02205882352941177 +2014,BruCap,69,F,0.01081081081081081,0.01306413301662708 +2014,BruCap,70,M,0.03199691595990748,0.024096385542168683 +2014,BruCap,70,F,0.01440392277045664,0.006605019815059446 +2014,BruCap,71,M,0.03369330453563715,0.026755852842809368 +2014,BruCap,71,F,0.01754385964912281,0.01517241379310345 +2014,BruCap,72,M,0.03789473684210527,0.019230769230769232 +2014,BruCap,72,F,0.0194213238208482,0.01597444089456869 +2014,BruCap,73,M,0.03507972665148064,0.02195945945945946 +2014,BruCap,73,F,0.02151983860121049,0.0079155672823219 +2014,BruCap,74,M,0.03748264692272097,0.026119402985074636 +2014,BruCap,74,F,0.02652519893899205,0.0170940170940171 +2014,BruCap,75,M,0.04107648725212465,0.023952095808383242 +2014,BruCap,75,F,0.02131258457374831,0.009104704097116844 +2014,BruCap,76,M,0.04547751389590703,0.03777777777777778 +2014,BruCap,76,F,0.02000714540907467,0.01669449081803005 +2014,BruCap,77,M,0.04338842975206612,0.042986425339366516 +2014,BruCap,77,F,0.02659956865564342,0.0108695652173913 +2014,BruCap,78,M,0.05317982456140352,0.0339425587467363 +2014,BruCap,78,F,0.028944581715495937,0.03174603174603175 +2014,BruCap,79,M,0.059643255295429215,0.05962059620596207 +2014,BruCap,79,F,0.031182015953589562,0.04397705544933078 +2014,BruCap,80,M,0.07223880597014926,0.06790123456790123 +2014,BruCap,80,F,0.04002911208151383,0.03539823008849558 +2014,BruCap,81,M,0.06590084643288996,0.07142857142857142 +2014,BruCap,81,F,0.04344703770197487,0.0297029702970297 +2014,BruCap,82,M,0.06757634827810266,0.07630522088353414 +2014,BruCap,82,F,0.050094161958568736,0.04450261780104712 +2014,BruCap,83,M,0.09801136363636363,0.04597701149425287 +2014,BruCap,83,F,0.05244252873563218,0.04428904428904429 +2014,BruCap,84,M,0.1029173419773096,0.08181818181818183 +2014,BruCap,84,F,0.06326129666011787,0.0695364238410596 +2014,BruCap,85,M,0.1085069444444444,0.09195402298850572 +2014,BruCap,85,F,0.06368620835090677,0.0530035335689046 +2014,BruCap,86,M,0.1195219123505976,0.09448818897637797 +2014,BruCap,86,F,0.08337109198006343,0.06614785992217899 +2014,BruCap,87,M,0.1441144114411441,0.08771929824561403 +2014,BruCap,87,F,0.1064439140811456,0.08080808080808081 +2014,BruCap,88,M,0.1552878179384203,0.1214953271028038 +2014,BruCap,88,F,0.1092132505175983,0.07692307692307693 +2014,BruCap,89,M,0.1815718157181572,0.2238805970149254 +2014,BruCap,89,F,0.125,0.1418918918918919 +2014,BruCap,90,M,0.184,0.1568627450980392 +2014,BruCap,90,F,0.1346396965865993,0.1260504201680672 +2014,BruCap,91,M,0.1935483870967742,0.2452830188679246 +2014,BruCap,91,F,0.1557562076749436,0.07692307692307693 +2014,BruCap,92,M,0.2230046948356808,0.1219512195121951 +2014,BruCap,92,F,0.1596491228070176,0.1136363636363637 +2014,BruCap,93,M,0.2697841726618705,0.06451612903225806 +2014,BruCap,93,F,0.1799116997792495,0.08860759493670886 +2014,BruCap,94,M,0.2291666666666667,0.25 +2014,BruCap,94,F,0.2115732368896926,0.1315789473684211 +2014,BruCap,95,M,0.2435897435897436,0.0 +2014,BruCap,95,F,0.2651757188498403,0.1666666666666667 +2014,BruCap,96,M,0.3728813559322034,0.25 +2014,BruCap,96,F,0.2050209205020921,0.2222222222222222 +2014,BruCap,97,M,0.2105263157894737,0.6 +2014,BruCap,97,F,0.2634408602150538,0.3043478260869566 +2014,BruCap,98,M,0.32,0.0 +2014,BruCap,98,F,0.3248407643312102,0.4166666666666667 +2014,BruCap,99,M,0.15,0.0 +2014,BruCap,99,F,0.2898550724637682,0.3 +2014,BruCap,100,M,0.1875,0.0 +2014,BruCap,100,F,0.4225352112676057,0.3333333333333333 +2014,BruCap,101,M,0.6,0.5 +2014,BruCap,101,F,0.4259259259259261,0.2 +2014,BruCap,102,M,0.5,0.6666666666666666 +2014,BruCap,102,F,0.2352941176470588,1.0 +2014,BruCap,103,M,1.0,0.0 +2014,BruCap,103,F,0.3636363636363637,0.0 +2014,BruCap,104,M,0.0,0.0 +2014,BruCap,104,F,0.6,0.25 +2014,BruCap,105,M,0.0,0.0 +2014,BruCap,105,F,0.5,0.0 +2014,BruCap,106,M,0.0,0.0 +2014,BruCap,106,F,0.6,0.0 +2014,BruCap,107,M,0.0,0.0 +2014,BruCap,107,F,1.0,0.0 +2014,BruCap,108,M,0.0,0.0 +2014,BruCap,108,F,1.0,0.0 +2014,BruCap,109,M,0.0,0.0 +2014,BruCap,109,F,0.0,0.0 +2014,BruCap,110,M,0.0,0.0 +2014,BruCap,110,F,0.0,0.0 +2014,BruCap,111,M,0.0,0.0 +2014,BruCap,111,F,0.0,0.0 +2014,BruCap,112,M,0.0,0.0 +2014,BruCap,112,F,0.0,0.0 +2014,BruCap,113,M,0.0,0.0 +2014,BruCap,113,F,0.0,0.0 +2014,BruCap,114,M,0.0,0.0 +2014,BruCap,114,F,0.0,0.0 +2014,BruCap,115,M,0.0,0.0 +2014,BruCap,115,F,0.0,0.0 +2014,BruCap,116,M,0.0,0.0 +2014,BruCap,116,F,0.0,0.0 +2014,BruCap,117,M,0.0,0.0 +2014,BruCap,117,F,0.0,0.0 +2014,BruCap,118,M,0.0,0.0 +2014,BruCap,118,F,0.0,0.0 +2014,BruCap,119,M,0.0,0.0 +2014,BruCap,119,F,0.0,0.0 +2014,BruCap,120,M,0.0,0.0 +2014,BruCap,120,F,0.0,0.0 +2014,Fla,0,M,0.0007078507078507077,0.0008715862870424173 +2014,Fla,0,F,0.0004372687521022536,0.0009113001215066828 +2014,Fla,1,M,9.384677949135044e-05,0.0005797101449275362 +2014,Fla,1,F,0.0002286087524493795,0.0003033060357901123 +2014,Fla,2,M,0.00012111302873406609,0.0002996703626011388 +2014,Fla,2,F,9.565411472116826e-05,0.0 +2014,Fla,3,M,0.0001779517750689563,0.0 +2014,Fla,3,F,0.0,0.0 +2014,Fla,4,M,0.00011798017932987261,0.0 +2014,Fla,4,F,0.0,0.0 +2014,Fla,5,M,2.901746851604666e-05,0.0003379520108144643 +2014,Fla,5,F,6.100536847242559e-05,0.000353356890459364 +2014,Fla,6,M,8.973170221039093e-05,0.0 +2014,Fla,6,F,3.1046258925799435e-05,0.0003604902667627974 +2014,Fla,7,M,3.0085140948885356e-05,0.0 +2014,Fla,7,F,9.379983116030391e-05,0.0003828483920367535 +2014,Fla,8,M,9.124642618164122e-05,0.00037750094375235937 +2014,Fla,8,F,0.0,0.0 +2014,Fla,9,M,0.00012375471814862936,0.0 +2014,Fla,9,F,0.00013045888914255902,0.0 +2014,Fla,10,M,6.42157649703002e-05,0.0 +2014,Fla,10,F,0.0,0.0004199916001679967 +2014,Fla,11,M,0.00022448128788121733,0.0 +2014,Fla,11,F,3.373591525538088e-05,0.0008319467554076539 +2014,Fla,12,M,6.367804381049414e-05,0.0 +2014,Fla,12,F,6.62471016893011e-05,0.0004411116012351125 +2014,Fla,13,M,0.0001552795031055901,0.0 +2014,Fla,13,F,3.238132245320899e-05,0.0 +2014,Fla,14,M,0.0002183746685384495,0.0 +2014,Fla,14,F,3.21874597656753e-05,0.0 +2014,Fla,15,M,0.0001819836214740674,0.0004327131112072696 +2014,Fla,15,F,0.0001913082294423365,0.0 +2014,Fla,16,M,0.00026793688597796957,0.0 +2014,Fla,16,F,0.0001545929567448907,0.0 +2014,Fla,17,M,0.0006543918617448465,0.0 +2014,Fla,17,F,0.0001848713603450932,0.0 +2014,Fla,18,M,0.0004446288830922457,0.0 +2014,Fla,18,F,0.0001232020205131364,0.0 +2014,Fla,19,M,0.0005272253302480886,0.0007619047619047619 +2014,Fla,19,F,0.00021551060620054799,0.0004315925766076824 +2014,Fla,20,M,0.0004794269437942412,0.0003838771593090212 +2014,Fla,20,F,0.0002326528238236492,0.0 +2014,Fla,21,M,0.000629533324209662,0.0 +2014,Fla,21,F,0.00017047876118766867,0.0 +2014,Fla,22,M,0.0008103071063933231,0.0006443298969072165 +2014,Fla,22,F,5.6745637679103416e-05,0.0 +2014,Fla,23,M,0.0007681966583445362,0.001166861143523921 +2014,Fla,23,F,0.0002286236854138089,0.0 +2014,Fla,24,M,0.0006561492596924657,0.0007980845969672786 +2014,Fla,24,F,0.00011888486001307742,0.0004342162396873643 +2014,Fla,25,M,0.000698263070611853,0.0 +2014,Fla,25,F,0.0003600252017641235,0.0 +2014,Fla,26,M,0.0006473063230058553,0.0002327205026762858 +2014,Fla,26,F,0.0002760736196319019,0.0 +2014,Fla,27,M,0.0006206040546131567,0.000877963125548727 +2014,Fla,27,F,0.000244783061012178,0.000187160771102377 +2014,Fla,28,M,0.000550677639428519,0.0005927682276229994 +2014,Fla,28,F,0.0003105493618210615,0.0001822821728034998 +2014,Fla,29,M,0.0007752862595419847,0.0007753440589261482 +2014,Fla,29,F,0.0001516254245511887,0.0003609456776755099 +2014,Fla,30,M,0.000784746846480265,0.000585480093676815 +2014,Fla,30,F,0.00023410294677084247,0.0001852194850898315 +2014,Fla,31,M,0.0007890880396798557,0.001325506532853626 +2014,Fla,31,F,0.0003168750360085269,0.00018635855385762206 +2014,Fla,32,M,0.0007364975450081834,0.0 +2014,Fla,32,F,0.000280662363177098,0.00019421246844047391 +2014,Fla,33,M,0.0009376206497159561,0.0007419773696902244 +2014,Fla,33,F,0.0005505092210294524,0.0007584376185058779 +2014,Fla,34,M,0.0009491525423728814,0.00019223375624759706 +2014,Fla,34,F,0.0003880803880803882,0.0005938242280285036 +2014,Fla,35,M,0.0009693142793840699,0.0003996003996003996 +2014,Fla,35,F,0.0005822174166181485,0.0004093327875562833 +2014,Fla,36,M,0.0008169014084507043,0.0005955926146515784 +2014,Fla,36,F,0.0007610779118277143,0.00041963911036508597 +2014,Fla,37,M,0.000885410716325831,0.000407000407000407 +2014,Fla,37,F,0.0003760921136376787,0.0004344048653344917 +2014,Fla,38,M,0.0009938614440222157,0.0006222775357809582 +2014,Fla,38,F,0.000710879417078878,0.0008777704630239193 +2014,Fla,39,M,0.001240065385265769,0.0014715156611309651 +2014,Fla,39,F,0.0008220420658767504,0.0006922011998154131 +2014,Fla,40,M,0.0009490238611713666,0.0008624407072013798 +2014,Fla,40,F,0.0009099181073703367,0.0 +2014,Fla,41,M,0.0010906258114775382,0.000843348091924942 +2014,Fla,41,F,0.0010708595606863946,0.0002387774594078319 +2014,Fla,42,M,0.001224846894138233,0.001940910071166703 +2014,Fla,42,F,0.001047016004387496,0.0007455268389662028 +2014,Fla,43,M,0.00133229979167676,0.0018979333614508648 +2014,Fla,43,F,0.001175001835940369,0.0019459985405010948 +2014,Fla,44,M,0.001746852027076207,0.001754385964912281 +2014,Fla,44,F,0.001005715407069443,0.0010403120936280882 +2014,Fla,45,M,0.001734981565820863,0.0004420866489832007 +2014,Fla,45,F,0.001482813943312752,0.0002632271650434325 +2014,Fla,46,M,0.00200484893696382,0.002168674698795181 +2014,Fla,46,F,0.001249489391354495,0.00261172373766686 +2014,Fla,47,M,0.002332163477867089,0.0019166267369429809 +2014,Fla,47,F,0.001566567604303454,0.001186239620403322 +2014,Fla,48,M,0.002237970906378217,0.0007492507492507493 +2014,Fla,48,F,0.001614566982105216,0.0003044140030441401 +2014,Fla,49,M,0.0026295699380778697,0.0030565461029037192 +2014,Fla,49,F,0.0019517844886753608,0.001286587327114828 +2014,Fla,50,M,0.0029535142539166173,0.0029964587305911197 +2014,Fla,50,F,0.002352070039418952,0.0003465003465003465 +2014,Fla,51,M,0.003207976590441097,0.004091174751607247 +2014,Fla,51,F,0.0021686213764107107,0.002558479532163743 +2014,Fla,52,M,0.002932939334465345,0.0034225264467952713 +2014,Fla,52,F,0.002514391583405016,0.001589825119236884 +2014,Fla,53,M,0.003980032379924447,0.002853519340519975 +2014,Fla,53,F,0.002555924996041709,0.001596169193934557 +2014,Fla,54,M,0.00488370537207591,0.004506065857885615 +2014,Fla,54,F,0.00278039373962958,0.001733853489380148 +2014,Fla,55,M,0.005576632993554875,0.004130808950086058 +2014,Fla,55,F,0.003420699856700412,0.002385496183206107 +2014,Fla,56,M,0.005644051589430231,0.005764796310530361 +2014,Fla,56,F,0.0037467304474868633,0.003503503503503504 +2014,Fla,57,M,0.006573877865536506,0.004389465283320032 +2014,Fla,57,F,0.003449597546952856,0.0046923879040667365 +2014,Fla,58,M,0.006692090047976381,0.00507185122569738 +2014,Fla,58,F,0.003914608052907996,0.002181025081788441 +2014,Fla,59,M,0.0075652151911545186,0.00877963125548727 +2014,Fla,59,F,0.004109657695584624,0.006186726659167604 +2014,Fla,60,M,0.008697237195010806,0.009108341323106424 +2014,Fla,60,F,0.00476823262721801,0.004216867469879518 +2014,Fla,61,M,0.009345794392523364,0.008453505718547987 +2014,Fla,61,F,0.005054360702345539,0.002534854245880862 +2014,Fla,62,M,0.009101029780128026,0.008771929824561403 +2014,Fla,62,F,0.005554944450555496,0.006147540983606557 +2014,Fla,63,M,0.009613748511145142,0.007498660953401178 +2014,Fla,63,F,0.006330513628573008,0.005066497783407221 +2014,Fla,64,M,0.01167725214320299,0.01233299075025694 +2014,Fla,64,F,0.006308706014299734,0.006635700066357001 +2014,Fla,65,M,0.013659155091925541,0.01243915630070308 +2014,Fla,65,F,0.006806690003889537,0.008971704623878536 +2014,Fla,66,M,0.01399923210963112,0.01928530913216109 +2014,Fla,66,F,0.007470077247389718,0.005702066999287242 +2014,Fla,67,M,0.01593590677348871,0.0128130460104834 +2014,Fla,67,F,0.008740475123263109,0.0038167938931297713 +2014,Fla,68,M,0.01778847761393654,0.01332398316970547 +2014,Fla,68,F,0.00867441205023017,0.01153504880212955 +2014,Fla,69,M,0.01877406385226073,0.01928571428571429 +2014,Fla,69,F,0.010220924327069579,0.009174311926605509 +2014,Fla,70,M,0.02093292771258873,0.01646706586826348 +2014,Fla,70,F,0.010969650633248007,0.01421800947867299 +2014,Fla,71,M,0.02160363850753811,0.023411371237458192 +2014,Fla,71,F,0.01150968732016114,0.013448607108549471 +2014,Fla,72,M,0.024742761426178508,0.029972752043596725 +2014,Fla,72,F,0.01333220825246815,0.01752464403066813 +2014,Fla,73,M,0.024993329182602508,0.02385321100917432 +2014,Fla,73,F,0.01409695014212184,0.01516587677725119 +2014,Fla,74,M,0.03058460769198717,0.02689243027888447 +2014,Fla,74,F,0.01575352014498815,0.014672686230248309 +2014,Fla,75,M,0.03110253990398425,0.030494216614090432 +2014,Fla,75,F,0.01756148250779356,0.01635514018691589 +2014,Fla,76,M,0.03592605510987095,0.03681710213776722 +2014,Fla,76,F,0.01872727272727273,0.021356783919597992 +2014,Fla,77,M,0.03882853094000945,0.03041825095057034 +2014,Fla,77,F,0.0240558912386707,0.032171581769437 +2014,Fla,78,M,0.045572010734519434,0.03571428571428571 +2014,Fla,78,F,0.02605032273025935,0.019230769230769232 +2014,Fla,79,M,0.04862044021907616,0.04930662557781202 +2014,Fla,79,F,0.031525753158406215,0.01769911504424779 +2014,Fla,80,M,0.056213180641964434,0.04738562091503268 +2014,Fla,80,F,0.035883820098157534,0.029824561403508767 +2014,Fla,81,M,0.06482830991663266,0.05440900562851782 +2014,Fla,81,F,0.04021210782147592,0.05202312138728324 +2014,Fla,82,M,0.07009933358481077,0.08176100628930817 +2014,Fla,82,F,0.04629590589028967,0.03846153846153847 +2014,Fla,83,M,0.07851296989873767,0.07551487414187644 +2014,Fla,83,F,0.05292641391054943,0.07740585774058578 +2014,Fla,84,M,0.0949739452008741,0.05882352941176471 +2014,Fla,84,F,0.061711506307949526,0.06775067750677506 +2014,Fla,85,M,0.1019934197793691,0.1141868512110727 +2014,Fla,85,F,0.07354752042986679,0.07303370786516854 +2014,Fla,86,M,0.1198115324209109,0.1396396396396396 +2014,Fla,86,F,0.08167909975976735,0.1076388888888889 +2014,Fla,87,M,0.1310326233486115,0.1186440677966102 +2014,Fla,87,F,0.09336932447397564,0.1673003802281369 +2014,Fla,88,M,0.1417757451506072,0.1405405405405406 +2014,Fla,88,F,0.1120283018867925,0.07582938388625593 +2014,Fla,89,M,0.1596308658943648,0.1311475409836066 +2014,Fla,89,F,0.1253855924514607,0.1116751269035533 +2014,Fla,90,M,0.1821872015281758,0.1379310344827586 +2014,Fla,90,F,0.1421876664181489,0.1564245810055866 +2014,Fla,91,M,0.1901702537744941,0.2337662337662338 +2014,Fla,91,F,0.15414438502673802,0.1171875 +2014,Fla,92,M,0.2205943909585601,0.2156862745098039 +2014,Fla,92,F,0.1781936533767291,0.2613636363636364 +2014,Fla,93,M,0.2507552870090635,0.1904761904761905 +2014,Fla,93,F,0.1876029654036244,0.1818181818181818 +2014,Fla,94,M,0.2441588785046729,0.3478260869565218 +2014,Fla,94,F,0.2181055574973785,0.3333333333333333 +2014,Fla,95,M,0.3114035087719299,0.2352941176470588 +2014,Fla,95,F,0.2476319350473613,0.2727272727272727 +2014,Fla,96,M,0.2784313725490196,0.3333333333333333 +2014,Fla,96,F,0.2502351834430856,0.3793103448275862 +2014,Fla,97,M,0.3364928909952607,0.1428571428571429 +2014,Fla,97,F,0.2888165038002172,0.4 +2014,Fla,98,M,0.25,0.3333333333333333 +2014,Fla,98,F,0.3076923076923077,0.1 +2014,Fla,99,M,0.4351851851851852,0.5 +2014,Fla,99,F,0.30852994555353896,0.1818181818181818 +2014,Fla,100,M,0.2807017543859649,0.3333333333333333 +2014,Fla,100,F,0.3513513513513514,0.4 +2014,Fla,101,M,0.3529411764705883,0.0 +2014,Fla,101,F,0.3553719008264463,0.4285714285714286 +2014,Fla,102,M,0.4583333333333333,0.0 +2014,Fla,102,F,0.3767123287671233,0.0 +2014,Fla,103,M,0.1428571428571429,0.0 +2014,Fla,103,F,0.4242424242424243,0.5 +2014,Fla,104,M,0.4,0.0 +2014,Fla,104,F,0.4107142857142857,0.0 +2014,Fla,105,M,1.0,1.0 +2014,Fla,105,F,0.35,0.0 +2014,Fla,106,M,0.0,0.0 +2014,Fla,106,F,0.6666666666666666,0.0 +2014,Fla,107,M,0.0,0.0 +2014,Fla,107,F,0.8333333333333334,0.0 +2014,Fla,108,M,1.0,0.0 +2014,Fla,108,F,0.3333333333333333,0.0 +2014,Fla,109,M,0.0,0.0 +2014,Fla,109,F,0.0,0.0 +2014,Fla,110,M,0.0,0.0 +2014,Fla,110,F,0.0,0.0 +2014,Fla,111,M,0.0,0.0 +2014,Fla,111,F,1.0,0.0 +2014,Fla,112,M,0.0,0.0 +2014,Fla,112,F,0.0,0.0 +2014,Fla,113,M,0.0,0.0 +2014,Fla,113,F,0.0,0.0 +2014,Fla,114,M,0.0,0.0 +2014,Fla,114,F,0.0,0.0 +2014,Fla,115,M,0.0,0.0 +2014,Fla,115,F,0.0,0.0 +2014,Fla,116,M,0.0,0.0 +2014,Fla,116,F,0.0,0.0 +2014,Fla,117,M,0.0,0.0 +2014,Fla,117,F,0.0,0.0 +2014,Fla,118,M,0.0,0.0 +2014,Fla,118,F,0.0,0.0 +2014,Fla,119,M,0.0,0.0 +2014,Fla,119,F,0.0,0.0 +2014,Fla,120,M,0.0,0.0 +2014,Fla,120,F,0.0,0.0 +2014,Wal,0,M,0.0008034709946970914,0.001491424310216257 +2014,Wal,0,F,0.0005045691540057184,0.0 +2014,Wal,1,M,0.00031185031185031187,0.001483679525222552 +2014,Wal,1,F,0.0001614726303891491,0.0 +2014,Wal,2,M,0.0002046245140167792,0.0 +2014,Wal,2,F,5.308700960874874e-05,0.0007423904974016332 +2014,Wal,3,M,9.915224827722967e-05,0.0 +2014,Wal,3,F,5.1867219917012454e-05,0.0 +2014,Wal,4,M,0.0,0.0 +2014,Wal,4,F,0.0001025062785095587,0.0 +2014,Wal,5,M,9.70591089973794e-05,0.0 +2014,Wal,5,F,5.151187348683872e-05,0.0 +2014,Wal,6,M,0.0,0.0 +2014,Wal,6,F,0.0001550868486352357,0.0 +2014,Wal,7,M,0.0,0.0 +2014,Wal,7,F,0.0,0.0 +2014,Wal,8,M,9.904912836767035e-05,0.0 +2014,Wal,8,F,0.0,0.0 +2014,Wal,9,M,9.919650828290843e-05,0.0 +2014,Wal,9,F,5.2077908551192576e-05,0.0 +2014,Wal,10,M,0.0002010252286661976,0.0 +2014,Wal,10,F,0.00015577132769094968,0.0 +2014,Wal,11,M,9.987515605493134e-05,0.0 +2014,Wal,11,F,0.0001052077853761178,0.0 +2014,Wal,12,M,0.0,0.0 +2014,Wal,12,F,0.00010043690051725,0.0 +2014,Wal,13,M,9.515200532851228e-05,0.0 +2014,Wal,13,F,0.0001000300090027008,0.0 +2014,Wal,14,M,0.00024455857177794094,0.0 +2014,Wal,14,F,5.14853524172373e-05,0.0 +2014,Wal,15,M,4.874006921089828e-05,0.0 +2014,Wal,15,F,0.00020413370757846395,0.0008176614881439084 +2014,Wal,16,M,0.0006340844795629697,0.0 +2014,Wal,16,F,0.0002540263171264543,0.001615508885298869 +2014,Wal,17,M,0.0004838397522740468,0.0 +2014,Wal,17,F,0.00015133171912832933,0.0 +2014,Wal,18,M,0.0005918035212309513,0.0006983240223463687 +2014,Wal,18,F,0.0002062812645041514,0.0 +2014,Wal,19,M,0.0005897095680377414,0.0 +2014,Wal,19,F,0.00020547593363127352,0.0 +2014,Wal,20,M,0.0007582938388625593,0.0 +2014,Wal,20,F,9.98402555910543e-05,0.0006071645415907711 +2014,Wal,21,M,0.0007725165863855313,0.0006105006105006105 +2014,Wal,21,F,0.00033118849356548064,0.0 +2014,Wal,22,M,0.0009357037829167224,0.001246105919003116 +2014,Wal,22,F,0.0001846210652635466,0.0 +2014,Wal,23,M,0.0006379003964095321,0.001558441558441559 +2014,Wal,23,F,0.0002834601029905041,0.0 +2014,Wal,24,M,0.0008277765003449067,0.0005070993914807302 +2014,Wal,24,F,0.0003842828321644731,0.0004065040650406504 +2014,Wal,25,M,0.0008479766335327647,0.0 +2014,Wal,25,F,0.00014844136566056408,0.0007510326699211416 +2014,Wal,26,M,0.0009342118202379783,0.0 +2014,Wal,26,F,0.0005642472428827902,0.0 +2014,Wal,27,M,0.0008940101321148307,0.0007952286282306162 +2014,Wal,27,F,0.0004152392816360428,0.0003575259206292456 +2014,Wal,28,M,0.0005746525963849127,0.0 +2014,Wal,28,F,0.00021351553325504432,0.0003542330853701736 +2014,Wal,29,M,0.001158870627897177,0.0003777861730260674 +2014,Wal,29,F,0.0002681396471282244,0.0 +2014,Wal,30,M,0.00116710875331565,0.0007344840249724567 +2014,Wal,30,F,0.0003854625550660793,0.0003700962250185049 +2014,Wal,31,M,0.001101148340412144,0.0003546099290780142 +2014,Wal,31,F,0.0003715696162216678,0.0 +2014,Wal,32,M,0.001192451265035255,0.0010623229461756366 +2014,Wal,32,F,0.0004627487274409995,0.0003389830508474576 +2014,Wal,33,M,0.00118258008123811,0.001678415575696543 +2014,Wal,33,F,0.0006150376710573523,0.0003233107015842225 +2014,Wal,34,M,0.001088646967340591,0.0 +2014,Wal,34,F,0.00047707394646170166,0.0003385240352064997 +2014,Wal,35,M,0.001263423878711308,0.001648532805802836 +2014,Wal,35,F,0.0003172756596689758,0.001362862010221465 +2014,Wal,36,M,0.001724588450483407,0.0003450655624568668 +2014,Wal,36,F,0.0006270575325286095,0.0006884681583476765 +2014,Wal,37,M,0.001540911192151626,0.001433178072375493 +2014,Wal,37,F,0.0008659772808313383,0.001432664756446992 +2014,Wal,38,M,0.0008174526132938231,0.001019021739130435 +2014,Wal,38,F,0.0009560229445506693,0.001072961373390558 +2014,Wal,39,M,0.001423033514892782,0.002278645833333334 +2014,Wal,39,F,0.001226091221186856,0.002045687009887487 +2014,Wal,40,M,0.001787394167450612,0.002146580803434529 +2014,Wal,40,F,0.00178027641133755,0.0006802721088435374 +2014,Wal,41,M,0.002413479052823315,0.002144607843137255 +2014,Wal,41,F,0.001086366105377512,0.0003328894806924102 +2014,Wal,42,M,0.0022889457385216107,0.00212056952438655 +2014,Wal,42,F,0.0009764324708179842,0.0007024938531787848 +2014,Wal,43,M,0.002961545471113542,0.002165171667182184 +2014,Wal,43,F,0.0014603870025556769,0.0006724949562878277 +2014,Wal,44,M,0.0028640059127864013,0.002181364911187286 +2014,Wal,44,F,0.001278422061912154,0.0024813895781637717 +2014,Wal,45,M,0.003432063939821345,0.0022082018927444807 +2014,Wal,45,F,0.002070393374741201,0.001041666666666667 +2014,Wal,46,M,0.0037957691061426655,0.000630715862503942 +2014,Wal,46,F,0.001462924019383744,0.002809975412715139 +2014,Wal,47,M,0.003143937668018408,0.002888503755054882 +2014,Wal,47,F,0.002331002331002331,0.0023728813559322037 +2014,Wal,48,M,0.003480942938973342,0.002370370370370371 +2014,Wal,48,F,0.002479338842975207,0.0007173601147776184 +2014,Wal,49,M,0.004593063186813187,0.004370902279113331 +2014,Wal,49,F,0.00318377948137908,0.0007140307033202428 +2014,Wal,50,M,0.004927842309046111,0.002505480739116818 +2014,Wal,50,F,0.002339032066003232,0.0025906735751295338 +2014,Wal,51,M,0.005448848930663397,0.0025756600128783 +2014,Wal,51,F,0.003398100548923935,0.00288421920065925 +2014,Wal,52,M,0.006429432513283029,0.003290556103981573 +2014,Wal,52,F,0.002867536914187888,0.002437043054427295 +2014,Wal,53,M,0.006954726970879885,0.006265664160401002 +2014,Wal,53,F,0.003485838779956427,0.002053388090349076 +2014,Wal,54,M,0.007826637712631198,0.00771035869929601 +2014,Wal,54,F,0.00335314091680815,0.002603036876355749 +2014,Wal,55,M,0.007528930613003672,0.005407232173031429 +2014,Wal,55,F,0.004504699614501668,0.0004440497335701599 +2014,Wal,56,M,0.01092999151983417,0.00906555090655509 +2014,Wal,56,F,0.00497004659418682,0.001836547291092746 +2014,Wal,57,M,0.009414174918296669,0.004845967462789893 +2014,Wal,57,F,0.005197505197505198,0.0027998133457769487 +2014,Wal,58,M,0.01137153639884795,0.01069900142653352 +2014,Wal,58,F,0.005403441856241202,0.004791566842357451 +2014,Wal,59,M,0.01137046684031256,0.007921539041870995 +2014,Wal,59,F,0.006289308176100629,0.0038591413410516157 +2014,Wal,60,M,0.01149777709642803,0.01065929727595736 +2014,Wal,60,F,0.00645617342130066,0.0071428571428571435 +2014,Wal,61,M,0.01337264399283985,0.01351351351351352 +2014,Wal,61,F,0.006959777287126811,0.004682622268470343 +2014,Wal,62,M,0.013738210761598427,0.01279317697228145 +2014,Wal,62,F,0.00816848735360693,0.002649708532061473 +2014,Wal,63,M,0.016173950299914308,0.01252699784017279 +2014,Wal,63,F,0.00856509968003938,0.007284079084287202 +2014,Wal,64,M,0.01663325567535352,0.01286031042128603 +2014,Wal,64,F,0.009375308398302577,0.0080413555427915 +2014,Wal,65,M,0.01866996664155816,0.019536574284416186 +2014,Wal,65,F,0.0104171713745821,0.00748663101604278 +2014,Wal,66,M,0.02013496461293685,0.01544220870379036 +2014,Wal,66,F,0.01089313880126183,0.006440281030444965 +2014,Wal,67,M,0.02009449536061935,0.02287419194430632 +2014,Wal,67,F,0.01063829787234043,0.01882057716436637 +2014,Wal,68,M,0.024460768990309467,0.020156046814044214 +2014,Wal,68,F,0.011779415635693609,0.01711309523809524 +2014,Wal,69,M,0.02573705179282869,0.02001291155584248 +2014,Wal,69,F,0.0146123663915573,0.005714285714285714 +2014,Wal,70,M,0.0269914994303742,0.01580459770114943 +2014,Wal,70,F,0.01573541196182706,0.01198083067092652 +2014,Wal,71,M,0.0283363802559415,0.03137570394207563 +2014,Wal,71,F,0.0164561170212766,0.014937759336099591 +2014,Wal,72,M,0.03166462258891739,0.028571428571428567 +2014,Wal,72,F,0.01630777547526804,0.009615384615384616 +2014,Wal,73,M,0.03014818599897803,0.030257186081694414 +2014,Wal,73,F,0.01817888018098085,0.01834189288334556 +2014,Wal,74,M,0.03449612403100776,0.02981466559226431 +2014,Wal,74,F,0.020749665327978586,0.02393038433647571 +2014,Wal,75,M,0.03565672844480258,0.04052780395852969 +2014,Wal,75,F,0.02621778638462685,0.01963746223564955 +2014,Wal,76,M,0.0430396050230761,0.03547459252157239 +2014,Wal,76,F,0.02479139922978177,0.0210867802108678 +2014,Wal,77,M,0.04855264675354632,0.054752066115702484 +2014,Wal,77,F,0.027294271471765958,0.02809917355371901 +2014,Wal,78,M,0.05335479078979945,0.03651987110633728 +2014,Wal,78,F,0.03481953290870488,0.030595813204508864 +2014,Wal,79,M,0.062304124357527885,0.05807200929152149 +2014,Wal,79,F,0.035077339193643815,0.0349025974025974 +2014,Wal,80,M,0.06200317965023847,0.074719800747198 +2014,Wal,80,F,0.04449485255627291,0.03662691652470188 +2014,Wal,81,M,0.07359956385443643,0.06481481481481481 +2014,Wal,81,F,0.04970736130574562,0.04147465437788018 +2014,Wal,82,M,0.08586296617519515,0.08995502248875563 +2014,Wal,82,F,0.055137630364164816,0.0499092558983666 +2014,Wal,83,M,0.0940760956814898,0.0989345509893455 +2014,Wal,83,F,0.0655664585191793,0.06886792452830189 +2014,Wal,84,M,0.09913141993957704,0.1194295900178253 +2014,Wal,84,F,0.07050895192114262,0.05382131324004306 +2014,Wal,85,M,0.1227954144620811,0.1142857142857143 +2014,Wal,85,F,0.08862001308044473,0.0858974358974359 +2014,Wal,86,M,0.1335051546391753,0.1540342298288509 +2014,Wal,86,F,0.08996996996996998,0.1011378002528445 +2014,Wal,87,M,0.1455155582672361,0.169054441260745 +2014,Wal,87,F,0.10335677325195697,0.1146853146853147 +2014,Wal,88,M,0.1489583333333333,0.1444444444444444 +2014,Wal,88,F,0.1201331596468375,0.1105919003115265 +2014,Wal,89,M,0.1716485507246377,0.2062780269058296 +2014,Wal,89,F,0.1298788694481831,0.1581920903954803 +2014,Wal,90,M,0.1944127708095781,0.2395209580838324 +2014,Wal,90,F,0.1452172139506425,0.1493212669683258 +2014,Wal,91,M,0.1904417089065894,0.1651376146788991 +2014,Wal,91,F,0.1738308927727917,0.2005420054200542 +2014,Wal,92,M,0.2205607476635514,0.2330097087378641 +2014,Wal,92,F,0.1988003427592117,0.2296296296296297 +2014,Wal,93,M,0.2365887207702889,0.2280701754385965 +2014,Wal,93,F,0.2054491899852725,0.2551020408163266 +2014,Wal,94,M,0.2494117647058824,0.2972972972972973 +2014,Wal,94,F,0.2330097087378641,0.1954887218045113 +2014,Wal,95,M,0.2461538461538462,0.3076923076923077 +2014,Wal,95,F,0.2615384615384616,0.2456140350877193 +2014,Wal,96,M,0.2580645161290323,0.4 +2014,Wal,96,F,0.2900158478605388,0.3055555555555556 +2014,Wal,97,M,0.2696629213483146,0.0 +2014,Wal,97,F,0.3190578158458245,0.34375 +2014,Wal,98,M,0.3287671232876712,0.0 +2014,Wal,98,F,0.3424657534246575,0.25 +2014,Wal,99,M,0.3958333333333333,0.0 +2014,Wal,99,F,0.3715170278637771,0.2800000000000001 +2014,Wal,100,M,0.4,0.0 +2014,Wal,100,F,0.3804878048780488,0.5 +2014,Wal,101,M,0.2222222222222222,0.6 +2014,Wal,101,F,0.3247863247863248,0.6 +2014,Wal,102,M,0.6666666666666666,0.0 +2014,Wal,102,F,0.35897435897435903,0.25 +2014,Wal,103,M,0.6666666666666666,0.0 +2014,Wal,103,F,0.5714285714285714,1.0 +2014,Wal,104,M,0.0,0.0 +2014,Wal,104,F,0.2857142857142857,0.5 +2014,Wal,105,M,0.0,0.0 +2014,Wal,105,F,0.6,0.0 +2014,Wal,106,M,0.0,0.0 +2014,Wal,106,F,0.375,0.0 +2014,Wal,107,M,0.0,0.0 +2014,Wal,107,F,1.0,0.0 +2014,Wal,108,M,0.0,0.0 +2014,Wal,108,F,0.0,0.0 +2014,Wal,109,M,0.0,0.0 +2014,Wal,109,F,1.0,0.0 +2014,Wal,110,M,0.0,0.0 +2014,Wal,110,F,0.0,0.0 +2014,Wal,111,M,0.0,0.0 +2014,Wal,111,F,0.0,0.0 +2014,Wal,112,M,0.0,0.0 +2014,Wal,112,F,0.0,0.0 +2014,Wal,113,M,0.0,0.0 +2014,Wal,113,F,0.0,0.0 +2014,Wal,114,M,0.0,0.0 +2014,Wal,114,F,0.0,0.0 +2014,Wal,115,M,0.0,0.0 +2014,Wal,115,F,0.0,0.0 +2014,Wal,116,M,0.0,0.0 +2014,Wal,116,F,0.0,0.0 +2014,Wal,117,M,0.0,0.0 +2014,Wal,117,F,0.0,0.0 +2014,Wal,118,M,0.0,0.0 +2014,Wal,118,F,0.0,0.0 +2014,Wal,119,M,0.0,0.0 +2014,Wal,119,F,0.0,0.0 +2014,Wal,120,M,0.0,0.0 +2014,Wal,120,F,0.0,0.0 +2015,BruCap,0,M,0.0014351778025833196,0.00033057851239669435 +2015,BruCap,0,F,0.000664451827242525,0.0006918021445866483 +2015,BruCap,1,M,0.00016087516087516092,0.0003377237419790612 +2015,BruCap,1,F,0.0005100306018361101,0.0003642987249544627 +2015,BruCap,2,M,0.00015989766549408382,0.0003571428571428572 +2015,BruCap,2,F,0.00016603021749958492,0.0 +2015,BruCap,3,M,0.00016369291209690614,0.0003728560775540641 +2015,BruCap,3,F,0.0,0.0 +2015,BruCap,4,M,0.0,0.0 +2015,BruCap,4,F,0.0,0.0 +2015,BruCap,5,M,0.00032706459525756336,0.0004154549231408392 +2015,BruCap,5,F,0.0,0.0 +2015,BruCap,6,M,0.0,0.0004500450045004501 +2015,BruCap,6,F,0.0,0.0 +2015,BruCap,7,M,0.0,0.0 +2015,BruCap,7,F,0.0001801152737752161,0.0 +2015,BruCap,8,M,0.0,0.0 +2015,BruCap,8,F,0.0001843317972350231,0.0 +2015,BruCap,9,M,0.0,0.0 +2015,BruCap,9,F,0.0001907304978065993,0.0 +2015,BruCap,10,M,0.0,0.0 +2015,BruCap,10,F,0.000195160031225605,0.0 +2015,BruCap,11,M,0.00019794140934283448,0.0005720823798627003 +2015,BruCap,11,F,0.0,0.0 +2015,BruCap,12,M,0.0002079866888519135,0.0 +2015,BruCap,12,F,0.0,0.0 +2015,BruCap,13,M,0.0,0.0 +2015,BruCap,13,F,0.00041605991262741833,0.0 +2015,BruCap,14,M,0.0,0.0 +2015,BruCap,14,F,0.0,0.0 +2015,BruCap,15,M,0.0004161464835622138,0.0 +2015,BruCap,15,F,0.0,0.0 +2015,BruCap,16,M,0.0002167786689789725,0.0 +2015,BruCap,16,F,0.00022578460149017842,0.0 +2015,BruCap,17,M,0.0,0.0 +2015,BruCap,17,F,0.0,0.0 +2015,BruCap,18,M,0.0006362672322375398,0.001228501228501229 +2015,BruCap,18,F,0.0002213858755811379,0.001191185229303157 +2015,BruCap,19,M,0.0008545182653279214,0.00055005500550055 +2015,BruCap,19,F,0.0,0.0005115089514066496 +2015,BruCap,20,M,0.0004145936981757878,0.0 +2015,BruCap,20,F,0.0002240143369175627,0.0 +2015,BruCap,21,M,0.0006305170239596469,0.0 +2015,BruCap,21,F,0.0002155172413793104,0.0 +2015,BruCap,22,M,0.000406421459053038,0.0004173622704507513 +2015,BruCap,22,F,0.0,0.0 +2015,BruCap,23,M,0.001006036217303823,0.0003672420124862284 +2015,BruCap,23,F,0.000199203187250996,0.0 +2015,BruCap,24,M,0.0009598771357266268,0.00064246707356248 +2015,BruCap,24,F,0.0007623403849818944,0.0 +2015,BruCap,25,M,0.0003733432891543775,0.00030266343825665866 +2015,BruCap,25,F,0.0001796299622777079,0.0 +2015,BruCap,26,M,0.0008892050506846879,0.0 +2015,BruCap,26,F,0.0,0.00020076289901626185 +2015,BruCap,27,M,0.0003679852805887764,0.0002452783909737552 +2015,BruCap,27,F,0.0001745200698080279,0.0001944012441679627 +2015,BruCap,28,M,0.001105379513633014,0.00023342670401493927 +2015,BruCap,28,F,0.0001758705592683785,0.0 +2015,BruCap,29,M,0.0005595970900951317,0.0006720430107526883 +2015,BruCap,29,F,0.0001864280387770321,0.0003800836183960471 +2015,BruCap,30,M,0.0005690440060698028,0.0002079002079002079 +2015,BruCap,30,F,0.0003604253018561903,0.00019157088122605367 +2015,BruCap,31,M,0.001158972377824995,0.0008463817181548879 +2015,BruCap,31,F,0.0001889644746787604,0.0 +2015,BruCap,32,M,0.0011472275334608027,0.0008230452674897119 +2015,BruCap,32,F,0.0001866019779809666,0.0003836562440053712 +2015,BruCap,33,M,0.0005735041101127893,0.0008232146532208272 +2015,BruCap,33,F,0.0001870907390084191,0.00041832252666806116 +2015,BruCap,34,M,0.0005647590361445782,0.0007789678675754625 +2015,BruCap,34,F,0.00018211619012930248,0.0 +2015,BruCap,35,M,0.001322251605591236,0.00101667344448963 +2015,BruCap,35,F,0.000388651379712398,0.0 +2015,BruCap,36,M,0.0009585889570552148,0.0002065688907250568 +2015,BruCap,36,F,0.0005803830528148577,0.000656024491581019 +2015,BruCap,37,M,0.0005836575875486381,0.0002109259649862898 +2015,BruCap,37,F,0.0007906700929037362,0.000231696014828545 +2015,BruCap,38,M,0.001983339944466481,0.000847637211273575 +2015,BruCap,38,F,0.0,0.00047607712449416816 +2015,BruCap,39,M,0.0009956192751891676,0.001350438892640108 +2015,BruCap,39,F,0.0006448839208942393,0.0007751937984496124 +2015,BruCap,40,M,0.0013877874702616973,0.001124859392575928 +2015,BruCap,40,F,0.001274155871734976,0.0007878151260504202 +2015,BruCap,41,M,0.00019766752322593402,0.001673840267814443 +2015,BruCap,41,F,0.0008276432857438444,0.0 +2015,BruCap,42,M,0.001798561151079137,0.001001001001001001 +2015,BruCap,42,F,0.002068252326783868,0.0005743825387708214 +2015,BruCap,43,M,0.00198609731876862,0.0018597236981934108 +2015,BruCap,43,F,0.001478040540540541,0.0 +2015,BruCap,44,M,0.002509168114263656,0.001573564122738002 +2015,BruCap,44,F,0.0008141664970486463,0.0006285355122564425 +2015,BruCap,45,M,0.002402402402402403,0.0008110300081103001 +2015,BruCap,45,F,0.001887188089746278,0.001884422110552764 +2015,BruCap,46,M,0.0030450669914738127,0.001936912008854455 +2015,BruCap,46,F,0.001064962726304579,0.001003009027081244 +2015,BruCap,47,M,0.0037910699241786015,0.0026873693639892517 +2015,BruCap,47,F,0.001759788825340959,0.001090116279069767 +2015,BruCap,48,M,0.003355704697986577,0.001882648258550361 +2015,BruCap,48,F,0.001905165114309907,0.0007627765064836003 +2015,BruCap,49,M,0.0032441200324412013,0.0027643400138217 +2015,BruCap,49,F,0.003320190910977382,0.001195695496213631 +2015,BruCap,50,M,0.003098533360875853,0.002767208578346593 +2015,BruCap,50,F,0.0037398711822148353,0.001601281024819856 +2015,BruCap,51,M,0.003847798204360838,0.002244668911335578 +2015,BruCap,51,F,0.0020977554017201604,0.0025651988029072267 +2015,BruCap,52,M,0.004136729806226867,0.002781088597536751 +2015,BruCap,52,F,0.0032078699743370398,0.0035890533871691345 +2015,BruCap,53,M,0.005874378671486671,0.0045662100456621 +2015,BruCap,53,F,0.001708306641042067,0.0027972027972027968 +2015,BruCap,54,M,0.004886717014660151,0.003593890386343217 +2015,BruCap,54,F,0.002617274008455809,0.001450676982591876 +2015,BruCap,55,M,0.007965407373691398,0.003910068426197459 +2015,BruCap,55,F,0.004419191919191919,0.0034773969200198713 +2015,BruCap,56,M,0.007832898172323759,0.003075345976422348 +2015,BruCap,56,F,0.0038543897216274095,0.002760905577029266 +2015,BruCap,57,M,0.009658246656760771,0.004107981220657278 +2015,BruCap,57,F,0.007232084155161078,0.001798561151079137 +2015,BruCap,58,M,0.010240655401945721,0.005030743432084964 +2015,BruCap,58,F,0.0056595559425337396,0.004331683168316832 +2015,BruCap,59,M,0.01144164759725401,0.0055900621118012426 +2015,BruCap,59,F,0.004484304932735426,0.005663939584644432 +2015,BruCap,60,M,0.009406846093545859,0.007751937984496123 +2015,BruCap,60,F,0.0054582670002274285,0.002136752136752137 +2015,BruCap,61,M,0.014806980433633004,0.01640625 +2015,BruCap,61,F,0.005955107650022904,0.003041825095057034 +2015,BruCap,62,M,0.012917115177610341,0.01254901960784314 +2015,BruCap,62,F,0.006802721088435374,0.0076103500761035 +2015,BruCap,63,M,0.014855811243810082,0.01187214611872146 +2015,BruCap,63,F,0.008303975842979365,0.004329004329004329 +2015,BruCap,64,M,0.01412918108419839,0.01205857019810508 +2015,BruCap,64,F,0.009064184223419891,0.0050125313283208035 +2015,BruCap,65,M,0.01892551892551893,0.01785714285714286 +2015,BruCap,65,F,0.01052901900359527,0.01179941002949853 +2015,BruCap,66,M,0.017203628401626533,0.01441812564366633 +2015,BruCap,66,F,0.007250129466597619,0.01021450459652707 +2015,BruCap,67,M,0.02242577384712571,0.0199764982373678 +2015,BruCap,67,F,0.0108148893360161,0.0043336944745395465 +2015,BruCap,68,M,0.020601700457815567,0.017412935323383092 +2015,BruCap,68,F,0.012588512981904007,0.01233183856502242 +2015,BruCap,69,M,0.02168861347792409,0.01325478645066274 +2015,BruCap,69,F,0.016260162601626018,0.012285012285012293 +2015,BruCap,70,M,0.027356746765249542,0.01386748844375963 +2015,BruCap,70,F,0.012919896640826873,0.0123304562268804 +2015,BruCap,71,M,0.030327214684756583,0.02086677367576244 +2015,BruCap,71,F,0.01872659176029963,0.017955801104972382 +2015,BruCap,72,M,0.02795311091073039,0.017452006980802792 +2015,BruCap,72,F,0.01342050929112182,0.005805515239477504 +2015,BruCap,73,M,0.04052573932092005,0.02839756592292089 +2015,BruCap,73,F,0.02218636546994756,0.01182432432432433 +2015,BruCap,74,M,0.039886039886039885,0.039285714285714285 +2015,BruCap,74,F,0.02099827882960413,0.01761517615176152 +2015,BruCap,75,M,0.04501452081316554,0.029821073558648117 +2015,BruCap,75,F,0.02485529451821587,0.028358208955223882 +2015,BruCap,76,M,0.047619047619047616,0.018947368421052636 +2015,BruCap,76,F,0.02620689655172414,0.015552099533437018 +2015,BruCap,77,M,0.04754273504273504,0.052505966587112166 +2015,BruCap,77,F,0.033272394881170016,0.0189328743545611 +2015,BruCap,78,M,0.0568489442338928,0.042857142857142864 +2015,BruCap,78,F,0.02816901408450705,0.02423263327948304 +2015,BruCap,79,M,0.06318840579710144,0.056338028169014086 +2015,BruCap,79,F,0.03680758017492712,0.03296703296703297 +2015,BruCap,80,M,0.06220379146919431,0.07331378299120235 +2015,BruCap,80,F,0.03716216216216217,0.02862985685071575 +2015,BruCap,81,M,0.06847545219638243,0.07744107744107744 +2015,BruCap,81,F,0.045937737281700836,0.04906542056074766 +2015,BruCap,82,M,0.08025889967637541,0.07508532423208192 +2015,BruCap,82,F,0.0518018018018018,0.056 +2015,BruCap,83,M,0.09103641456582633,0.08520179372197309 +2015,BruCap,83,F,0.05812574139976275,0.05509641873278237 +2015,BruCap,84,M,0.09438377535101404,0.09349593495934956 +2015,BruCap,84,F,0.062074186222558676,0.06779661016949153 +2015,BruCap,85,M,0.1055956678700361,0.101010101010101 +2015,BruCap,85,F,0.06928213689482471,0.072992700729927 +2015,BruCap,86,M,0.1256085686465433,0.1401273885350319 +2015,BruCap,86,F,0.08010801080108011,0.0532319391634981 +2015,BruCap,87,M,0.1394557823129252,0.09009009009009007 +2015,BruCap,87,F,0.09637357178340784,0.1092436974789916 +2015,BruCap,88,M,0.1392081736909323,0.14 +2015,BruCap,88,F,0.1105769230769231,0.1043956043956044 +2015,BruCap,89,M,0.1533646322378717,0.1914893617021277 +2015,BruCap,89,F,0.1345029239766082,0.1233766233766234 +2015,BruCap,90,M,0.1655629139072848,0.07547169811320754 +2015,BruCap,90,F,0.13609467455621302,0.1428571428571429 +2015,BruCap,91,M,0.1791767554479419,0.1219512195121951 +2015,BruCap,91,F,0.15615835777126094,0.2038834951456311 +2015,BruCap,92,M,0.2305630026809652,0.2564102564102564 +2015,BruCap,92,F,0.1819803746654773,0.1578947368421053 +2015,BruCap,93,M,0.2658610271903324,0.3243243243243244 +2015,BruCap,93,F,0.2063492063492064,0.1392405063291139 +2015,BruCap,94,M,0.2388059701492538,0.2222222222222222 +2015,BruCap,94,F,0.2319034852546917,0.2028985507246377 +2015,BruCap,95,M,0.2882882882882883,0.3571428571428572 +2015,BruCap,95,F,0.2453703703703704,0.0967741935483871 +2015,BruCap,96,M,0.2542372881355932,0.3076923076923077 +2015,BruCap,96,F,0.2433628318584071,0.125 +2015,BruCap,97,M,0.3888888888888889,0.2 +2015,BruCap,97,F,0.2887700534759358,0.2857142857142857 +2015,BruCap,98,M,0.3333333333333333,0.3333333333333333 +2015,BruCap,98,F,0.3260869565217392,0.4 +2015,BruCap,99,M,0.2941176470588236,0.0 +2015,BruCap,99,F,0.4380952380952381,0.5 +2015,BruCap,100,M,0.2941176470588236,0.0 +2015,BruCap,100,F,0.33673469387755106,0.2857142857142857 +2015,BruCap,101,M,0.3846153846153847,0.0 +2015,BruCap,101,F,0.4047619047619048,0.6666666666666666 +2015,BruCap,102,M,0.25,0.0 +2015,BruCap,102,F,0.4333333333333334,0.0 +2015,BruCap,103,M,0.5,0.0 +2015,BruCap,103,F,0.4615384615384616,1.0 +2015,BruCap,104,M,0.0,0.0 +2015,BruCap,104,F,0.7142857142857143,0.0 +2015,BruCap,105,M,0.0,0.0 +2015,BruCap,105,F,0.25,0.0 +2015,BruCap,106,M,0.0,0.0 +2015,BruCap,106,F,0.75,0.0 +2015,BruCap,107,M,0.0,0.0 +2015,BruCap,107,F,0.5,0.0 +2015,BruCap,108,M,0.0,0.0 +2015,BruCap,108,F,0.0,0.0 +2015,BruCap,109,M,0.0,0.0 +2015,BruCap,109,F,0.0,0.0 +2015,BruCap,110,M,0.0,0.0 +2015,BruCap,110,F,0.0,0.0 +2015,BruCap,111,M,0.0,0.0 +2015,BruCap,111,F,0.0,0.0 +2015,BruCap,112,M,0.0,0.0 +2015,BruCap,112,F,0.0,0.0 +2015,BruCap,113,M,0.0,0.0 +2015,BruCap,113,F,0.0,0.0 +2015,BruCap,114,M,0.0,0.0 +2015,BruCap,114,F,0.0,0.0 +2015,BruCap,115,M,0.0,0.0 +2015,BruCap,115,F,0.0,0.0 +2015,BruCap,116,M,0.0,0.0 +2015,BruCap,116,F,0.0,0.0 +2015,BruCap,117,M,0.0,0.0 +2015,BruCap,117,F,0.0,0.0 +2015,BruCap,118,M,0.0,0.0 +2015,BruCap,118,F,0.0,0.0 +2015,BruCap,119,M,0.0,0.0 +2015,BruCap,119,F,0.0,0.0 +2015,BruCap,120,M,0.0,0.0 +2015,BruCap,120,F,0.0,0.0 +2015,Fla,0,M,0.0007122276538573602,0.0005474952094169176 +2015,Fla,0,F,0.0006812221124697707,0.0011597564511452599 +2015,Fla,1,M,0.00015952016334864732,0.0 +2015,Fla,1,F,0.0001996539331824837,0.0 +2015,Fla,2,M,6.196746707978312e-05,0.0 +2015,Fla,2,F,0.000129487553008967,0.0002947244326554671 +2015,Fla,3,M,3.005168890491646e-05,0.0002906976744186047 +2015,Fla,3,F,6.331317863813352e-05,0.00030646644192460935 +2015,Fla,4,M,8.832881874926393e-05,0.0 +2015,Fla,4,F,0.0001232209968578646,0.0 +2015,Fla,5,M,0.0001175191703146576,0.001257466205595725 +2015,Fla,5,F,3.101833183411396e-05,0.0003162555344718533 +2015,Fla,6,M,5.780848050408995e-05,0.0003257328990228013 +2015,Fla,6,F,6.069434328720563e-05,0.0 +2015,Fla,7,M,2.982848620432513e-05,0.0 +2015,Fla,7,F,3.096838128271036e-05,0.0 +2015,Fla,8,M,2.991951650061335e-05,0.0003486750348675036 +2015,Fla,8,F,0.0002181432889775312,0.0 +2015,Fla,9,M,6.063729800200103e-05,0.0 +2015,Fla,9,F,9.635767970707265e-05,0.0 +2015,Fla,10,M,0.0001233007613822015,0.0 +2015,Fla,10,F,0.0,0.0 +2015,Fla,11,M,6.404098623118796e-05,0.0 +2015,Fla,11,F,0.0001339674459106437,0.0 +2015,Fla,12,M,0.0,0.0003944773175542406 +2015,Fla,12,F,6.725401842760106e-05,0.0 +2015,Fla,13,M,3.175107159866647e-05,0.0 +2015,Fla,13,F,9.906875371507826e-05,0.00042517006802721087 +2015,Fla,14,M,0.0001549522746993926,0.0 +2015,Fla,14,F,0.0001938047094544398,0.0004043671653861706 +2015,Fla,15,M,0.0002490582484978675,0.0 +2015,Fla,15,F,0.000256846566282467,0.0 +2015,Fla,16,M,0.0002421087673637382,0.0004175365344467641 +2015,Fla,16,F,0.00019074868860276592,0.0 +2015,Fla,17,M,0.0003862150920974451,0.0008156606851549756 +2015,Fla,17,F,9.25383262901385e-05,0.0 +2015,Fla,18,M,0.0004159980982944078,0.0008022462896109105 +2015,Fla,18,F,0.0002460554239842525,0.0004342162396873643 +2015,Fla,19,M,0.0004742989268986778,0.00037313432835820896 +2015,Fla,19,F,9.224524936965746e-05,0.0008410428931875525 +2015,Fla,20,M,0.0005273798013536082,0.0003354579000335458 +2015,Fla,20,F,0.0001536900992838041,0.0 +2015,Fla,21,M,0.0005644933672029354,0.0006693440428380187 +2015,Fla,21,F,0.00020346471340541798,0.0 +2015,Fla,22,M,0.0006846126461648,0.0008982035928143712 +2015,Fla,22,F,0.00011371066321744318,0.000856898029134533 +2015,Fla,23,M,0.0007030067056024228,0.0005622715771717742 +2015,Fla,23,F,8.535579139044584e-05,0.00024102193299590269 +2015,Fla,24,M,0.0006895220233334253,0.0005099439061703213 +2015,Fla,24,F,0.00022964749110115966,0.0004313133491481562 +2015,Fla,25,M,0.00042982405868531153,0.0007035647279549719 +2015,Fla,25,F,0.0002086624735445793,0.0 +2015,Fla,26,M,0.0005563852528624559,0.0002156566745740781 +2015,Fla,26,F,0.00027079885662704983,0.0003639672429481347 +2015,Fla,27,M,0.0005613661880281273,0.0004273504273504274 +2015,Fla,27,F,0.0004300678892882377,0.0 +2015,Fla,28,M,0.0007699369243981166,0.0003986446083316724 +2015,Fla,28,F,0.0002751536274419885,0.0 +2015,Fla,29,M,0.0006746396810794235,0.0009191176470588236 +2015,Fla,29,F,0.0004346746150024839,0.0 +2015,Fla,30,M,0.0006271839440910313,0.0003682563063892469 +2015,Fla,30,F,0.0003326981822581133,0.0003433476394849786 +2015,Fla,31,M,0.0009287206872533086,0.0005565862708719852 +2015,Fla,31,F,0.0002332293519139384,0.0 +2015,Fla,32,M,0.0008737070544798625,0.0008986340762041695 +2015,Fla,32,F,0.000286820593718629,0.0003602305475504323 +2015,Fla,33,M,0.0007363167798412827,0.00037085110328203234 +2015,Fla,33,F,0.0005033838581576151,0.0005555555555555557 +2015,Fla,34,M,0.0007429011666299802,0.0009023641941887748 +2015,Fla,34,F,0.000439126138983423,0.0003612064294744447 +2015,Fla,35,M,0.0009747116478041912,0.0005587632706276774 +2015,Fla,35,F,0.0005530973451327434,0.000379003221527383 +2015,Fla,36,M,0.001217049760739081,0.0001957330201605011 +2015,Fla,36,F,0.0004972650422675287,0.0005870841487279842 +2015,Fla,37,M,0.0008435970980259827,0.0009587727708533078 +2015,Fla,37,F,0.0003651685393258427,0.0006128702757916241 +2015,Fla,38,M,0.001309645826215693,0.0007936507936507938 +2015,Fla,38,F,0.0006346642049388415,0.0004211412929037692 +2015,Fla,39,M,0.0008158270446665308,0.000609508329947176 +2015,Fla,39,F,0.0007084452578445553,0.0 +2015,Fla,40,M,0.001152624328807174,0.0008225375282747275 +2015,Fla,40,F,0.0006226473834658817,0.00044474093840337996 +2015,Fla,41,M,0.00113734835355286,0.001280136547898443 +2015,Fla,41,F,0.0007983702235436626,0.0006988120195667365 +2015,Fla,42,M,0.001608467804700877,0.0022797927461139893 +2015,Fla,42,F,0.0006514997524300942,0.0004692632566870014 +2015,Fla,43,M,0.001298571571271602,0.001069061364122301 +2015,Fla,43,F,0.0009720595199521448,0.001696969696969697 +2015,Fla,44,M,0.002252906976744186,0.001467505241090147 +2015,Fla,44,F,0.0008805400645729381,0.0009571667863125153 +2015,Fla,45,M,0.001793852419276641,0.0015171218032076286 +2015,Fla,45,F,0.001349395225594347,0.001547189272821042 +2015,Fla,46,M,0.0018553322731434628,0.001744059298016133 +2015,Fla,46,F,0.001190707620528772,0.0005193456245131135 +2015,Fla,47,M,0.0020990764063811922,0.002400960384153662 +2015,Fla,47,F,0.001394498942104251,0.001439263097294186 +2015,Fla,48,M,0.001972610194086704,0.0023769907297361537 +2015,Fla,48,F,0.001936912008854455,0.0008792497069167644 +2015,Fla,49,M,0.002571937306280364,0.00248323814253787 +2015,Fla,49,F,0.001638240574506284,0.001517450682852808 +2015,Fla,50,M,0.002547716608989194,0.0033154807447079828 +2015,Fla,50,F,0.00182493505378191,0.0025493945188017854 +2015,Fla,51,M,0.003411870735161581,0.00301287318542865 +2015,Fla,51,F,0.002182691258321511,0.002066115702479339 +2015,Fla,52,M,0.003999739147446907,0.0035211267605633812 +2015,Fla,52,F,0.002283358088186393,0.002215657311669129 +2015,Fla,53,M,0.003960352227974689,0.0043600124571784495 +2015,Fla,53,F,0.002297733197825991,0.0032128514056224897 +2015,Fla,54,M,0.004582392776523702,0.0022471910112359553 +2015,Fla,54,F,0.003014984245007141,0.0032076984763432237 +2015,Fla,55,M,0.005174151640721245,0.00591304347826087 +2015,Fla,55,F,0.002967025556879229,0.001749781277340333 +2015,Fla,56,M,0.005835190332881528,0.005250262513125656 +2015,Fla,56,F,0.003873182271493843,0.003833253473885961 +2015,Fla,57,M,0.006469305955980592,0.004672897196261682 +2015,Fla,57,F,0.004208336288625671,0.005050505050505051 +2015,Fla,58,M,0.007144241015208756,0.008477997577714978 +2015,Fla,58,F,0.00408477101254265,0.0026246719160104987 +2015,Fla,59,M,0.007948102112065763,0.002553191489361702 +2015,Fla,59,F,0.004853776921388326,0.0038419319429198687 +2015,Fla,60,M,0.007930841026164127,0.007146047342563644 +2015,Fla,60,F,0.005154768789760868,0.0051311288483466356 +2015,Fla,61,M,0.009953776657211892,0.005896805896805897 +2015,Fla,61,F,0.004922239095145834,0.006176652254478073 +2015,Fla,62,M,0.0097493774174747,0.006082108464267613 +2015,Fla,62,F,0.005950649281954987,0.00646830530401035 +2015,Fla,63,M,0.01070766117699961,0.009523809523809523 +2015,Fla,63,F,0.006637718837292917,0.002814919071076707 +2015,Fla,64,M,0.01209099765056444,0.009229098805646038 +2015,Fla,64,F,0.007234279354479686,0.00517464424320828 +2015,Fla,65,M,0.01162287658985378,0.017647058823529408 +2015,Fla,65,F,0.006404649719267556,0.006770480704129994 +2015,Fla,66,M,0.01300561140986673,0.01391982182628063 +2015,Fla,66,F,0.007526580861779519,0.004989308624376337 +2015,Fla,67,M,0.01579310138152177,0.011222681630242173 +2015,Fla,67,F,0.008240191605839416,0.01322556943423953 +2015,Fla,68,M,0.01652109548482606,0.018159806295399518 +2015,Fla,68,F,0.0087858071077462,0.007818608287724784 +2015,Fla,69,M,0.01882104689946226,0.01671511627906977 +2015,Fla,69,F,0.00928352647699643,0.0136986301369863 +2015,Fla,70,M,0.019726331874696117,0.01486988847583643 +2015,Fla,70,F,0.0101959024014877,0.006825938566552901 +2015,Fla,71,M,0.0205991124260355,0.02404965089216447 +2015,Fla,71,F,0.0118655462184874,0.01573254670599804 +2015,Fla,72,M,0.025853910350167767,0.02799650043744532 +2015,Fla,72,F,0.01358273828003726,0.01780415430267063 +2015,Fla,73,M,0.0263454839817495,0.017924528301886792 +2015,Fla,73,F,0.015991106550367708,0.01023890784982935 +2015,Fla,74,M,0.02916913540859578,0.02843601895734597 +2015,Fla,74,F,0.01511668679627537,0.01968503937007874 +2015,Fla,75,M,0.03266709649688373,0.03115264797507788 +2015,Fla,75,F,0.0179172125632945,0.0184971098265896 +2015,Fla,76,M,0.03909691629955947,0.028665931642778388 +2015,Fla,76,F,0.02020380099432319,0.010935601458080191 +2015,Fla,77,M,0.03905967450271248,0.03634085213032582 +2015,Fla,77,F,0.02341000851946513,0.02720207253886011 +2015,Fla,78,M,0.04408728988498968,0.0649867374005305 +2015,Fla,78,F,0.02697055295437837,0.03120567375886525 +2015,Fla,79,M,0.05179054757443265,0.05035971223021583 +2015,Fla,79,F,0.03138888888888889,0.0197869101978691 +2015,Fla,80,M,0.05617977528089887,0.06568144499178982 +2015,Fla,80,F,0.03532150598057318,0.033282904689863835 +2015,Fla,81,M,0.06162905953005655,0.06806282722513089 +2015,Fla,81,F,0.04349277902996912,0.05272727272727274 +2015,Fla,82,M,0.07272840583322948,0.08450704225352113 +2015,Fla,82,F,0.04911854612453415,0.04123711340206186 +2015,Fla,83,M,0.08245471749121384,0.08624708624708624 +2015,Fla,83,F,0.05432907136220855,0.06361323155216285 +2015,Fla,84,M,0.0901213171577123,0.08 +2015,Fla,84,F,0.06523385722401061,0.06496519721577726 +2015,Fla,85,M,0.1017185322805388,0.1079365079365079 +2015,Fla,85,F,0.07197665621960445,0.08259587020648967 +2015,Fla,86,M,0.1183317167798254,0.1304347826086957 +2015,Fla,86,F,0.08733756421879722,0.049689440993788817 +2015,Fla,87,M,0.1332398316970547,0.1518324607329843 +2015,Fla,87,F,0.103507683826063,0.051587301587301584 +2015,Fla,88,M,0.1505743557901273,0.1241830065359477 +2015,Fla,88,F,0.1174852952410053,0.09302325581395347 +2015,Fla,89,M,0.1658698050753954,0.1589403973509934 +2015,Fla,89,F,0.1356067316209035,0.1243523316062176 +2015,Fla,90,M,0.1834540780556205,0.2307692307692308 +2015,Fla,90,F,0.1478441558441558,0.1286549707602339 +2015,Fla,91,M,0.205736025753585,0.1527777777777778 +2015,Fla,91,F,0.1726967549421858,0.1655629139072848 +2015,Fla,92,M,0.2212529738302934,0.2280701754385965 +2015,Fla,92,F,0.1918696614995255,0.1296296296296296 +2015,Fla,93,M,0.2611739364566505,0.1578947368421053 +2015,Fla,93,F,0.2126607319485658,0.1940298507462687 +2015,Fla,94,M,0.2754442649434572,0.2941176470588236 +2015,Fla,94,F,0.2366082762122366,0.1904761904761905 +2015,Fla,95,M,0.2553846153846154,0.2142857142857143 +2015,Fla,95,F,0.2442953020134228,0.1153846153846154 +2015,Fla,96,M,0.3057324840764331,0.1538461538461539 +2015,Fla,96,F,0.3100358422939068,0.3636363636363637 +2015,Fla,97,M,0.3260869565217392,0.3333333333333333 +2015,Fla,97,F,0.2941919191919192,0.2222222222222222 +2015,Fla,98,M,0.4,0.2 +2015,Fla,98,F,0.3527607361963191,0.4444444444444444 +2015,Fla,99,M,0.4015151515151515,0.5 +2015,Fla,99,F,0.3546511627906977,0.375 +2015,Fla,100,M,0.4032258064516129,1.0 +2015,Fla,100,F,0.4304461942257218,0.75 +2015,Fla,101,M,0.3902439024390244,0.5 +2015,Fla,101,F,0.4166666666666667,0.5 +2015,Fla,102,M,0.5,0.0 +2015,Fla,102,F,0.4451612903225807,0.25 +2015,Fla,103,M,0.3846153846153847,0.0 +2015,Fla,103,F,0.5054945054945055,0.0 +2015,Fla,104,M,0.5,0.0 +2015,Fla,104,F,0.4210526315789474,0.0 +2015,Fla,105,M,1.0,0.0 +2015,Fla,105,F,0.5151515151515151,0.0 +2015,Fla,106,M,0.0,0.0 +2015,Fla,106,F,0.3846153846153847,0.0 +2015,Fla,107,M,0.0,0.0 +2015,Fla,107,F,1.0,0.5 +2015,Fla,108,M,0.0,0.0 +2015,Fla,108,F,0.0,0.0 +2015,Fla,109,M,0.0,0.0 +2015,Fla,109,F,0.5,0.0 +2015,Fla,110,M,0.0,0.0 +2015,Fla,110,F,1.0,0.0 +2015,Fla,111,M,0.0,0.0 +2015,Fla,111,F,0.0,0.0 +2015,Fla,112,M,0.0,0.0 +2015,Fla,112,F,0.0,0.0 +2015,Fla,113,M,0.0,0.0 +2015,Fla,113,F,0.0,0.0 +2015,Fla,114,M,0.0,0.0 +2015,Fla,114,F,0.0,0.0 +2015,Fla,115,M,0.0,0.0 +2015,Fla,115,F,0.0,0.0 +2015,Fla,116,M,0.0,0.0 +2015,Fla,116,F,0.0,0.0 +2015,Fla,117,M,0.0,0.0 +2015,Fla,117,F,0.0,0.0 +2015,Fla,118,M,0.0,0.0 +2015,Fla,118,F,0.0,0.0 +2015,Fla,119,M,0.0,0.0 +2015,Fla,119,F,0.0,0.0 +2015,Fla,120,M,0.0,0.0 +2015,Fla,120,F,0.0,0.0 +2015,Wal,0,M,0.0005919707243569046,0.0 +2015,Wal,0,F,0.0005170036764705881,0.0007199424046076314 +2015,Wal,1,M,0.000423728813559322,0.0007142857142857143 +2015,Wal,1,F,0.0001665001665001665,0.0007473841554559044 +2015,Wal,2,M,0.000154822727976467,0.0 +2015,Wal,2,F,0.000266851683834125,0.0007524454477050414 +2015,Wal,3,M,0.0001014455997971088,0.0 +2015,Wal,3,F,5.268703898840885e-05,0.0 +2015,Wal,4,M,0.00019738465334320256,0.0 +2015,Wal,4,F,0.0001545276604512208,0.0 +2015,Wal,5,M,0.0001972678404103171,0.0 +2015,Wal,5,F,0.0,0.0 +2015,Wal,6,M,0.0001932180465655492,0.0 +2015,Wal,6,F,0.0002053388090349076,0.0 +2015,Wal,7,M,0.0,0.0 +2015,Wal,7,F,0.0,0.0 +2015,Wal,8,M,4.872344572208146e-05,0.0 +2015,Wal,8,F,5.047445992327882e-05,0.0 +2015,Wal,9,M,4.936321453253036e-05,0.0 +2015,Wal,9,F,0.0001025115325474116,0.0 +2015,Wal,10,M,9.885818792941526e-05,0.0 +2015,Wal,10,F,0.0001038475517939665,0.0 +2015,Wal,11,M,0.0001000450202591166,0.0 +2015,Wal,11,F,5.17170045510964e-05,0.0 +2015,Wal,12,M,0.0001988565746955009,0.0 +2015,Wal,12,F,0.0001572162247143905,0.0 +2015,Wal,13,M,0.0001933488012374324,0.0 +2015,Wal,13,F,0.00020049120344844867,0.0 +2015,Wal,14,M,0.0,0.0 +2015,Wal,14,F,0.0,0.0 +2015,Wal,15,M,0.00034146341463414627,0.0 +2015,Wal,15,F,0.0001540199199096417,0.0 +2015,Wal,16,M,0.0002433208428633997,0.0 +2015,Wal,16,F,0.0001018329938900204,0.0 +2015,Wal,17,M,0.0002914885347842985,0.0 +2015,Wal,17,F,0.0002027266737621003,0.0 +2015,Wal,18,M,0.0001930315606601679,0.0006835269993164733 +2015,Wal,18,F,0.0001506780512305374,0.0 +2015,Wal,19,M,0.0004936321453253036,0.0006734006734006732 +2015,Wal,19,F,5.16288915276989e-05,0.0 +2015,Wal,20,M,0.0006391975612154587,0.0006293266205160479 +2015,Wal,20,F,0.00030864197530864197,0.0006042296072507553 +2015,Wal,21,M,0.0004267425320056899,0.0 +2015,Wal,21,F,0.0004999250112483127,0.0 +2015,Wal,22,M,0.0007731489903583772,0.0029550827423167852 +2015,Wal,22,F,0.0003324468085106384,0.0 +2015,Wal,23,M,0.0008054051635419929,0.0 +2015,Wal,23,F,0.00041780790121164304,0.0 +2015,Wal,24,M,0.0007344165978151108,0.0 +2015,Wal,24,F,0.0002863551758698039,0.0004093327875562833 +2015,Wal,25,M,0.0006031363088057903,0.0004741583688952111 +2015,Wal,25,F,0.0003896167145570545,0.0003806623524933385 +2015,Wal,26,M,0.0007128261179489616,0.0004342162396873643 +2015,Wal,26,F,0.00029941613852986677,0.0003621876131836291 +2015,Wal,27,M,0.0009905894006934127,0.0004048582995951417 +2015,Wal,27,F,0.0002063876992931221,0.0 +2015,Wal,28,M,0.0009458383114297092,0.0011605415860735009 +2015,Wal,28,F,0.0005702140894717744,0.0 +2015,Wal,29,M,0.0006789220806350532,0.0014981273408239699 +2015,Wal,29,F,0.0003724989357173265,0.0006734006734006732 +2015,Wal,30,M,0.0009466210886142519,0.0007202016564638098 +2015,Wal,30,F,0.0005343307507347048,0.000654236179260713 +2015,Wal,31,M,0.0009004237288135592,0.0003541076487252125 +2015,Wal,31,F,0.0007127583749109052,0.001056338028169014 +2015,Wal,32,M,0.001361470388019061,0.000351000351000351 +2015,Wal,32,F,0.0005280667476369013,0.0 +2015,Wal,33,M,0.0006197066721751704,0.0003473428273706148 +2015,Wal,33,F,0.0007679705099324186,0.0 +2015,Wal,34,M,0.0009728124519993855,0.001653986106516705 +2015,Wal,34,F,0.0007137030995106036,0.0 +2015,Wal,35,M,0.00134145083066763,0.001344989912575656 +2015,Wal,35,F,0.0005272871078302137,0.0 +2015,Wal,36,M,0.001364041760663134,0.0 +2015,Wal,36,F,0.0008956796628029506,0.001668335001668335 +2015,Wal,37,M,0.001457725947521866,0.0017024174327545118 +2015,Wal,37,F,0.0005720228809152366,0.0006756756756756758 +2015,Wal,38,M,0.001637079858801862,0.001071428571428571 +2015,Wal,38,F,0.0007609191903819812,0.00035075412136092597 +2015,Wal,39,M,0.001424573899771051,0.001698369565217391 +2015,Wal,39,F,0.001154039136979428,0.0006997900629811056 +2015,Wal,40,M,0.001223331376003132,0.0019236934915036871 +2015,Wal,40,F,0.001369059260707999,0.0003397893306150187 +2015,Wal,41,M,0.0019709056780854053,0.0 +2015,Wal,41,F,0.00126357169599401,0.001668335001668335 +2015,Wal,42,M,0.002318497976996864,0.0009225092250922508 +2015,Wal,42,F,0.001356300013563,0.0009976720984369804 +2015,Wal,43,M,0.0025997310623039,0.002423508027870343 +2015,Wal,43,F,0.001419194607060493,0.001737317581653927 +2015,Wal,44,M,0.0031406463359126076,0.0018320610687022894 +2015,Wal,44,F,0.0018690736688548512,0.0006724949562878277 +2015,Wal,45,M,0.002674906608864087,0.003145643284051589 +2015,Wal,45,F,0.001640539555231498,0.0007059654076950227 +2015,Wal,46,M,0.0033901497316131467,0.001582278481012658 +2015,Wal,46,F,0.00211484529446922,0.0003483106931382794 +2015,Wal,47,M,0.003384957803950663,0.004091910607491345 +2015,Wal,47,F,0.0025130220232111858,0.0017655367231638422 +2015,Wal,48,M,0.003694918346866162,0.002296870513924778 +2015,Wal,48,F,0.00260346530209175,0.002039428959891231 +2015,Wal,49,M,0.004593842484208665,0.004185351270553065 +2015,Wal,49,F,0.002653327533710309,0.002154398563734291 +2015,Wal,50,M,0.004727725963811407,0.004424778761061947 +2015,Wal,50,F,0.00310598111227702,0.00249910746162085 +2015,Wal,51,M,0.004900013243279036,0.0037902716361339225 +2015,Wal,51,F,0.003362846926613315,0.0018768768768768766 +2015,Wal,52,M,0.005747650761791808,0.005498059508408797 +2015,Wal,52,F,0.002927170256455066,0.002462043496101765 +2015,Wal,53,M,0.006141294602833064,0.004981733643307871 +2015,Wal,53,F,0.004069393874491326,0.003693065244152647 +2015,Wal,54,M,0.006078616776982304,0.004112622587788675 +2015,Wal,54,F,0.003843466107617051,0.0028747433264887053 +2015,Wal,55,M,0.008016762321217091,0.005108991825613079 +2015,Wal,55,F,0.004509870660313138,0.001738374619730552 +2015,Wal,56,M,0.01027413253630972,0.009931506849315071 +2015,Wal,56,F,0.004690961212700343,0.004492362982929021 +2015,Wal,57,M,0.008714285714285714,0.006338028169014085 +2015,Wal,57,F,0.0053935990015155574,0.003231763619575254 +2015,Wal,58,M,0.01046837371602693,0.008356545961002786 +2015,Wal,58,F,0.006446633676851137,0.0042573320719016105 +2015,Wal,59,M,0.01298766422625615,0.010163339382940107 +2015,Wal,59,F,0.006793106592504787,0.003401360544217687 +2015,Wal,60,M,0.012509496074955693,0.01034879264085857 +2015,Wal,60,F,0.007440130202278541,0.008296730112249878 +2015,Wal,61,M,0.014782653641391431,0.01042920176494184 +2015,Wal,61,F,0.00809659090909091,0.009316770186335404 +2015,Wal,62,M,0.0153115663679044,0.0113314447592068 +2015,Wal,62,F,0.01020062847474015,0.0042283298097251605 +2015,Wal,63,M,0.01491877555530998,0.01519756838905775 +2015,Wal,63,F,0.009726081778483529,0.00747863247863248 +2015,Wal,64,M,0.017227324601923808,0.018926056338028168 +2015,Wal,64,F,0.010320019846192009,0.006309148264984227 +2015,Wal,65,M,0.0191957636935297,0.01533603969327921 +2015,Wal,65,F,0.01030260800318535,0.005865102639296189 +2015,Wal,66,M,0.019035602611223883,0.02312411514865503 +2015,Wal,66,F,0.01051447574334898,0.007088331515812432 +2015,Wal,67,M,0.02192761649046261,0.01727447216890595 +2015,Wal,67,F,0.0121580547112462,0.008328375966686495 +2015,Wal,68,M,0.02207377287249492,0.02581311306143521 +2015,Wal,68,F,0.01265886624974783,0.009696186166774402 +2015,Wal,69,M,0.02590216519647153,0.020805369127516786 +2015,Wal,69,F,0.0124459234608985,0.01302681992337165 +2015,Wal,70,M,0.028216242741473788,0.02598267821452365 +2015,Wal,70,F,0.01661745519467143,0.01090116279069767 +2015,Wal,71,M,0.02981444784723473,0.02061855670103093 +2015,Wal,71,F,0.014870163497817569,0.01879084967320261 +2015,Wal,72,M,0.0295499634541088,0.029021558872305137 +2015,Wal,72,F,0.01705073014265215,0.015371477369769432 +2015,Wal,73,M,0.03451449608835711,0.030408340573414436 +2015,Wal,73,F,0.02103915111598976,0.0150709219858156 +2015,Wal,74,M,0.037837268128161884,0.02377179080824089 +2015,Wal,74,F,0.02564313306484754,0.02323838080959521 +2015,Wal,75,M,0.03920978740473325,0.03628691983122363 +2015,Wal,75,F,0.02459576406285584,0.02388059701492538 +2015,Wal,76,M,0.046218049034950436,0.04154302670623145 +2015,Wal,76,F,0.02685950413223141,0.02175602175602176 +2015,Wal,77,M,0.04989908051132541,0.04846686449060336 +2015,Wal,77,F,0.030918509990954687,0.02416666666666667 +2015,Wal,78,M,0.05331394644371744,0.060240963855421686 +2015,Wal,78,F,0.03575325220310533,0.03754266211604096 +2015,Wal,79,M,0.06671899529042387,0.0732519422863485 +2015,Wal,79,F,0.040337463749011336,0.046434494195688215 +2015,Wal,80,M,0.06795077581594436,0.08292079207920793 +2015,Wal,80,F,0.0442439109865078,0.051607445008460234 +2015,Wal,81,M,0.07671658660638599,0.07650273224043716 +2015,Wal,81,F,0.047935842522555366,0.0566873339238264 +2015,Wal,82,M,0.08502500735510445,0.1008522727272727 +2015,Wal,82,F,0.05638804677349502,0.060402684563758385 +2015,Wal,83,M,0.09301958307012002,0.0681063122923588 +2015,Wal,83,F,0.06606416629010392,0.0669811320754717 +2015,Wal,84,M,0.09823008849557524,0.1214165261382799 +2015,Wal,84,F,0.07596144670292967,0.06847935548841894 +2015,Wal,85,M,0.117462311557789,0.1169354838709678 +2015,Wal,85,F,0.08598312783906555,0.08059023836549375 +2015,Wal,86,M,0.13278112449799198,0.1555555555555556 +2015,Wal,86,F,0.09702473413788984,0.0997191011235955 +2015,Wal,87,M,0.1451900237529691,0.1575931232091691 +2015,Wal,87,F,0.1104092643768917,0.1256906077348067 +2015,Wal,88,M,0.1610953058321479,0.1718213058419244 +2015,Wal,88,F,0.1279207335107956,0.1415094339622642 +2015,Wal,89,M,0.1877551020408163,0.146551724137931 +2015,Wal,89,F,0.144053876478318,0.1396551724137931 +2015,Wal,90,M,0.1805251641137856,0.2333333333333334 +2015,Wal,90,F,0.1620736172672962,0.1340659340659341 +2015,Wal,91,M,0.2355430183356841,0.3565891472868218 +2015,Wal,91,F,0.1725695269788448,0.1775456919060052 +2015,Wal,92,M,0.2245080500894455,0.3 +2015,Wal,92,F,0.1978304310590922,0.1845637583892618 +2015,Wal,93,M,0.2759856630824373,0.325 +2015,Wal,93,F,0.2273212379935966,0.2352941176470588 +2015,Wal,94,M,0.3075539568345324,0.1521739130434783 +2015,Wal,94,F,0.2394822006472492,0.2420382165605096 +2015,Wal,95,M,0.3132911392405064,0.3333333333333333 +2015,Wal,95,F,0.2615643397813289,0.1962616822429907 +2015,Wal,96,M,0.2896551724137932,0.3333333333333333 +2015,Wal,96,F,0.265625,0.3125 +2015,Wal,97,M,0.4130434782608696,0.0 +2015,Wal,97,F,0.3399558498896248,0.24 +2015,Wal,98,M,0.4,0.5 +2015,Wal,98,F,0.3501577287066246,0.35 +2015,Wal,99,M,0.4081632653061225,0.0 +2015,Wal,99,F,0.3556485355648536,0.38095238095238093 +2015,Wal,100,M,0.5357142857142857,0.25 +2015,Wal,100,F,0.3137254901960785,0.2777777777777778 +2015,Wal,101,M,0.4583333333333333,0.0 +2015,Wal,101,F,0.35200000000000004,0.0 +2015,Wal,102,M,0.7142857142857143,0.0 +2015,Wal,102,F,0.4625,0.0 +2015,Wal,103,M,1.0,0.0 +2015,Wal,103,F,0.52,0.0 +2015,Wal,104,M,0.0,0.0 +2015,Wal,104,F,0.4666666666666667,0.0 +2015,Wal,105,M,0.0,0.0 +2015,Wal,105,F,0.6,0.0 +2015,Wal,106,M,0.0,0.0 +2015,Wal,106,F,0.75,1.0 +2015,Wal,107,M,0.0,0.0 +2015,Wal,107,F,0.6,0.0 +2015,Wal,108,M,0.0,0.0 +2015,Wal,108,F,0.0,0.0 +2015,Wal,109,M,0.0,0.0 +2015,Wal,109,F,0.0,0.0 +2015,Wal,110,M,0.0,0.0 +2015,Wal,110,F,0.0,0.0 +2015,Wal,111,M,0.0,0.0 +2015,Wal,111,F,0.0,0.0 +2015,Wal,112,M,0.0,0.0 +2015,Wal,112,F,0.0,0.0 +2015,Wal,113,M,0.0,0.0 +2015,Wal,113,F,0.0,0.0 +2015,Wal,114,M,0.0,0.0 +2015,Wal,114,F,0.0,0.0 +2015,Wal,115,M,0.0,0.0 +2015,Wal,115,F,0.0,0.0 +2015,Wal,116,M,0.0,0.0 +2015,Wal,116,F,0.0,0.0 +2015,Wal,117,M,0.0,0.0 +2015,Wal,117,F,0.0,0.0 +2015,Wal,118,M,0.0,0.0 +2015,Wal,118,F,0.0,0.0 +2015,Wal,119,M,0.0,0.0 +2015,Wal,119,F,0.0,0.0 +2015,Wal,120,M,0.0,0.0 +2015,Wal,120,F,0.0,0.0 +2016,BruCap,0,M,0.0006498781478472786,0.0006443298969072165 +2016,BruCap,0,F,0.0005084745762711863,0.0003549875754348599 +2016,BruCap,1,M,0.00016220600162206002,0.00032594524119947853 +2016,BruCap,1,F,0.00016903313049357682,0.0003394433129667346 +2016,BruCap,2,M,0.0001652073352056831,0.00034270047978067166 +2016,BruCap,2,F,0.00017433751743375168,0.0003602305475504323 +2016,BruCap,3,M,0.00016310552927744252,0.0 +2016,BruCap,3,F,0.0001699813020567738,0.0 +2016,BruCap,4,M,0.0001669727834362999,0.0 +2016,BruCap,4,F,0.0,0.0 +2016,BruCap,5,M,0.000160333493666827,0.0 +2016,BruCap,5,F,0.0,0.0 +2016,BruCap,6,M,0.0,0.0 +2016,BruCap,6,F,0.0001736412571627019,0.0 +2016,BruCap,7,M,0.0,0.0 +2016,BruCap,7,F,0.0001812250815512867,0.0 +2016,BruCap,8,M,0.0,0.0 +2016,BruCap,8,F,0.0,0.0 +2016,BruCap,9,M,0.0,0.0 +2016,BruCap,9,F,0.0,0.0 +2016,BruCap,10,M,0.0,0.0 +2016,BruCap,10,F,0.0,0.0 +2016,BruCap,11,M,0.0,0.0 +2016,BruCap,11,F,0.0001973943939992104,0.0 +2016,BruCap,12,M,0.0001994415636218588,0.0 +2016,BruCap,12,F,0.0,0.0 +2016,BruCap,13,M,0.0002109259649862898,0.0 +2016,BruCap,13,F,0.0,0.0 +2016,BruCap,14,M,0.00020550760378133996,0.0 +2016,BruCap,14,F,0.0,0.0 +2016,BruCap,15,M,0.0002079866888519135,0.0 +2016,BruCap,15,F,0.0002187705097352877,0.0 +2016,BruCap,16,M,0.0002072968490878939,0.0 +2016,BruCap,16,F,0.0002176278563656148,0.0 +2016,BruCap,17,M,0.0004327131112072696,0.0 +2016,BruCap,17,F,0.0002256826901376665,0.0 +2016,BruCap,18,M,0.0004145077720207254,0.0005711022272986865 +2016,BruCap,18,F,0.00022109219544550084,0.0 +2016,BruCap,19,M,0.0004254413954477772,0.0005219206680584551 +2016,BruCap,19,F,0.00022007042253521133,0.0 +2016,BruCap,20,M,0.0004263483265828181,0.0004889975550122249 +2016,BruCap,20,F,0.0002215330084182543,0.0 +2016,BruCap,21,M,0.0004117768169652049,0.0004393673110720562 +2016,BruCap,21,F,0.00022396416573348263,0.0 +2016,BruCap,22,M,0.00041493775933609963,0.0004061738424045492 +2016,BruCap,22,F,0.00021195421788893602,0.00031685678073510766 +2016,BruCap,23,M,0.000396904147648343,0.0003679175864606328 +2016,BruCap,23,F,0.00020104543626859667,0.00028192839018889197 +2016,BruCap,24,M,0.0003860258637328701,0.00031979533098816764 +2016,BruCap,24,F,0.0001904036557501904,0.0002396357536544453 +2016,BruCap,25,M,0.0003651634106262553,0.0002785515320334262 +2016,BruCap,25,F,0.00018053800324968408,0.00021574973031283708 +2016,BruCap,26,M,0.0003593244699964068,0.0005227391531625719 +2016,BruCap,26,F,0.0001747946163258172,0.0002039151712887439 +2016,BruCap,27,M,0.0003463803255975061,0.0004715868898844612 +2016,BruCap,27,F,0.00017397355601948508,0.0001887148518588413 +2016,BruCap,28,M,0.0005486466715435258,0.0004554771122751082 +2016,BruCap,28,F,0.0001743679163034002,0.0001824817518248175 +2016,BruCap,29,M,0.0005554526939455656,0.0004375410194705754 +2016,BruCap,29,F,0.00018021265092809519,0.0001874062968515742 +2016,BruCap,30,M,0.0005683971201212581,0.0004232804232804233 +2016,BruCap,30,F,0.00019036740909956216,0.0003690717844620779 +2016,BruCap,31,M,0.0005784805244890089,0.0003987240829346093 +2016,BruCap,31,F,0.00036954915003695486,0.00037608123354644597 +2016,BruCap,32,M,0.0005923000987166831,0.0006176652254478072 +2016,BruCap,32,F,0.0001939111886755866,0.0003892565200467108 +2016,BruCap,33,M,0.0005861664712778429,0.0005986828976252245 +2016,BruCap,33,F,0.0001909490166125645,0.0001930129318664351 +2016,BruCap,34,M,0.0005858230814294082,0.0006158899609936358 +2016,BruCap,34,F,0.0003826286588865506,0.00021052631578947367 +2016,BruCap,35,M,0.0005778120184899846,0.0005749329244921426 +2016,BruCap,35,F,0.0003712641544458883,0.00039658933174697595 +2016,BruCap,36,M,0.000777302759424796,0.0006100040666937777 +2016,BruCap,36,F,0.0003943217665615142,0.0004236390595212879 +2016,BruCap,37,M,0.0007704160246533128,0.0008309098462816784 +2016,BruCap,37,F,0.0005926511260371393,0.0006632765863365022 +2016,BruCap,38,M,0.0009873617693522906,0.0008326394671107411 +2016,BruCap,38,F,0.000600120024004801,0.0007042253521126763 +2016,BruCap,39,M,0.001007252215954875,0.001066325442525059 +2016,BruCap,39,F,0.0006185567010309278,0.000724112961622013 +2016,BruCap,40,M,0.001006036217303823,0.001128158844765343 +2016,BruCap,40,F,0.0006538796861377508,0.000783494384956908 +2016,BruCap,41,M,0.0011935548040580858,0.001136363636363637 +2016,BruCap,41,F,0.0008550662676357418,0.0007961783439490446 +2016,BruCap,42,M,0.001392480604734434,0.001447876447876448 +2016,BruCap,42,F,0.0008389261744966443,0.0008534850640113798 +2016,BruCap,43,M,0.001619433198380567,0.0017650025214321738 +2016,BruCap,43,F,0.001037990450487855,0.00115606936416185 +2016,BruCap,44,M,0.001988071570576541,0.001864677677144379 +2016,BruCap,44,F,0.001265555789917739,0.0012051822838204278 +2016,BruCap,45,M,0.002137167281911793,0.002098085496984002 +2016,BruCap,45,F,0.001435014350143502,0.001255886970172685 +2016,BruCap,46,M,0.002420330778539734,0.0024390243902439033 +2016,BruCap,46,F,0.001471825063078217,0.0015994881637875881 +2016,BruCap,47,M,0.002662297767765718,0.002801905295601009 +2016,BruCap,47,F,0.001703940362087327,0.001669449081803005 +2016,BruCap,48,M,0.0029667302394575127,0.002984183825723665 +2016,BruCap,48,F,0.0019902697921273787,0.001845699520118125 +2016,BruCap,49,M,0.003180661577608143,0.003145643284051589 +2016,BruCap,49,F,0.002129925452609159,0.0022822365918600232 +2016,BruCap,50,M,0.0036548223350253814,0.003871876099964801 +2016,BruCap,50,F,0.002492729538845036,0.0023952095808383238 +2016,BruCap,51,M,0.004141644232760406,0.0042283298097251605 +2016,BruCap,51,F,0.0027128547579298827,0.002810116419108792 +2016,BruCap,52,M,0.0047464940668824175,0.004924242424242424 +2016,BruCap,52,F,0.0029535864978902948,0.003000428632661809 +2016,BruCap,53,M,0.005285179475886369,0.005177220230983672 +2016,BruCap,53,F,0.00301659125188537,0.003146067415730337 +2016,BruCap,54,M,0.005926601322087987,0.005879882402351953 +2016,BruCap,54,F,0.003432003432003432,0.003292568203198495 +2016,BruCap,55,M,0.006730984967466906,0.006830601092896175 +2016,BruCap,55,F,0.0038360589541691905,0.003885381253035454 +2016,BruCap,56,M,0.007376671277086214,0.0074589756340129295 +2016,BruCap,56,F,0.004255319148936171,0.004062976130015236 +2016,BruCap,57,M,0.007984514880232278,0.00829445308449974 +2016,BruCap,57,F,0.004522937755761361,0.004517221908526256 +2016,BruCap,58,M,0.008776328986960883,0.008960573476702509 +2016,BruCap,58,F,0.004888888888888889,0.0048426150121065395 +2016,BruCap,59,M,0.009575569358178054,0.009675583380762664 +2016,BruCap,59,F,0.005285179475886369,0.005072923272035511 +2016,BruCap,60,M,0.01061901061901062,0.01086261980830671 +2016,BruCap,60,F,0.005668934240362812,0.00579896907216495 +2016,BruCap,61,M,0.01122694466720128,0.01163636363636364 +2016,BruCap,61,F,0.0062645011600928075,0.006564551422319475 +2016,BruCap,62,M,0.01246612466124662,0.012274959083469721 +2016,BruCap,62,F,0.00676937441643324,0.007053291536050156 +2016,BruCap,63,M,0.01342098055327308,0.01388888888888889 +2016,BruCap,63,F,0.0076335877862595426,0.007987220447284345 +2016,BruCap,64,M,0.014675052410901468,0.0150093808630394 +2016,BruCap,64,F,0.008485471843661609,0.008115419296663661 +2016,BruCap,65,M,0.01597633136094675,0.01584342963653309 +2016,BruCap,65,F,0.009231536926147704,0.009674582233948988 +2016,BruCap,66,M,0.01737207833228048,0.017334777898158182 +2016,BruCap,66,F,0.009942438513867086,0.01036269430051814 +2016,BruCap,67,M,0.01863753213367609,0.018518518518518517 +2016,BruCap,67,F,0.010749868904037759,0.01078748651564186 +2016,BruCap,68,M,0.02048114434330299,0.020075282308657467 +2016,BruCap,68,F,0.01172870984191739,0.011261261261261259 +2016,BruCap,69,M,0.02256652071404513,0.02260638297872341 +2016,BruCap,69,F,0.01304232100079851,0.01279069767441861 +2016,BruCap,70,M,0.024632499006754068,0.024502297090352215 +2016,BruCap,70,F,0.01422643746295199,0.0141206675224647 +2016,BruCap,71,M,0.02668699961875715,0.026229508196721308 +2016,BruCap,71,F,0.01579871269748391,0.01526717557251909 +2016,BruCap,72,M,0.029230135858377925,0.0288135593220339 +2016,BruCap,72,F,0.01688973868706182,0.01714285714285714 +2016,BruCap,73,M,0.03207810320781032,0.031135531135531136 +2016,BruCap,73,F,0.01825201825201825,0.01780415430267063 +2016,BruCap,74,M,0.03493699885452463,0.03534303534303535 +2016,BruCap,74,F,0.01974496092143151,0.02058319039451115 +2016,BruCap,75,M,0.03766105054509415,0.03816793893129771 +2016,BruCap,75,F,0.02184637068357999,0.02240896358543418 +2016,BruCap,76,M,0.04113763331640427,0.04149377593360997 +2016,BruCap,76,F,0.02479050279329609,0.025157232704402517 +2016,BruCap,77,M,0.04589994842702424,0.04646017699115045 +2016,BruCap,77,F,0.02810387762362149,0.02733118971061094 +2016,BruCap,78,M,0.05138339920948617,0.05076142131979695 +2016,BruCap,78,F,0.03153495440729484,0.03185840707964602 +2016,BruCap,79,M,0.05628948879954049,0.05569620253164557 +2016,BruCap,79,F,0.03516819571865444,0.03535353535353535 +2016,BruCap,80,M,0.06234413965087283,0.06325301204819278 +2016,BruCap,80,F,0.03902993558165972,0.03846153846153847 +2016,BruCap,81,M,0.06868304977945809,0.06774193548387097 +2016,BruCap,81,F,0.04373291682936354,0.04487179487179487 +2016,BruCap,82,M,0.07681564245810056,0.07749077490774907 +2016,BruCap,82,F,0.0499603489294211,0.05012531328320802 +2016,BruCap,83,M,0.08573436401967674,0.08712121212121213 +2016,BruCap,83,F,0.056633663366336635,0.05763688760806916 +2016,BruCap,84,M,0.095679012345679,0.09595959595959597 +2016,BruCap,84,F,0.06471816283924843,0.06395348837209303 +2016,BruCap,85,M,0.1061259706643658,0.1050228310502283 +2016,BruCap,85,F,0.07366707366707367,0.07407407407407407 +2016,BruCap,86,M,0.1180625630676085,0.12 +2016,BruCap,86,F,0.08412055780476832,0.08560311284046693 +2016,BruCap,87,M,0.1319290465631929,0.1343283582089552 +2016,BruCap,87,F,0.09694881889763778,0.09876543209876544 +2016,BruCap,88,M,0.1479524438573316,0.15 +2016,BruCap,88,F,0.1096952908587258,0.1084905660377359 +2016,BruCap,89,M,0.1612426035502959,0.1627906976744186 +2016,BruCap,89,F,0.1237113402061856,0.1241830065359477 +2016,BruCap,90,M,0.1743970315398887,0.1756756756756757 +2016,BruCap,90,F,0.1381178063642519,0.1397058823529412 +2016,BruCap,91,M,0.1903807615230461,0.1836734693877551 +2016,BruCap,91,F,0.1540832049306626,0.1523809523809524 +2016,BruCap,92,M,0.2108433734939759,0.2 +2016,BruCap,92,F,0.1709027169149869,0.1666666666666667 +2016,BruCap,93,M,0.2299651567944251,0.2222222222222222 +2016,BruCap,93,F,0.1898454746136865,0.1891891891891892 +2016,BruCap,94,M,0.2489451476793249,0.2608695652173913 +2016,BruCap,94,F,0.2097428958051421,0.2153846153846154 +2016,BruCap,95,M,0.2662337662337662,0.2631578947368421 +2016,BruCap,95,F,0.2296819787985866,0.2264150943396227 +2016,BruCap,96,M,0.2875,0.3333333333333333 +2016,BruCap,96,F,0.2507645259938838,0.24 +2016,BruCap,97,M,0.3023255813953488,0.3333333333333333 +2016,BruCap,97,F,0.2748538011695907,0.2857142857142857 +2016,BruCap,98,M,0.3478260869565218,0.25 +2016,BruCap,98,F,0.2962962962962963,0.3333333333333333 +2016,BruCap,99,M,0.35,0.5 +2016,BruCap,99,F,0.3260869565217392,0.375 +2016,BruCap,100,M,0.4166666666666667,0.0 +2016,BruCap,100,F,0.35,0.3333333333333333 +2016,BruCap,101,M,0.4166666666666667,0.5 +2016,BruCap,101,F,0.3787878787878788,0.4 +2016,BruCap,102,M,0.5,0.0 +2016,BruCap,102,F,0.4230769230769231,0.0 +2016,BruCap,103,M,0.5,0.0 +2016,BruCap,103,F,0.4117647058823529,0.5 +2016,BruCap,104,M,0.5,1.0 +2016,BruCap,104,F,0.5,0.0 +2016,BruCap,105,M,0.0,0.0 +2016,BruCap,105,F,0.5,0.5 +2016,BruCap,106,M,0.0,0.0 +2016,BruCap,106,F,0.6666666666666666,0.6666666666666666 +2016,BruCap,107,M,0.0,0.0 +2016,BruCap,107,F,1.0,0.5 +2016,BruCap,108,M,0.0,0.0 +2016,BruCap,108,F,1.0,0.0 +2016,BruCap,109,M,0.0,0.0 +2016,BruCap,109,F,0.0,0.0 +2016,BruCap,110,M,0.0,0.0 +2016,BruCap,110,F,0.0,0.0 +2016,BruCap,111,M,0.0,0.0 +2016,BruCap,111,F,0.0,0.0 +2016,BruCap,112,M,0.0,0.0 +2016,BruCap,112,F,0.0,0.0 +2016,BruCap,113,M,0.0,0.0 +2016,BruCap,113,F,0.0,0.0 +2016,BruCap,114,M,0.0,0.0 +2016,BruCap,114,F,0.0,0.0 +2016,BruCap,115,M,0.0,1.0 +2016,BruCap,115,F,0.0,0.0 +2016,BruCap,116,M,0.0,0.0 +2016,BruCap,116,F,0.0,0.0 +2016,BruCap,117,M,0.0,0.0 +2016,BruCap,117,F,0.0,0.0 +2016,BruCap,118,M,0.0,0.0 +2016,BruCap,118,F,0.0,0.0 +2016,BruCap,119,M,0.0,0.0 +2016,BruCap,119,F,0.0,0.0 +2016,BruCap,120,M,0.0,0.0 +2016,BruCap,120,F,0.0,0.0 +2016,Fla,0,M,0.0005667989197479412,0.0002690341673392521 +2016,Fla,0,F,0.00056173858090791,0.0002787844995818233 +2016,Fla,1,M,9.587114917550812e-05,0.0 +2016,Fla,1,F,6.729248679384947e-05,0.0 +2016,Fla,2,M,3.152783908190933e-05,0.0 +2016,Fla,2,F,3.2945672585905844e-05,0.0 +2016,Fla,3,M,3.071724773460298e-05,0.0 +2016,Fla,3,F,0.0,0.0 +2016,Fla,4,M,0.0,0.0 +2016,Fla,4,F,0.0,0.0 +2016,Fla,5,M,0.0,0.0 +2016,Fla,5,F,0.0,0.0 +2016,Fla,6,M,0.0,0.0 +2016,Fla,6,F,0.0,0.0 +2016,Fla,7,M,0.0,0.0 +2016,Fla,7,F,0.0,0.0 +2016,Fla,8,M,0.0,0.0 +2016,Fla,8,F,0.0,0.0 +2016,Fla,9,M,0.0,0.0 +2016,Fla,9,F,0.0,0.0 +2016,Fla,10,M,0.0,0.0 +2016,Fla,10,F,0.0,0.0 +2016,Fla,11,M,0.0,0.0 +2016,Fla,11,F,0.0,0.0 +2016,Fla,12,M,3.185829430692281e-05,0.0 +2016,Fla,12,F,0.0,0.0 +2016,Fla,13,M,3.1826861871419485e-05,0.0 +2016,Fla,13,F,0.0,0.0 +2016,Fla,14,M,6.324910660636919e-05,0.0 +2016,Fla,14,F,3.29023130326062e-05,0.0 +2016,Fla,15,M,9.260402518829483e-05,0.0 +2016,Fla,15,F,3.2188495831589787e-05,0.0 +2016,Fla,16,M,0.0002483469406761246,0.0 +2016,Fla,16,F,3.203280158882696e-05,0.0 +2016,Fla,17,M,0.0003316849595947413,0.0 +2016,Fla,17,F,6.333322777795371e-05,0.0 +2016,Fla,18,M,0.0003850824965194467,0.0 +2016,Fla,18,F,6.144015728680265e-05,0.0 +2016,Fla,19,M,0.0004455401431668994,0.0 +2016,Fla,19,F,6.147415011987458e-05,0.0 +2016,Fla,20,M,0.00047389153807422325,0.0 +2016,Fla,20,F,6.13591041570793e-05,0.0 +2016,Fla,21,M,0.0005273488998916004,0.0002889338341519792 +2016,Fla,21,F,0.0001227332699211439,0.0 +2016,Fla,22,M,0.0005643181625800628,0.00029850746268656717 +2016,Fla,22,F,0.00011623514369569642,0.0 +2016,Fla,23,M,0.0006305688827964362,0.0002625360987135732 +2016,Fla,23,F,0.0001421827901950748,0.0 +2016,Fla,24,M,0.000651713463313963,0.000246669955599408 +2016,Fla,24,F,0.0001712279900687766,0.0 +2016,Fla,25,M,0.0005821851348728897,0.0002255299954894001 +2016,Fla,25,F,0.0001728508873012215,0.0 +2016,Fla,26,M,0.0006047167909695626,0.000206996481059822 +2016,Fla,26,F,0.0001795117280995692,0.0 +2016,Fla,27,M,0.0006165590135055784,0.00019512195121951215 +2016,Fla,27,F,0.0001806739136980939,0.0001695202576707917 +2016,Fla,28,M,0.0007397544015386891,0.0001930874686232864 +2016,Fla,28,F,0.0002454891371056831,0.00016498927569707968 +2016,Fla,29,M,0.0007708728652751424,0.0003685277317118113 +2016,Fla,29,F,0.0002745995423340962,0.00016556291390728482 +2016,Fla,30,M,0.0007658140603461482,0.0003481288076588338 +2016,Fla,30,F,0.0003090139365285375,0.0001654807214959457 +2016,Fla,31,M,0.0007454453290395682,0.00034843205574912887 +2016,Fla,31,F,0.0003310361431279907,0.0001668056713928274 +2016,Fla,32,M,0.0007804144868052143,0.000353045013239188 +2016,Fla,32,F,0.0003191458496532916,0.00017111567419575633 +2016,Fla,33,M,0.0007864064035950008,0.0003460806367883717 +2016,Fla,33,F,0.00037074005418508485,0.00017497812773403318 +2016,Fla,34,M,0.0008418880017380914,0.00035733428622476335 +2016,Fla,34,F,0.0003896031613513664,0.0001789228842368939 +2016,Fla,35,M,0.0009027986758952754,0.0006966213862765588 +2016,Fla,35,F,0.0004637965842745676,0.0001773364071643909 +2016,Fla,36,M,0.0009443889803297266,0.0005433798224959246 +2016,Fla,36,F,0.0004946957621063046,0.0001843317972350231 +2016,Fla,37,M,0.0009650114422785297,0.0007572889057175312 +2016,Fla,37,F,0.0005219780219780219,0.0001892505677517033 +2016,Fla,38,M,0.001006880349051854,0.0007646721468170522 +2016,Fla,38,F,0.000642296629338993,0.0002 +2016,Fla,39,M,0.001105536185049749,0.0007807925043919579 +2016,Fla,39,F,0.0006320386118133762,0.00020673971469919368 +2016,Fla,40,M,0.001190856545354207,0.0007895775759968418 +2016,Fla,40,F,0.0007055503292568204,0.00041347942939838736 +2016,Fla,41,M,0.001207492067057932,0.0007945967421533573 +2016,Fla,41,F,0.0007333653005387414,0.0004394638540980005 +2016,Fla,42,M,0.0012946729602157788,0.001049097775912715 +2016,Fla,42,F,0.0009057225195553727,0.0004628558204119417 +2016,Fla,43,M,0.001448825416537307,0.001235839340885685 +2016,Fla,43,F,0.0010135661936691099,0.0004630701551285018 +2016,Fla,44,M,0.001719754748018544,0.001260504201680673 +2016,Fla,44,F,0.001070397291645923,0.0004822763443453099 +2016,Fla,45,M,0.001766998281412631,0.001660095455488691 +2016,Fla,45,F,0.001220911776915,0.00047551117451260117 +2016,Fla,46,M,0.001889306043357152,0.001950585175552666 +2016,Fla,46,F,0.001347444754765055,0.0005113781641523907 +2016,Fla,47,M,0.002069795427196149,0.002177226213803614 +2016,Fla,47,F,0.001529126213592233,0.001034126163391934 +2016,Fla,48,M,0.002287688500863719,0.002140309155766944 +2016,Fla,48,F,0.001706894893739783,0.0005733944954128443 +2016,Fla,49,M,0.002540777205598784,0.0023501762632197427 +2016,Fla,49,F,0.0019149132521225551,0.001173364623056615 +2016,Fla,50,M,0.002881273918972419,0.0027445109780439127 +2016,Fla,50,F,0.002088292091435757,0.001528117359413203 +2016,Fla,51,M,0.0032736007482516,0.002799694578773225 +2016,Fla,51,F,0.0023202354609319627,0.002273465410847678 +2016,Fla,52,M,0.003633939706704512,0.003058954393770857 +2016,Fla,52,F,0.0025138260432378077,0.002425502425502426 +2016,Fla,53,M,0.004120160446459714,0.0035671819262782407 +2016,Fla,53,F,0.002774756376390153,0.0030086498683715678 +2016,Fla,54,M,0.004663246952235028,0.003478810879190386 +2016,Fla,54,F,0.0030752212389380533,0.003233629749393695 +2016,Fla,55,M,0.005191684236777075,0.004563233376792698 +2016,Fla,55,F,0.003386363636363637,0.0032679738562091517 +2016,Fla,56,M,0.005736524790785564,0.004624688722874422 +2016,Fla,56,F,0.003650128430444775,0.003947368421052632 +2016,Fla,57,M,0.006352799852153022,0.0053437833986462405 +2016,Fla,57,F,0.004026158393260257,0.004331087584215593 +2016,Fla,58,M,0.006927590188270222,0.00712871287128713 +2016,Fla,58,F,0.004224516435267592,0.004087889626980072 +2016,Fla,59,M,0.007612726917821589,0.006916192026037429 +2016,Fla,59,F,0.004510806638363566,0.0048 +2016,Fla,60,M,0.008312946227969444,0.00898972602739726 +2016,Fla,60,F,0.004829733506582657,0.003923766816143498 +2016,Fla,61,M,0.008972875690962848,0.009045680687471731 +2016,Fla,61,F,0.005250668955419801,0.005244755244755245 +2016,Fla,62,M,0.009605179367437912,0.008517034068136272 +2016,Fla,62,F,0.005627728396360385,0.005031446540880503 +2016,Fla,63,M,0.01035202225551038,0.01128205128205128 +2016,Fla,63,F,0.006014957549304021,0.0058900523560209425 +2016,Fla,64,M,0.011350415708975341,0.01184068891280947 +2016,Fla,64,F,0.006458078165015032,0.005738880918220947 +2016,Fla,65,M,0.0123936957594404,0.01288515406162465 +2016,Fla,65,F,0.0069730320087372935,0.005913272010512485 +2016,Fla,66,M,0.01336094985267949,0.01431718061674009 +2016,Fla,66,F,0.007520077187207356,0.00700770847932726 +2016,Fla,67,M,0.014625769777356709,0.01601830663615561 +2016,Fla,67,F,0.008115190622446394,0.007994186046511628 +2016,Fla,68,M,0.01590826134566249,0.0175544794188862 +2016,Fla,68,F,0.008847269698101285,0.008365019011406844 +2016,Fla,69,M,0.01742768563946664,0.019230769230769232 +2016,Fla,69,F,0.009632922936616509,0.00878594249201278 +2016,Fla,70,M,0.019068090417417832,0.02094240837696335 +2016,Fla,70,F,0.010511562718990891,0.01022304832713755 +2016,Fla,71,M,0.02100230210731362,0.02277904328018224 +2016,Fla,71,F,0.01146187469645459,0.01221640488656196 +2016,Fla,72,M,0.022966796358554,0.02419354838709678 +2016,Fla,72,F,0.0125854620905473,0.01317122593718339 +2016,Fla,73,M,0.02521750651415449,0.02831050228310503 +2016,Fla,73,F,0.01376814444750403,0.013265306122448979 +2016,Fla,74,M,0.02790229161420297,0.02801932367149759 +2016,Fla,74,F,0.01542271265965766,0.01413427561837456 +2016,Fla,75,M,0.031242670169348414,0.033696729435084234 +2016,Fla,75,F,0.01725161239267202,0.018556701030927842 +2016,Fla,76,M,0.03522878720568636,0.03896103896103896 +2016,Fla,76,F,0.01972237245357851,0.02166064981949459 +2016,Fla,77,M,0.0395961021209048,0.04267589388696655 +2016,Fla,77,F,0.02262834118789798,0.02247191011235955 +2016,Fla,78,M,0.04446012702893437,0.048748353096179184 +2016,Fla,78,F,0.02617304555627205,0.03129251700680273 +2016,Fla,79,M,0.04988172374781447,0.04885057471264368 +2016,Fla,79,F,0.03049944329568952,0.0344311377245509 +2016,Fla,80,M,0.0561803917265595,0.06065318818040435 +2016,Fla,80,F,0.03555191480647143,0.03937007874015748 +2016,Fla,81,M,0.06360078277886498,0.06642728904847396 +2016,Fla,81,F,0.04128001331613333,0.04251968503937008 +2016,Fla,82,M,0.07239622172508077,0.07984790874524715 +2016,Fla,82,F,0.04784354810546534,0.0550098231827112 +2016,Fla,83,M,0.08211715650010089,0.08482142857142858 +2016,Fla,83,F,0.055381768515662864,0.06387665198237885 +2016,Fla,84,M,0.09311233885819524,0.08505154639175258 +2016,Fla,84,F,0.06435759419611514,0.0684931506849315 +2016,Fla,85,M,0.105655377991223,0.1068493150684932 +2016,Fla,85,F,0.07449987338566726,0.08478802992518704 +2016,Fla,86,M,0.1188825659596482,0.1223021582733813 +2016,Fla,86,F,0.08626011998369154,0.09935897435897437 +2016,Fla,87,M,0.1329663608562691,0.1395348837209302 +2016,Fla,87,F,0.0995097389691268,0.1125827814569536 +2016,Fla,88,M,0.1480500367917587,0.1446540880503145 +2016,Fla,88,F,0.1140175411601785,0.1302521008403362 +2016,Fla,89,M,0.1662404092071611,0.1818181818181818 +2016,Fla,89,F,0.1295767333160218,0.1428571428571429 +2016,Fla,90,M,0.1854465270121279,0.1935483870967742 +2016,Fla,90,F,0.1456838220217347,0.1656441717791411 +2016,Fla,91,M,0.2077363896848138,0.2307692307692308 +2016,Fla,91,F,0.1632777304273712,0.1721854304635762 +2016,Fla,92,M,0.229665071770335,0.2622950819672132 +2016,Fla,92,F,0.182406015037594,0.2131147540983607 +2016,Fla,93,M,0.2517838939857289,0.2954545454545455 +2016,Fla,93,F,0.2032902467685076,0.2417582417582418 +2016,Fla,94,M,0.2708029197080292,0.3 +2016,Fla,94,F,0.2252320040130424,0.2857142857142857 +2016,Fla,95,M,0.2925472747497219,0.3043478260869566 +2016,Fla,95,F,0.2453457446808511,0.2857142857142857 +2016,Fla,96,M,0.313929313929314,0.2 +2016,Fla,96,F,0.2701900237529692,0.3478260869565218 +2016,Fla,97,M,0.3440366972477064,0.3 +2016,Fla,97,F,0.2981770833333333,0.4285714285714286 +2016,Fla,98,M,0.3577235772357724,0.3333333333333333 +2016,Fla,98,F,0.3237924865831843,0.2857142857142857 +2016,Fla,99,M,0.38095238095238093,0.0 +2016,Fla,99,F,0.3539192399049882,0.6 +2016,Fla,100,M,0.4050632911392405,0.0 +2016,Fla,100,F,0.3825301204819277,0.5555555555555556 +2016,Fla,101,M,0.3888888888888889,0.0 +2016,Fla,101,F,0.4120370370370371,0.0 +2016,Fla,102,M,0.48,0.0 +2016,Fla,102,F,0.4468085106382979,0.5 +2016,Fla,103,M,0.6363636363636364,0.0 +2016,Fla,103,F,0.4767441860465116,0.6666666666666666 +2016,Fla,104,M,1.0,0.0 +2016,Fla,104,F,0.5777777777777777,1.0 +2016,Fla,105,M,1.0,0.0 +2016,Fla,105,F,0.6818181818181818,1.0 +2016,Fla,106,M,0.0,0.0 +2016,Fla,106,F,0.75,0.0 +2016,Fla,107,M,0.0,0.0 +2016,Fla,107,F,0.625,0.0 +2016,Fla,108,M,0.0,0.0 +2016,Fla,108,F,0.0,1.0 +2016,Fla,109,M,0.0,0.0 +2016,Fla,109,F,1.0,0.0 +2016,Fla,110,M,0.0,0.0 +2016,Fla,110,F,1.0,0.0 +2016,Fla,111,M,0.0,0.0 +2016,Fla,111,F,0.0,0.0 +2016,Fla,112,M,0.0,0.0 +2016,Fla,112,F,0.0,0.0 +2016,Fla,113,M,0.0,0.0 +2016,Fla,113,F,0.0,0.0 +2016,Fla,114,M,0.0,0.0 +2016,Fla,114,F,0.0,0.0 +2016,Fla,115,M,1.0,0.0 +2016,Fla,115,F,0.0,0.0 +2016,Fla,116,M,0.0,0.0 +2016,Fla,116,F,0.0,0.0 +2016,Fla,117,M,0.0,0.0 +2016,Fla,117,F,1.0,0.0 +2016,Fla,118,M,0.0,0.0 +2016,Fla,118,F,0.0,0.0 +2016,Fla,119,M,0.0,0.0 +2016,Fla,119,F,0.0,0.0 +2016,Fla,120,M,0.0,0.0 +2016,Fla,120,F,0.0,0.0 +2016,Wal,0,M,0.0005036655660641334,0.0 +2016,Wal,0,F,0.0004639832966013223,0.0 +2016,Wal,1,M,0.0001062699256110521,0.0 +2016,Wal,1,F,5.680527152919791e-05,0.0 +2016,Wal,2,M,5.242189138184106e-05,0.0 +2016,Wal,2,F,5.497828357798671e-05,0.0 +2016,Wal,3,M,0.0,0.0 +2016,Wal,3,F,0.0,0.0 +2016,Wal,4,M,0.0,0.0 +2016,Wal,4,F,0.0,0.0 +2016,Wal,5,M,0.0,0.0 +2016,Wal,5,F,0.0,0.0 +2016,Wal,6,M,0.0,0.0 +2016,Wal,6,F,0.0,0.0 +2016,Wal,7,M,0.0,0.0 +2016,Wal,7,F,0.0,0.0 +2016,Wal,8,M,0.0,0.0 +2016,Wal,8,F,0.0,0.0 +2016,Wal,9,M,0.0,0.0 +2016,Wal,9,F,0.0,0.0 +2016,Wal,10,M,0.0,0.0 +2016,Wal,10,F,0.0,0.0 +2016,Wal,11,M,0.0,0.0 +2016,Wal,11,F,0.0,0.0 +2016,Wal,12,M,0.0,0.0 +2016,Wal,12,F,0.0,0.0 +2016,Wal,13,M,0.0,0.0 +2016,Wal,13,F,0.0,0.0 +2016,Wal,14,M,4.821368304324768e-05,0.0 +2016,Wal,14,F,0.0,0.0 +2016,Wal,15,M,9.460290430916228e-05,0.0 +2016,Wal,15,F,0.0,0.0 +2016,Wal,16,M,0.00019465667429071986,0.0 +2016,Wal,16,F,5.113781641523907e-05,0.0 +2016,Wal,17,M,0.0002911349410451744,0.0 +2016,Wal,17,F,5.06636943965954e-05,0.0 +2016,Wal,18,M,0.0003875217981011432,0.0 +2016,Wal,18,F,0.0001009642081881973,0.0 +2016,Wal,19,M,0.0005303249445569376,0.0 +2016,Wal,19,F,0.0001002757583354224,0.0 +2016,Wal,20,M,0.0005428881650380022,0.0 +2016,Wal,20,F,0.0001032098255753948,0.0 +2016,Wal,21,M,0.0005417918534206767,0.0 +2016,Wal,21,F,0.0002059732234809475,0.0 +2016,Wal,22,M,0.0006178413573499357,0.0 +2016,Wal,22,F,0.0002005113038247531,0.0 +2016,Wal,23,M,0.0005938784833257198,0.0 +2016,Wal,23,F,0.00019105846388995032,0.0 +2016,Wal,24,M,0.000677323218639935,0.0 +2016,Wal,24,F,0.0002343127606729463,0.0 +2016,Wal,25,M,0.000743287187587104,0.000449034575662326 +2016,Wal,25,F,0.000242306760358614,0.0 +2016,Wal,26,M,0.000843644544431946,0.0004504504504504505 +2016,Wal,26,F,0.00024578479083714304,0.0 +2016,Wal,27,M,0.0008140203026240182,0.0004043671653861706 +2016,Wal,27,F,0.0002512310320570797,0.0 +2016,Wal,28,M,0.0007959407024176699,0.0003819709702062643 +2016,Wal,28,F,0.0002587054379883065,0.0 +2016,Wal,29,M,0.0008973975471133713,0.00037243947858472997 +2016,Wal,29,F,0.00031047865459249684,0.0 +2016,Wal,30,M,0.0008316008316008316,0.0003585514521333812 +2016,Wal,30,F,0.0002649708532061474,0.0 +2016,Wal,31,M,0.0008391461687732733,0.0003522367030644593 +2016,Wal,31,F,0.00037259807313567885,0.0 +2016,Wal,32,M,0.001053851828432922,0.0003469812630117973 +2016,Wal,32,F,0.00032754667540124465,0.0 +2016,Wal,33,M,0.001094890510948905,0.0006832934745473183 +2016,Wal,33,F,0.0004190236748376283,0.0 +2016,Wal,34,M,0.001131570826046703,0.0006731740154830024 +2016,Wal,34,F,0.0004072904999490887,0.0 +2016,Wal,35,M,0.001223116909591275,0.0006512536633018561 +2016,Wal,35,F,0.0005577810455859236,0.0 +2016,Wal,36,M,0.001332445036642239,0.0006583278472679394 +2016,Wal,36,F,0.0006296568370238219,0.0003176620076238882 +2016,Wal,37,M,0.001568381430363865,0.0006576783952647156 +2016,Wal,37,F,0.0007344454936522926,0.00032467532467532473 +2016,Wal,38,M,0.0016554578375582,0.001015916017609211 +2016,Wal,38,F,0.0008786437874715732,0.0003304692663582287 +2016,Wal,39,M,0.0018849661215548427,0.0007107320540156361 +2016,Wal,39,F,0.0009095043201455207,0.0003463803255975061 +2016,Wal,40,M,0.001972286841306767,0.001016260162601626 +2016,Wal,40,F,0.001000550302666467,0.0003421142661648991 +2016,Wal,41,M,0.002143205065757428,0.001263823064770932 +2016,Wal,41,F,0.001023890784982935,0.0006700167504187605 +2016,Wal,42,M,0.002390662354099283,0.001822046765866991 +2016,Wal,42,F,0.0012607985057202901,0.0009973404255319148 +2016,Wal,43,M,0.002631698352919824,0.002417648836506498 +2016,Wal,43,F,0.001490111081007857,0.000999000999000999 +2016,Wal,44,M,0.002865842736879814,0.0027289266221952697 +2016,Wal,44,F,0.00172887667346396,0.001034839599862021 +2016,Wal,45,M,0.003048225659690628,0.002140672782874618 +2016,Wal,45,F,0.0018214936247723129,0.001340482573726542 +2016,Wal,46,M,0.0031808961829245808,0.002837326607818412 +2016,Wal,46,F,0.0020065669463699377,0.001410934744268078 +2016,Wal,47,M,0.003578154425612053,0.003429996881821017 +2016,Wal,47,F,0.002300331247699669,0.001717032967032967 +2016,Wal,48,M,0.004029830006021585,0.004383218534752661 +2016,Wal,48,F,0.0024213075060532693,0.0017717930545712262 +2016,Wal,49,M,0.004559547692868867,0.004647110078419983 +2016,Wal,49,F,0.0026932399676811197,0.0017029972752043599 +2016,Wal,50,M,0.005038896746817539,0.0048120300751879706 +2016,Wal,50,F,0.002961543486781935,0.001781261132882081 +2016,Wal,51,M,0.005690390998836056,0.006054811982154238 +2016,Wal,51,F,0.003282966454817122,0.002490217004624689 +2016,Wal,52,M,0.006279296011320421,0.0060221870047543575 +2016,Wal,52,F,0.003457548981943911,0.002635542168674699 +2016,Wal,53,M,0.006855575868372943,0.006266490765171504 +2016,Wal,53,F,0.003761371588523443,0.00330988829127017 +2016,Wal,54,M,0.007688848920863309,0.007404914170313027 +2016,Wal,54,F,0.004169353105523318,0.0033003300330033012 +2016,Wal,55,M,0.008262224028172829,0.007638446849140675 +2016,Wal,55,F,0.004422647458072427,0.00416146483562214 +2016,Wal,56,M,0.009201190203707944,0.008561643835616438 +2016,Wal,56,F,0.004907190100277363,0.003502626970227671 +2016,Wal,57,M,0.00992054163336311,0.0094604064470918 +2016,Wal,57,F,0.00536228093120586,0.004963898916967509 +2016,Wal,58,M,0.01083569065541545,0.009967960128159488 +2016,Wal,58,F,0.005907626208378088,0.006066262249183389 +2016,Wal,59,M,0.011812000595563059,0.01128747795414462 +2016,Wal,59,F,0.006339216491084053,0.007557864903164856 +2016,Wal,60,M,0.01252408477842004,0.012177121771217709 +2016,Wal,60,F,0.006977277943539133,0.007770762506070908 +2016,Wal,61,M,0.013577906440539021,0.0132244262932711 +2016,Wal,61,F,0.007448353398604019,0.007881773399014778 +2016,Wal,62,M,0.0143688709423672,0.01381552214546932 +2016,Wal,62,F,0.00801526717557252,0.008447729672650475 +2016,Wal,63,M,0.015375453413458941,0.01640016400164002 +2016,Wal,63,F,0.008532423208191127,0.008537886872998933 +2016,Wal,64,M,0.016490913170293917,0.0176522506619594 +2016,Wal,64,F,0.00905724579663731,0.00921409214092141 +2016,Wal,65,M,0.01758849557522124,0.01897876186172616 +2016,Wal,65,F,0.009626472800200552,0.01071811361200429 +2016,Wal,66,M,0.01893896819152523,0.020417633410672858 +2016,Wal,66,F,0.01025537904685301,0.01018573996405033 +2016,Wal,67,M,0.02004802591165466,0.021078431372549014 +2016,Wal,67,F,0.011110562441360921,0.01163434903047092 +2016,Wal,68,M,0.021586029201259658,0.02463054187192119 +2016,Wal,68,F,0.0120870265914585,0.012812690665039659 +2016,Wal,69,M,0.023107995722941668,0.02462526766595289 +2016,Wal,69,F,0.01297175833716358,0.01257445400397088 +2016,Wal,70,M,0.02504737579302958,0.02837370242214533 +2016,Wal,70,F,0.01400579085583463,0.014095536413469069 +2016,Wal,71,M,0.02681799075241699,0.0281980742778542 +2016,Wal,71,F,0.0152117786616426,0.01630837657524092 +2016,Wal,72,M,0.0288631090487239,0.03318250377073907 +2016,Wal,72,F,0.0168054617750769,0.01767676767676768 +2016,Wal,73,M,0.031585732703051136,0.03281519861830743 +2016,Wal,73,F,0.01842330762639246,0.01835664335664336 +2016,Wal,74,M,0.03524229074889868,0.03539019963702359 +2016,Wal,74,F,0.02055498458376156,0.01992753623188406 +2016,Wal,75,M,0.03857111549419242,0.04065040650406504 +2016,Wal,75,F,0.02281528876915306,0.02391975308641975 +2016,Wal,76,M,0.04270202547504698,0.04653204565408253 +2016,Wal,76,F,0.02563305887835949,0.02442748091603054 +2016,Wal,77,M,0.04790550147653943,0.049060542797494784 +2016,Wal,77,F,0.02881821751079702,0.03023070803500398 +2016,Wal,78,M,0.05347467608951708,0.057142857142857134 +2016,Wal,78,F,0.03297448503856913,0.03330486763450043 +2016,Wal,79,M,0.05946291560102303,0.060606060606060615 +2016,Wal,79,F,0.03772272924815298,0.03985828166519044 +2016,Wal,80,M,0.06632153351056387,0.06962785114045618 +2016,Wal,80,F,0.04292513271096468,0.04533565823888405 +2016,Wal,81,M,0.07438727246667623,0.08005427408412483 +2016,Wal,81,F,0.049262888013918135,0.05357142857142857 +2016,Wal,82,M,0.08283661928778847,0.08915304606240712 +2016,Wal,82,F,0.05621952385505306,0.060634328358208964 +2016,Wal,83,M,0.09387558270374538,0.09554140127388536 +2016,Wal,83,F,0.06443039134818074,0.06680369989722508 +2016,Wal,84,M,0.1053089643167972,0.1117021276595745 +2016,Wal,84,F,0.07376256767208042,0.07833163784333673 +2016,Wal,85,M,0.1180392156862745,0.125 +2016,Wal,85,F,0.08403794596824088,0.08864864864864865 +2016,Wal,86,M,0.1323843416370107,0.1379310344827586 +2016,Wal,86,F,0.09616749467707594,0.09641532756489493 +2016,Wal,87,M,0.1463273568536727,0.1592920353982301 +2016,Wal,87,F,0.1089396540340684,0.1141975308641975 +2016,Wal,88,M,0.1611670718999653,0.1694915254237288 +2016,Wal,88,F,0.1231745095146777,0.1275590551181103 +2016,Wal,89,M,0.1768447837150127,0.175 +2016,Wal,89,F,0.1384328989676765,0.1446654611211573 +2016,Wal,90,M,0.1923656454043195,0.202970297029703 +2016,Wal,90,F,0.1556151782292066,0.158102766798419 +2016,Wal,91,M,0.2112956810631229,0.2173913043478261 +2016,Wal,91,F,0.1736334405144695,0.1861042183622829 +2016,Wal,92,M,0.2336706531738731,0.2650602409638555 +2016,Wal,92,F,0.1927814379833859,0.19375 +2016,Wal,93,M,0.2572087658592849,0.2794117647058824 +2016,Wal,93,F,0.2141084721729883,0.2377049180327869 +2016,Wal,94,M,0.28150572831423903,0.2857142857142857 +2016,Wal,94,F,0.2351587666820065,0.2469135802469136 +2016,Wal,95,M,0.3107049608355092,0.35897435897435903 +2016,Wal,95,F,0.2548543689320389,0.2622950819672132 +2016,Wal,96,M,0.3333333333333333,0.3157894736842105 +2016,Wal,96,F,0.2789115646258503,0.2906976744186047 +2016,Wal,97,M,0.3398058252427185,0.3333333333333333 +2016,Wal,97,F,0.3104265402843602,0.3428571428571429 +2016,Wal,98,M,0.339622641509434,0.25 +2016,Wal,98,F,0.3288135593220339,0.3157894736842105 +2016,Wal,99,M,0.4102564102564103,0.0 +2016,Wal,99,F,0.3509615384615385,0.4 +2016,Wal,100,M,0.4137931034482759,1.0 +2016,Wal,100,F,0.3881578947368421,0.4615384615384616 +2016,Wal,101,M,0.5,1.0 +2016,Wal,101,F,0.3971631205673759,0.3333333333333333 +2016,Wal,102,M,0.6153846153846154,1.0 +2016,Wal,102,F,0.4375,0.5 +2016,Wal,103,M,0.5,1.0 +2016,Wal,103,F,0.5348837209302325,0.5 +2016,Wal,104,M,0.0,1.0 +2016,Wal,104,F,0.625,1.0 +2016,Wal,105,M,1.0,0.0 +2016,Wal,105,F,0.5,0.0 +2016,Wal,106,M,1.0,1.0 +2016,Wal,106,F,1.0,1.0 +2016,Wal,107,M,0.0,0.0 +2016,Wal,107,F,1.0,0.0 +2016,Wal,108,M,0.0,0.0 +2016,Wal,108,F,1.0,0.0 +2016,Wal,109,M,0.0,0.0 +2016,Wal,109,F,0.0,0.0 +2016,Wal,110,M,0.0,0.0 +2016,Wal,110,F,1.0,1.0 +2016,Wal,111,M,0.0,0.0 +2016,Wal,111,F,0.0,0.0 +2016,Wal,112,M,0.0,0.0 +2016,Wal,112,F,0.0,0.0 +2016,Wal,113,M,0.0,0.0 +2016,Wal,113,F,0.0,0.0 +2016,Wal,114,M,0.0,0.0 +2016,Wal,114,F,0.0,0.0 +2016,Wal,115,M,0.0,0.0 +2016,Wal,115,F,0.0,0.0 +2016,Wal,116,M,0.0,0.0 +2016,Wal,116,F,0.0,0.0 +2016,Wal,117,M,0.0,0.0 +2016,Wal,117,F,0.0,0.0 +2016,Wal,118,M,0.0,0.0 +2016,Wal,118,F,0.0,0.0 +2016,Wal,119,M,0.0,0.0 +2016,Wal,119,F,0.0,0.0 +2016,Wal,120,M,0.0,0.0 +2016,Wal,120,F,0.0,0.0 diff --git a/larray/tests/data/test.xlsx b/larray/tests/data/test.xlsx new file mode 100644 index 000000000..8a957d23c Binary files /dev/null and b/larray/tests/data/test.xlsx differ diff --git a/larray/tests/data/test1d.csv b/larray/tests/data/test1d.csv new file mode 100644 index 000000000..16be91619 --- /dev/null +++ b/larray/tests/data/test1d.csv @@ -0,0 +1,2 @@ +a,a0,a1,a2 +,0,1,2 diff --git a/larray/tests/data/test1d_liam2.csv b/larray/tests/data/test1d_liam2.csv new file mode 100644 index 000000000..d0ab30046 --- /dev/null +++ b/larray/tests/data/test1d_liam2.csv @@ -0,0 +1,3 @@ +time,, +2007,2010,2013 +3722,3395,3347 diff --git a/larray/tests/data/test1d_narrow.csv b/larray/tests/data/test1d_narrow.csv new file mode 100644 index 000000000..eff558a1e --- /dev/null +++ b/larray/tests/data/test1d_narrow.csv @@ -0,0 +1,4 @@ +a,value +a0,0 +a1,1 +a2,2 diff --git a/larray/tests/data/test2d.csv b/larray/tests/data/test2d.csv new file mode 100644 index 000000000..cd6ae8d37 --- /dev/null +++ b/larray/tests/data/test2d.csv @@ -0,0 +1,4 @@ +a\b,b0,b1 +1,0,1 +2,2,3 +3,4,5 diff --git a/larray/tests/data/test2d_classic.csv b/larray/tests/data/test2d_classic.csv new file mode 100644 index 000000000..a5b63f948 --- /dev/null +++ b/larray/tests/data/test2d_classic.csv @@ -0,0 +1,4 @@ +a,b0,b1,b2 +a0,0,1,2 +a1,3,4,5 +a2,6,7,8 \ No newline at end of file diff --git a/larray/tests/data/test2d_narrow.csv b/larray/tests/data/test2d_narrow.csv new file mode 100644 index 000000000..2f726083e --- /dev/null +++ b/larray/tests/data/test2d_narrow.csv @@ -0,0 +1,7 @@ +a,b,value +1,b0,0 +1,b1,1 +2,b0,2 +2,b1,3 +3,b0,4 +3,b1,5 diff --git a/larray/tests/data/test3d.csv b/larray/tests/data/test3d.csv new file mode 100644 index 000000000..7816f5a64 --- /dev/null +++ b/larray/tests/data/test3d.csv @@ -0,0 +1,7 @@ +a,b\c,c0,c1,c2 +1,b0,0,1,2 +1,b1,3,4,5 +2,b0,6,7,8 +2,b1,9,10,11 +3,b0,12,13,14 +3,b1,15,16,17 diff --git a/larray/tests/data/test3d_narrow.csv b/larray/tests/data/test3d_narrow.csv new file mode 100644 index 000000000..9e3c75014 --- /dev/null +++ b/larray/tests/data/test3d_narrow.csv @@ -0,0 +1,19 @@ +a,b,c,value +1,b0,c0,0 +1,b0,c1,1 +1,b0,c2,2 +1,b1,c0,3 +1,b1,c1,4 +1,b1,c2,5 +2,b0,c0,6 +2,b0,c1,7 +2,b0,c2,8 +2,b1,c0,9 +2,b1,c1,10 +2,b1,c2,11 +3,b0,c0,12 +3,b0,c1,13 +3,b0,c2,14 +3,b1,c0,15 +3,b1,c1,16 +3,b1,c2,17 diff --git a/larray/tests/data/test5d_eurostat.csv b/larray/tests/data/test5d_eurostat.csv new file mode 100644 index 000000000..b0929d1a2 --- /dev/null +++ b/larray/tests/data/test5d_eurostat.csv @@ -0,0 +1,41 @@ +arr,age,sex,nat\time 2007 2010 2013 +1,0,F,1 3722 3395 3347 +1,0,F,2 338 316 323 +1,0,M,1 2878 2791 2822 +1,0,M,2 1121 1037 976 +1,1,F,1 4073 4161 4429 +1,1,F,2 1561 1463 1467 +1,1,M,1 3507 3741 3366 +1,1,M,2 2052 2052 2118 +1,2,F,1 4807 4868 4852 +1,2,F,2 3785 3508 3172 +1,2,M,1 4464 4692 4839 +1,2,M,2 95 100 103 +1,3,F,1 1135 1023 928 +1,3,F,2 3121 3180 2900 +1,3,M,1 3850 4118 3716 +1,3,M,2 4174 4131 4290 +1,4,F,1 4072 3775 3781 +1,4,F,2 4392 4305 4215 +1,4,M,1 1657 1492 1360 +1,4,M,2 916 973 895 +2,0,F,1 141 135 141 +2,0,F,2 3713 3952 3895 +2,0,M,1 1616 1499 1556 +2,0,M,2 1895 2029 1946 +2,1,F,1 3272 3501 3584 +2,1,F,2 793 725 679 +2,1,M,1 4766 5007 5242 +2,1,M,2 2943 2670 2525 +2,2,F,1 3594 3922 4019 +2,2,F,2 4150 3813 3576 +2,2,M,1 1264 1244 1333 +2,2,M,2 1922 1970 1972 +2,3,F,1 380 400 387 +2,3,F,2 3860 3787 3431 +2,3,M,1 2962 3112 2962 +2,3,M,2 2679 2599 2490 +2,4,F,1 4159 4210 4461 +2,4,F,2 28 27 28 +2,4,M,1 2887 2972 2837 +2,4,M,2 2712 2827 2806 \ No newline at end of file diff --git a/larray/tests/test5d.csv b/larray/tests/data/test5d_liam2.csv similarity index 91% rename from larray/tests/test5d.csv rename to larray/tests/data/test5d_liam2.csv index 98777ae04..de1e55adf 100644 --- a/larray/tests/test5d.csv +++ b/larray/tests/data/test5d_liam2.csv @@ -1,4 +1,6 @@ -arr,age,sex,nat\time,2007,2010,2013 +# a nice test array with 5 dimensions,,,,,, +arr,age,sex,nat,time,, +,,,,2007,2010,2013 1,0,F,1,3722,3395,3347 1,0,F,2,338,316,323 1,0,H,1,2878,2791,2822 diff --git a/larray/tests/data/test_blank_cells.xlsx b/larray/tests/data/test_blank_cells.xlsx new file mode 100644 index 000000000..04c9900de Binary files /dev/null and b/larray/tests/data/test_blank_cells.xlsx differ diff --git a/larray/tests/data/test_narrow.xlsx b/larray/tests/data/test_narrow.xlsx new file mode 100644 index 000000000..010c47986 Binary files /dev/null and b/larray/tests/data/test_narrow.xlsx differ diff --git a/larray/tests/data/test_session.h5 b/larray/tests/data/test_session.h5 new file mode 100644 index 000000000..d17d199b6 Binary files /dev/null and b/larray/tests/data/test_session.h5 differ diff --git a/larray/tests/data/testint_labels.csv b/larray/tests/data/testint_labels.csv new file mode 100644 index 000000000..56d877e39 --- /dev/null +++ b/larray/tests/data/testint_labels.csv @@ -0,0 +1,10 @@ +a,b\c,0,1,2 +0,0,0,1,2 +0,1,3,4,5 +0,2,6,7,8 +1,0,9,10,11 +1,1,12,13,14 +1,2,15,16,17 +2,0,18,19,20 +2,1,21,22,23 +2,2,24,25,26 diff --git a/larray/tests/data/testmissing_values.csv b/larray/tests/data/testmissing_values.csv new file mode 100644 index 000000000..f05c14ea9 --- /dev/null +++ b/larray/tests/data/testmissing_values.csv @@ -0,0 +1,5 @@ +a,b\c,c0,c1,c2 +1,b0,0,1,2 +1,b1,3,4,5 +2,b1,9,10,11 +3,b0,12,13,14 diff --git a/larray/tests/data/testmissing_values_narrow.csv b/larray/tests/data/testmissing_values_narrow.csv new file mode 100644 index 000000000..1663c2a6a --- /dev/null +++ b/larray/tests/data/testmissing_values_narrow.csv @@ -0,0 +1,12 @@ +a,b,c,value +1,b0,c0,0 +1,b0,c1,1 +1,b0,c2,2 +1,b1,c0,3 +1,b1,c1,4 +1,b1,c2,5 +2,b1,c0,9 +2,b1,c2,11 +3,b0,c0,12 +3,b0,c1,13 +3,b0,c2,14 diff --git a/larray/tests/data/testunsorted_narrow.csv b/larray/tests/data/testunsorted_narrow.csv new file mode 100644 index 000000000..295e82af8 --- /dev/null +++ b/larray/tests/data/testunsorted_narrow.csv @@ -0,0 +1,19 @@ +a,b,c,value +3,b1,c2,0 +3,b1,c1,1 +3,b1,c0,2 +3,b0,c2,3 +3,b0,c1,4 +3,b0,c0,5 +2,b1,c2,6 +2,b1,c1,7 +2,b1,c0,8 +2,b0,c2,9 +2,b0,c1,10 +2,b0,c0,11 +1,b1,c2,12 +1,b1,c1,13 +1,b1,c0,14 +1,b0,c2,15 +1,b0,c1,16 +1,b0,c0,17 diff --git a/larray/tests/test1d.csv b/larray/tests/test1d.csv deleted file mode 100644 index f711ce0f9..000000000 --- a/larray/tests/test1d.csv +++ /dev/null @@ -1,2 +0,0 @@ -time,2007,2010,2013 -,3722,3395,3347 \ No newline at end of file diff --git a/larray/tests/test1d_columns.csv b/larray/tests/test1d_columns.csv deleted file mode 100644 index 44a3415ad..000000000 --- a/larray/tests/test1d_columns.csv +++ /dev/null @@ -1,5 +0,0 @@ -age,value -0,3722 -1,338 -2,2878 -3,1121 diff --git a/larray/tests/test2d.csv b/larray/tests/test2d.csv deleted file mode 100644 index 7e83b7465..000000000 --- a/larray/tests/test2d.csv +++ /dev/null @@ -1,6 +0,0 @@ -age\time,2007,2010,2013 -0,3722,3395,3347 -1,338,316,323 -2,2878,2791,2822 -3,1121,1037,976 -4,4073,4161,4429 diff --git a/larray/tests/test3d.csv b/larray/tests/test3d.csv deleted file mode 100644 index 8242ad069..000000000 --- a/larray/tests/test3d.csv +++ /dev/null @@ -1,11 +0,0 @@ -age,sex\time,2007,2010,2013 -0,F,3722,3395,3347 -0,H,338,316,323 -1,F,2878,2791,2822 -1,H,1121,1037,976 -2,F,4073,4161,4429 -2,H,1561,1463,1467 -3,F,3507,3741,3366 -3,H,2052,2052,2118 -4,F,4807,4868,4852 -4,H,3785,3508,3172 diff --git a/larray/tests/test_array.py b/larray/tests/test_array.py new file mode 100644 index 000000000..165d833d0 --- /dev/null +++ b/larray/tests/test_array.py @@ -0,0 +1,5001 @@ +from __future__ import absolute_import, division, print_function + +import os +import sys +from unittest import TestCase + +import pytest +import numpy as np +import pandas as pd + +try: + import xlwings as xw +except ImportError: + xw = None + +from larray.tests.common import inputpath, assert_array_equal, assert_array_nan_equal, assert_larray_equiv +from larray import (LArray, Axis, LGroup, union, zeros, zeros_like, ndtest, ones, eye, diag, stack, + clip, exp, where, X, mean, isnan, round, read_hdf, read_csv, read_eurostat, read_excel, + from_lists, from_string, open_excel, from_frame, sequence, nan_equal) +from larray.inout.array import from_series +from larray.core.axis import _to_ticks, _to_key +from larray.util.misc import StringIO + + +class TestValueStrings(TestCase): + def test_split(self): + assert_array_equal(_to_ticks('M,F'), np.asarray(['M', 'F'])) + assert_array_equal(_to_ticks('M, F'), np.asarray(['M', 'F'])) + + def test_union(self): + self.assertEqual(union('A11,A22', 'A12,A22'), ['A11', 'A22', 'A12']) + + def test_range(self): + assert_array_equal(_to_ticks('0..115'), np.asarray(range(116))) + assert_array_equal(_to_ticks('..115'), np.asarray(range(116))) + with self.assertRaises(ValueError): + _to_ticks('10..') + with self.assertRaises(ValueError): + _to_ticks('..') + + +class TestKeyStrings(TestCase): + def test_nonstring(self): + self.assertEqual(_to_key(('M', 'F')), ['M', 'F']) + self.assertEqual(_to_key(['M', 'F']), ['M', 'F']) + + def test_split(self): + self.assertEqual(_to_key('M,F'), ['M', 'F']) + self.assertEqual(_to_key('M, F'), ['M', 'F']) + self.assertEqual(_to_key('M,'), ['M']) + self.assertEqual(_to_key('M'), 'M') + + def test_slice_strings(self): + # these two examples have different results and this is fine because numeric axes do not necessarily start at 0 + self.assertEqual(_to_key('0:115'), slice(0, 115)) + self.assertEqual(_to_key(':115'), slice(115)) + self.assertEqual(_to_key('10:'), slice(10, None)) + self.assertEqual(_to_key(':'), slice(None)) + + +class TestLArray(TestCase): + def setUp(self): + self.title = 'test array' + self.lipro = Axis(['P%02d' % i for i in range(1, 16)], 'lipro') + self.age = Axis('age=0..115') + self.sex = Axis('sex=M,F') + + vla = 'A11,A12,A13,A23,A24,A31,A32,A33,A34,A35,A36,A37,A38,A41,A42,A43,A44,A45,A46,A71,A72,A73' + wal = 'A25,A51,A52,A53,A54,A55,A56,A57,A61,A62,A63,A64,A65,A81,A82,A83,A84,A85,A91,A92,A93' + bru = 'A21' + self.vla_str = vla + self.wal_str = wal + # string without commas + self.bru_str = bru + # list of strings + self.belgium = union(vla, wal, bru) + + # belgium = vla + wal + bru # equivalent + # wal_bru = belgium - vla + # wal_bru = wal + bru # equivalent + + self.geo = Axis(self.belgium, 'geo') + + self.array = np.arange(116 * 44 * 2 * 15).reshape(116, 44, 2, 15).astype(float) + self.larray = LArray(self.array, axes=(self.age, self.geo, self.sex, self.lipro), title=self.title) + + self.small_title = 'small test array' + self.small_data = np.arange(30).reshape(2, 15) + self.small = LArray(self.small_data, axes=(self.sex, self.lipro), title=self.small_title) + + self.io_1d = ndtest(3) + self.io_2d = ndtest("a=1..3; b=b0,b1") + self.io_3d = ndtest("a=1..3; b=b0,b1; c=c0..c2") + self.io_int_labels = ndtest("a=0..2; b=0..2; c=0..2") + self.io_unsorted = ndtest("a=3..1; b=b1,b0; c=c2..c0") + self.io_missing_values = ndtest("a=1..3; b=b0,b1; c=c0..c2", dtype=float) + self.io_missing_values[2, 'b0'] = np.nan + self.io_missing_values[3, 'b1'] = np.nan + self.io_narrow_missing_values = self.io_missing_values.copy() + self.io_narrow_missing_values[2, 'b1', 'c1'] = np.nan + + @pytest.fixture(autouse=True) + def setup(self, tmpdir): + self.tmpdir = tmpdir.strpath + + def tmp_path(self, fname): + return os.path.join(self.tmpdir, fname) + + def test_ndrange(self): + arr = ndtest('a=a0..a2') + self.assertEqual(arr.shape, (3,)) + self.assertEqual(arr.axes.names, ['a']) + assert_array_equal(arr.data, np.arange(3)) + + # using an explicit Axis object + a = Axis('a=a0..a2') + arr = ndtest(a) + self.assertEqual(arr.shape, (3,)) + self.assertEqual(arr.axes.names, ['a']) + assert_array_equal(arr.data, np.arange(3)) + + # using a group as an axis + arr = ndtest(a[:'a1']) + self.assertEqual(arr.shape, (2,)) + self.assertEqual(arr.axes.names, ['a']) + assert_array_equal(arr.data, np.arange(2)) + + def test_getattr(self): + self.assertEqual(type(self.larray.geo), Axis) + self.assertIs(self.larray.geo, self.geo) + with self.assertRaises(AttributeError): + self.larray.geom + + def test_zeros(self): + la = zeros((self.geo, self.age)) + self.assertEqual(la.shape, (44, 116)) + assert_array_equal(la, np.zeros((44, 116))) + + def test_zeros_like(self): + la = zeros_like(self.larray) + self.assertEqual(la.shape, (116, 44, 2, 15)) + assert_array_equal(la, np.zeros((116, 44, 2, 15))) + + def test_bool(self): + a = ones([2]) + # ValueError: The truth value of an array with more than one element + # is ambiguous. Use a.any() or a.all() + self.assertRaises(ValueError, bool, a) + + a = ones([1]) + self.assertTrue(bool(a)) + + a = zeros([1]) + self.assertFalse(bool(a)) + + a = LArray(np.array(2), []) + self.assertTrue(bool(a)) + + a = LArray(np.array(0), []) + self.assertFalse(bool(a)) + + def test_iter(self): + array = self.small + l = list(array) + assert_array_equal(l[0], array['M']) + assert_array_equal(l[1], array['F']) + + def test_rename(self): + la = self.larray + new = la.rename('sex', 'gender') + # old array axes names not modified + self.assertEqual(la.axes.names, ['age', 'geo', 'sex', 'lipro']) + self.assertEqual(new.axes.names, ['age', 'geo', 'gender', 'lipro']) + + new = la.rename(self.sex, 'gender') + # old array axes names not modified + self.assertEqual(la.axes.names, ['age', 'geo', 'sex', 'lipro']) + self.assertEqual(new.axes.names, ['age', 'geo', 'gender', 'lipro']) + + def test_info(self): + expected = """\ +test array +116 x 44 x 2 x 15 + age [116]: 0 1 2 ... 113 114 115 + geo [44]: 'A11' 'A12' 'A13' ... 'A92' 'A93' 'A21' + sex [2]: 'M' 'F' + lipro [15]: 'P01' 'P02' 'P03' ... 'P13' 'P14' 'P15' +dtype: float64 +memory used: 1.17 Mb""" + self.assertEqual(self.larray.info, expected) + + def test_str(self): + lipro = self.lipro + lipro3 = lipro['P01:P03'] + sex = self.sex + + # zero dimension / scalar + self.assertEqual(str(self.small[lipro['P01'], sex['F']]), "15") + + # empty / len 0 first dimension + self.assertEqual(str(self.small[sex[[]]]), "LArray([])") + + # one dimension + self.assertEqual(str(self.small[lipro3, sex['M']]), """\ +lipro P01 P02 P03 + 0 1 2""") + # two dimensions + self.assertEqual(str(self.small.filter(lipro=lipro3)), """\ +sex\lipro P01 P02 P03 + M 0 1 2 + F 15 16 17""") + # four dimensions (too many rows) + self.assertEqual(str(self.larray.filter(lipro=lipro3)), """\ +age geo sex\lipro P01 P02 P03 + 0 A11 M 0.0 1.0 2.0 + 0 A11 F 15.0 16.0 17.0 + 0 A12 M 30.0 31.0 32.0 + 0 A12 F 45.0 46.0 47.0 + 0 A13 M 60.0 61.0 62.0 +... ... ... ... ... ... +115 A92 F 153045.0 153046.0 153047.0 +115 A93 M 153060.0 153061.0 153062.0 +115 A93 F 153075.0 153076.0 153077.0 +115 A21 M 153090.0 153091.0 153092.0 +115 A21 F 153105.0 153106.0 153107.0""") + # too many columns + self.assertEqual(str(self.larray['P01', 'A11', 'M']), """\ +age 0 1 2 3 4 5 6 7 8 ... \ + 106 107 108 109 110 111 112 113 114 115 + 0.0 1320.0 2640.0 3960.0 5280.0 6600.0 7920.0 9240.0 10560.0 ... \ +139920.0 141240.0 142560.0 143880.0 145200.0 146520.0 147840.0 149160.0 150480.0 151800.0""") + + arr = LArray([0, ''], Axis(['a0', ''], 'a')) + self.assertEqual(str(arr), "a a0 \n 0 ") + + def test_getitem(self): + raw = self.array + la = self.larray + age, geo, sex, lipro = la.axes + age159 = age[[1, 5, 9]] + lipro159 = lipro['P01,P05,P09'] + + # LGroup at "correct" place + subset = la[age159] + self.assertEqual(subset.axes[1:], (geo, sex, lipro)) + self.assertTrue(subset.axes[0].equals(Axis([1, 5, 9], 'age'))) + assert_array_equal(subset, raw[[1, 5, 9]]) + + # LGroup at "incorrect" place + assert_array_equal(la[lipro159], raw[..., [0, 4, 8]]) + + # multiple LGroup key (in "incorrect" order) + res = la[lipro159, age159] + self.assertEqual(res.axes.names, ['age', 'geo', 'sex', 'lipro']) + assert_array_equal(res, raw[[1, 5, 9]][..., [0, 4, 8]]) + + # LGroup key and scalar + res = la[lipro159, 5] + self.assertEqual(res.axes.names, ['geo', 'sex', 'lipro']) + assert_array_equal(res, raw[..., [0, 4, 8]][5]) + + # mixed LGroup/positional key + assert_array_equal(la[[1, 5, 9], lipro159], + raw[[1, 5, 9]][..., [0, 4, 8]]) + + # single None slice + assert_array_equal(la[:], raw) + + # only Ellipsis + assert_array_equal(la[...], raw) + + # Ellipsis and LGroup + assert_array_equal(la[..., lipro159], raw[..., [0, 4, 8]]) + + # string 'int..int' + assert_array_equal(la['10..13'], la['10,11,12,13']) + assert_array_equal(la['8, 10..13, 15'], la['8,10,11,12,13,15']) + + # ambiguous label + arr = ndtest("a=l0,l1;b=l1,l2") + res = arr[arr.b['l1']] + assert_array_equal(res, arr.data[:, 0]) + + # scalar group on another axis + arr = ndtest((3, 2)) + alt_a = Axis("alt_a=a1..a2") + lgroup = alt_a['a1'] + assert_array_equal(arr[lgroup], arr['a1']) + pgroup = alt_a.i[0] + assert_array_equal(arr[pgroup], arr['a1']) + + # key with duplicate axes + with self.assertRaises(ValueError): + la[age[1, 2], age[3, 4]] + + # key with lgroup from another axis leading to duplicate axis + bad = Axis(3, 'bad') + with self.assertRaises(ValueError): + la[bad[1, 2], age[3, 4]] + + def test_getitem_abstract_axes(self): + raw = self.array + la = self.larray + age, geo, sex, lipro = la.axes + age159 = X.age[1, 5, 9] + lipro159 = X.lipro['P01,P05,P09'] + + # LGroup at "correct" place + subset = la[age159] + self.assertEqual(subset.axes[1:], (geo, sex, lipro)) + self.assertTrue(subset.axes[0].equals(Axis([1, 5, 9], 'age'))) + assert_array_equal(subset, raw[[1, 5, 9]]) + + # LGroup at "incorrect" place + assert_array_equal(la[lipro159], raw[..., [0, 4, 8]]) + + # multiple LGroup key (in "incorrect" order) + assert_array_equal(la[lipro159, age159], raw[[1, 5, 9]][..., [0, 4, 8]]) + + # mixed LGroup/positional key + assert_array_equal(la[[1, 5, 9], lipro159], raw[[1, 5, 9]][..., [0, 4, 8]]) + + # single None slice + assert_array_equal(la[:], raw) + + # only Ellipsis + assert_array_equal(la[...], raw) + + # Ellipsis and LGroup + assert_array_equal(la[..., lipro159], raw[..., [0, 4, 8]]) + + # key with duplicate axes + with self.assertRaises(ValueError): + la[X.age[1, 2], X.age[3]] + + # key with invalid axis + with self.assertRaises(ValueError): + la[X.bad[1, 2], X.age[3, 4]] + + def test_getitem_anonymous_axes(self): + la = ndtest([Axis(3), Axis(4)]) + raw = la.data + assert_array_equal(la[X[0][1:]], raw[1:]) + assert_array_equal(la[X[1][2:]], raw[:, 2:]) + assert_array_equal(la[X[0][2:], X[1][1:]], raw[2:, 1:]) + assert_array_equal(la.i[2:, 1:], raw[2:, 1:]) + + def test_getitem_guess_axis(self): + raw = self.array + la = self.larray + age, geo, sex, lipro = la.axes + + # key at "correct" place + assert_array_equal(la[[1, 5, 9]], raw[[1, 5, 9]]) + subset = la[[1, 5, 9]] + self.assertEqual(subset.axes[1:], (geo, sex, lipro)) + self.assertTrue(subset.axes[0].equals(Axis([1, 5, 9], 'age'))) + assert_array_equal(subset, raw[[1, 5, 9]]) + + # key at "incorrect" place + assert_array_equal(la['P01,P05,P09'], raw[..., [0, 4, 8]]) + assert_array_equal(la[['P01', 'P05', 'P09']], raw[..., [0, 4, 8]]) + + # multiple keys (in "incorrect" order) + assert_array_equal(la['P01,P05,P09', [1, 5, 9]], + raw[[1, 5, 9]][..., [0, 4, 8]]) + + # mixed LGroup/key + assert_array_equal(la[lipro['P01,P05,P09'], [1, 5, 9]], + raw[[1, 5, 9]][..., [0, 4, 8]]) + + # single None slice + assert_array_equal(la[:], raw) + + # only Ellipsis + assert_array_equal(la[...], raw) + + # Ellipsis and LGroup + assert_array_equal(la[..., 'P01,P05,P09'], raw[..., [0, 4, 8]]) + assert_array_equal(la[..., ['P01', 'P05', 'P09']], raw[..., [0, 4, 8]]) + + # LGroup without axis (which also needs to be guessed) + g = LGroup(['P01', 'P05', 'P09']) + assert_array_equal(la[g], raw[..., [0, 4, 8]]) + + # key with duplicate axes + with self.assertRaisesRegexp(ValueError, "key has several values for axis: age"): + la[[1, 2], [3, 4]] + + # key with invalid label (ie label not found on any axis) + with self.assertRaisesRegexp(ValueError, "999 is not a valid label for any axis"): + la[[1, 2], 999] + + # key with invalid label list (ie list of labels not found on any axis) + with self.assertRaisesRegexp(ValueError, "\[998, 999\] is not a valid label for any axis"): + la[[1, 2], [998, 999]] + + # key with partial invalid list (ie list containing a label not found + # on any axis) + # FIXME: the message should be the same as for 999, 4 (ie it should NOT mention age). + with self.assertRaisesRegexp(ValueError, "age\[3, 999\] is not a valid label for any axis"): + la[[1, 2], [3, 999]] + + with self.assertRaisesRegexp(ValueError, "\[999, 4\] is not a valid label for any axis"): + la[[1, 2], [999, 4]] + + # ambiguous key + arr = ndtest("a=l0,l1;b=l1,l2") + with self.assertRaisesRegexp(ValueError, "l1 is ambiguous \(valid in a, b\)"): + arr['l1'] + + # ambiguous key disambiguated via string + res = arr['b[l1]'] + assert_array_equal(res, arr.data[:, 0]) + + def test_getitem_positional_group(self): + raw = self.array + la = self.larray + age, geo, sex, lipro = la.axes + age159 = age.i[1, 5, 9] + lipro159 = lipro.i[0, 4, 8] + + # LGroup at "correct" place + subset = la[age159] + self.assertEqual(subset.axes[1:], (geo, sex, lipro)) + self.assertTrue(subset.axes[0].equals(Axis([1, 5, 9], 'age'))) + assert_array_equal(subset, raw[[1, 5, 9]]) + + # LGroup at "incorrect" place + assert_array_equal(la[lipro159], raw[..., [0, 4, 8]]) + + # multiple LGroup key (in "incorrect" order) + assert_array_equal(la[lipro159, age159], + raw[[1, 5, 9]][..., [0, 4, 8]]) + + # mixed LGroup/positional key + assert_array_equal(la[[1, 5, 9], lipro159], + raw[[1, 5, 9]][..., [0, 4, 8]]) + + # single None slice + assert_array_equal(la[:], raw) + + # only Ellipsis + assert_array_equal(la[...], raw) + + # Ellipsis and LGroup + assert_array_equal(la[..., lipro159], raw[..., [0, 4, 8]]) + + # key with duplicate axes + with self.assertRaisesRegexp(ValueError, + "key has several values for axis: age"): + la[age.i[1, 2], age.i[3, 4]] + + def test_getitem_abstract_positional(self): + raw = self.array + la = self.larray + age, geo, sex, lipro = la.axes + age159 = X.age.i[1, 5, 9] + lipro159 = X.lipro.i[0, 4, 8] + + # LGroup at "correct" place + subset = la[age159] + self.assertEqual(subset.axes[1:], (geo, sex, lipro)) + self.assertTrue(subset.axes[0].equals(Axis([1, 5, 9], 'age'))) + assert_array_equal(subset, raw[[1, 5, 9]]) + + # LGroup at "incorrect" place + assert_array_equal(la[lipro159], raw[..., [0, 4, 8]]) + + # multiple LGroup key (in "incorrect" order) + assert_array_equal(la[lipro159, age159], + raw[[1, 5, 9]][..., [0, 4, 8]]) + + # mixed LGroup/positional key + assert_array_equal(la[[1, 5, 9], lipro159], + raw[[1, 5, 9]][..., [0, 4, 8]]) + + # single None slice + assert_array_equal(la[:], raw) + + # only Ellipsis + assert_array_equal(la[...], raw) + + # Ellipsis and LGroup + assert_array_equal(la[..., lipro159], raw[..., [0, 4, 8]]) + + # key with duplicate axes + with self.assertRaisesRegexp(ValueError, "key has several values for axis: age"): + la[X.age.i[2, 3], X.age.i[1, 5]] + + def test_getitem_bool_larray_key(self): + arr = ndtest((3, 2, 4)) + raw = arr.data + + # all dimensions + res = arr[arr < 5] + self.assertTrue(isinstance(res, LArray)) + self.assertEqual(res.ndim, 1) + assert_array_equal(res, raw[raw < 5]) + + # missing dimension + filt = arr['b1'] % 5 == 0 + res = arr[filt] + self.assertTrue(isinstance(res, LArray)) + self.assertEqual(res.ndim, 2) + self.assertEqual(res.shape, (3, 2)) + raw_key = raw[:, 1, :] % 5 == 0 + raw_d1, raw_d3 = raw_key.nonzero() + assert_array_equal(res, raw[raw_d1, :, raw_d3]) + + def test_getitem_bool_larray_and_group_key(self): + arr = ndtest((3, 6, 4)).set_labels('b', '0..5') + + # using axis + res = arr['a0,a2', arr.b < 3, 'c0:c3'] + assert isinstance(res, LArray) + assert res.ndim == 3 + assert_array_equal(res, arr['a0,a2', '0:2', 'c0:c3']) + + # using axis reference + res = arr['a0,a2', X.b < 3, 'c0:c3'] + assert isinstance(res, LArray) + assert res.ndim == 3 + assert_array_equal(res, arr['a0,a2', '0:2', 'c0:c3']) + + def test_getitem_bool_ndarray_key(self): + raw = self.array + la = self.larray + + res = la[raw < 5] + self.assertTrue(isinstance(res, LArray)) + self.assertEqual(res.ndim, 1) + assert_array_equal(res, raw[raw < 5]) + + def test_getitem_bool_anonymous_axes(self): + a = ndtest([Axis(2), Axis(3), Axis(4), Axis(5)]) + mask = ones(a.axes[1, 3], dtype=bool) + res = a[mask] + assert res.ndim == 3 + assert res.shape == (15, 2, 4) + + # XXX: we might want to transpose the result to always move combined axes to the front + a = ndtest([Axis(2), Axis(3), Axis(4), Axis(5)]) + mask = ones(a.axes[1, 2], dtype=bool) + res = a[mask] + assert res.ndim == 3 + assert res.shape == (2, 12, 5) + + def test_getitem_igroup_on_int_axis(self): + a = Axis('a=1..3') + arr = ndtest(a) + self.assertEqual(arr[a.i[1]], 1) + + def test_getitem_int_larray_lgroup_key(self): + # e axis go from 0 to 3 + arr = ndtest("c=0,1; d=0,1; e=0..3") + # key values go from 0 to 3 + key = ndtest("a=0,1; b=0,1") + # this replaces 'e' axis by 'a' and 'b' axes + res = arr[X.e[key]] + self.assertEqual(res.shape, (2, 2, 2, 2)) + self.assertEqual(res.axes.names, ['c', 'd', 'a', 'b']) + + def test_getitem_structured_key_with_groups(self): + arr = ndtest((3, 2)) + expected = arr['a1':] + + a, b = arr.axes + alt_a = Axis('a=a1..a3') + + # a) slice with lgroup + # a.1) LGroup.axis from array.axes + assert_array_equal(arr[a['a1']:a['a2']], expected) + + # a.2) LGroup.axis not from array.axes + assert_array_equal((arr[alt_a['a1']:alt_a['a2']]), expected) + + # b) slice with igroup + # b.1) IGroup.axis from array.axes + assert_array_equal((arr[a.i[1]:a.i[2]]), expected) + + # b.2) IGroup.axis not from array.axes + assert_array_equal((arr[alt_a.i[0]:alt_a.i[1]]), expected) + + # c) list with LGroup + # c.1) LGroup.axis from array.axes + assert_array_equal((arr[[a['a1'], a['a2']]]), expected) + + # c.2) LGroup.axis not from array.axes + assert_array_equal((arr[[alt_a['a1'], alt_a['a2']]]), expected) + + # d) list with IGroup + # d.1) IGroup.axis from array.axes + assert_array_equal((arr[[a.i[1], a.i[2]]]), expected) + + # d.2) IGroup.axis not from array.axes + assert_array_equal((arr[[alt_a.i[0], alt_a.i[1]]]), expected) + + def test_getitem_single_larray_key_guess(self): + a = Axis(['a1', 'a2'], 'a') + b = Axis(['b1', 'b2', 'b3'], 'b') + c = Axis(['c1', 'c2', 'c3', 'c4'], 'c') + + # 1) key with extra axis + arr = ndtest([a, b]) + # replace the values_axis by the extra axis + key = LArray(['a1', 'a2', 'a2', 'a1'], [c]) + self.assertEqual(arr[key].axes, [c, b]) + + # 2) key with the values axis (the one being replaced) + arr = ndtest([a, b]) + key = LArray(['b2', 'b1', 'b3'], [b]) + # axis stays the same but data should be flipped/shuffled + self.assertEqual(arr[key].axes, [a, b]) + + # 2bis) key with part of the values axis (the one being replaced) + arr = ndtest([a, b]) + b_bis = Axis(['b1', 'b2'], 'b') + key = LArray(['b3', 'b2'], [b_bis]) + self.assertEqual(arr[key].axes, [a, b_bis]) + + # 3) key with another existing axis (not the values axis) + # arr = ndtest([a, b]) + # key = LArray(['a1', 'a2', 'a1'], [b]) + # # we need points indexing + # # equivalent to + # # tmp = arr[x.a['a1', 'a2', 'a1'] ^ x.b['b1', 'b2', 'b3']] + # # res = tmp.set_axes([b]) + # # both the values axis and the other existing axis + # self.assertEqual(arr[key].axes, [b]) + # + # # 3bis) key with part of another existing axis (not the values axis) + # arr = ndtest([a, b]) + # b_bis = Axis('b', ['b1', 'b2']) + # key = LArray(['a2', 'a1'], [b_bis]) + # # we need points indexing + # # equivalent to + # # tmp = arr[x.a['a2', 'a1'] ^ x.b['b1', 'b2']] + # # res = tmp.set_axes([b_bis]) + # self.assertEqual(arr[key].axes, [b_bis]) + # + # # 4) key has both the values axis and another existing axis + # # a\b b1 b2 b3 + # # a1 0 1 2 + # # a2 3 4 5 + # arr = ndtest([a, b]) + # # a\b b1 b2 b3 + # # a1 a1 a2 a1 + # # a2 a2 a1 a2 + # key = LArray([['a1', 'a2', 'a1'], + # ['a2', 'a1', 'a2']], + # [a, b]) + # # a\b b1 b2 b3 + # # a1 0 4 2 + # # a2 3 1 5 + # # we need to produce the following keys for numpy: + # # k0: + # # [[0, 1, 0], + # # [1, 0, 1]] + # # TODO: [0, 1, 2] is enough in this case (thanks to broadcasting) because in numpy missing dimensions are + # # filled by adding length 1 dimensions to the left. Ie it works because b is the last dimension. + # # k1: + # # [[0, 1, 2], + # # [0, 1, 2]] + # + # # we need points indexing + # # equivalent to + # # tmp = arr[x.a[['a1', 'a2', 'a1'], + # # ['a2', 'a1', 'a2']] ^ x.b['b1', 'b2', 'b3']] + # # res = tmp.set_axes([a, b]) + # # this is kinda ugly because a ND x.a has implicit (positional dimension + # res = arr[key] + # self.assertEqual(res.axes, [a, b]) + # assert_array_equal(res, [[0, 4, 2], + # [3, 1, 5]]) + # + # # 5) key has both the values axis and an extra axis + # arr = ndtest([a, b]) + # key = LArray([['a1', 'a2', 'a2', 'a1'], ['a2', 'a1', 'a1', 'a2']], + # [a, c]) + # self.assertEqual(arr[key].axes, [a, c]) + # + # # 6) key has both another existing axis (not values) and an extra axis + # arr = ndtest([a, b]) + # key = LArray([['b1', 'b2', 'b1', 'b2'], ['b3', 'b4', 'b3', 'b4']], + # [a, c]) + # self.assertEqual(arr[key].axes, [a, c]) + # + # # 7) key has the values axis, another existing axis and an extra axis + # arr = ndtest([a, b]) + # key = LArray([[['a1', 'a2', 'a1', 'a2'], + # ['a2', 'a1', 'a2', 'a1'], + # ['a1', 'a2', 'a1', 'a2']], + # + # [['a1', 'a2', 'a2', 'a1'], + # ['a2', 'a2', 'a2', 'a2'], + # ['a1', 'a2', 'a2', 'a1']]], + # [a, b, c]) + # self.assertEqual(arr[key].axes, [a, c]) + # + # def test_getitem_multiple_larray_key_guess(self): + # a = Axis('a', ['a1', 'a2']) + # b = Axis('b', ['b1', 'b2', 'b3']) + # c = Axis('c', ['c1', 'c2', 'c3', 'c4']) + # d = Axis('d', ['d1', 'd2', 'd3', 'd4', 'd5']) + # e = Axis('e', ['e1', 'e2', 'e3', 'e4', 'e5', 'e6']) + # + # # 1) key with extra disjoint axes + # arr = ndtest([a, b]) + # k1 = LArray(['a1', 'a2', 'a2', 'a1'], [c]) + # k2 = LArray(['b1', 'b2', 'b3', 'b1'], [d]) + # self.assertEqual(arr[k1, k2].axes, [c, d]) + # + # # 2) key with common extra axes + # arr = ndtest([a, b]) + # k1 = LArray(['a1', 'a2', 'a2', 'a1'], [c, d]) + # k2 = LArray(['b1', 'b2', 'b3', 'b1'], [c, e]) + # # TODO: not sure what *should* happen in this case! + # self.assertEqual(arr[k1, k2].axes, [c, d, e]) + + def test_getitem_ndarray_key_guess(self): + raw = self.array + la = self.larray + keys = ['P04', 'P01', 'P03', 'P02'] + key = np.array(keys) + res = la[key] + self.assertTrue(isinstance(res, LArray)) + self.assertEqual(res.axes, la.axes.replace(X.lipro, Axis(keys, 'lipro'))) + assert_array_equal(res, raw[:, :, :, [3, 0, 2, 1]]) + + def test_getitem_int_larray_key_guess(self): + a = Axis([0, 1], 'a') + b = Axis([2, 3], 'b') + c = Axis([4, 5], 'c') + d = Axis([6, 7], 'd') + e = Axis([8, 9, 10, 11], 'e') + + arr = ndtest([c, d, e]) + key = LArray([[8, 9], [10, 11]], [a, b]) + self.assertEqual(arr[key].axes, [c, d, a, b]) + + def test_getitem_int_ndarray_key_guess(self): + c = Axis([4, 5], 'c') + d = Axis([6, 7], 'd') + e = Axis([8, 9, 10, 11], 'e') + + arr = ndtest([c, d, e]) + # ND keys do not work yet + # key = np.array([[8, 11], [10, 9]]) + key = np.array([8, 11, 10]) + res = arr[key] + self.assertEqual(res.axes, [c, d, Axis([8, 11, 10], 'e')]) + + def test_getitem_axis_object(self): + arr = ndtest((2, 3)) + a, b = arr.axes + + assert_array_equal(arr[a], arr) + assert_array_equal(arr[b], arr) + + b2 = Axis('b=b0,b2') + + assert_array_equal(arr[b2], from_string("""a\\b b0 b2 + a0 0 2 + a1 3 5""")) + + def test_positional_indexer_getitem(self): + raw = self.array + la = self.larray + for key in [0, (0, 5, 1, 2), (slice(None), 5, 1), (0, 5), [1, 0], ([1, 0], 5)]: + assert_array_equal(la.i[key], raw[key]) + assert_array_equal(la.i[[1, 0], [5, 4]], raw[np.ix_([1, 0], [5, 4])]) + with self.assertRaises(IndexError): + la.i[0, 0, 0, 0, 0] + + def test_positional_indexer_setitem(self): + for key in [0, (0, 2, 1, 2), (slice(None), 2, 1), (0, 2), [1, 0], ([1, 0], 2)]: + la = self.larray.copy() + raw = self.array.copy() + la.i[key] = 42 + raw[key] = 42 + assert_array_equal(la, raw) + + la = self.larray.copy() + raw = self.array.copy() + la.i[[1, 0], [5, 4]] = 42 + raw[np.ix_([1, 0], [5, 4])] = 42 + assert_array_equal(la, raw) + + def test_points_indexer_getitem(self): + arr = ndtest((2, 3, 3)) + raw = arr.data + + keys = [ + ('a0', + 0), + (('a0', 'c2'), + (0, slice(None), 2)), + (('a0', 'b1', 'c2'), + (0, 1, 2)), + # key in the "correct" order + ((['a1', 'a0', 'a1', 'a0'], 'b1', ['c1', 'c0', 'c1', 'c0']), + ([1, 0, 1, 0], 1, [1, 0, 1, 0])), + # key in the "wrong" order + ((['a1', 'a0', 'a1', 'a0'], ['c1', 'c0', 'c1', 'c0'], 'b1'), + ([1, 0, 1, 0], 1, [1, 0, 1, 0])), + # advanced key with a missing dimension + ((['a1', 'a0', 'a1', 'a0'], ['c1', 'c0', 'c1', 'c0']), + ([1, 0, 1, 0], slice(None), [1, 0, 1, 0])), + ] + for label_key, index_key in keys: + assert_array_equal(arr.points[label_key], raw[index_key]) + + # XXX: we might want to raise KeyError or IndexError instead? + with self.assertRaises(ValueError): + arr.points['a0', 'b1', 'c2', 'd0'] + + def test_points_indexer_setitem(self): + keys = [ + ('a0', + 0), + (('a0', 'c2'), + (0, slice(None), 2)), + (('a0', 'b1', 'c2'), + (0, 1, 2)), + # key in the "correct" order + ((['a1', 'a0', 'a1', 'a0'], 'b1', ['c1', 'c0', 'c1', 'c0']), + ([1, 0, 1, 0], 1, [1, 0, 1, 0])), + # key in the "wrong" order + ((['a1', 'a0', 'a1', 'a0'], ['c1', 'c0', 'c1', 'c0'], 'b1'), + ([1, 0, 1, 0], 1, [1, 0, 1, 0])), + # advanced key with a missing dimension + ((['a1', 'a0', 'a1', 'a0'], ['c1', 'c0', 'c1', 'c0']), + ([1, 0, 1, 0], slice(None), [1, 0, 1, 0])), + ] + for label_key, index_key in keys: + arr = ndtest((2, 3, 3)) + raw = arr.data.copy() + arr.points[label_key] = 42 + raw[index_key] = 42 + assert_array_equal(arr, raw) + + arr = ndtest(2) + # XXX: we might want to raise KeyError or IndexError instead? + with self.assertRaises(ValueError): + arr.points['a0', 'b1'] = 42 + + # test when broadcasting is involved + arr = ndtest((2, 3, 4)) + data = arr.data.copy() + value = data[:, 0, 0].reshape(2, 1) + data[:, [0, 1, 2], [0, 1, 2]] = value + arr.points['b0,b1,b2', 'c0,c1,c2'] = arr['b0', 'c0'] + assert_array_equal(arr, data) + + def test_setitem_larray(self): + """ + tests LArray.__setitem__(key, value) where value is an LArray + """ + age, geo, sex, lipro = self.larray.axes + + # 1) using a LGroup key + ages1_5_9 = age[[1, 5, 9]] + + # a) value has exactly the same shape as the target slice + la = self.larray.copy() + raw = self.array.copy() + + la[ages1_5_9] = la[ages1_5_9] + 25.0 + raw[[1, 5, 9]] = raw[[1, 5, 9]] + 25.0 + assert_array_equal(la, raw) + + # b) value has exactly the same shape but LGroup at a "wrong" positions + la = self.larray.copy() + la[geo[:], ages1_5_9] = la[ages1_5_9] + 25.0 + # same raw as previous test + assert_array_equal(la, raw) + + # c) value has an extra length-1 axis + la = self.larray.copy() + raw = self.array.copy() + + raw_value = raw[[1, 5, 9], np.newaxis] + 26.0 + fake_axis = Axis(['label'], 'fake') + age_axis = la[ages1_5_9].axes.age + value = LArray(raw_value, axes=(age_axis, fake_axis, self.geo, self.sex, self.lipro)) + la[ages1_5_9] = value + raw[[1, 5, 9]] = raw[[1, 5, 9]] + 26.0 + assert_array_equal(la, raw) + + # d) value has the same axes than target but one has length 1 + # la = self.larray.copy() + # raw = self.array.copy() + # raw[[1, 5, 9]] = np.sum(raw[[1, 5, 9]], axis=1, keepdims=True) + # la[ages1_5_9] = la[ages1_5_9].sum(geo=(geo.all(),)) + # assert_array_equal(la, raw) + + # e) value has a missing dimension + la = self.larray.copy() + raw = self.array.copy() + la[ages1_5_9] = la[ages1_5_9].sum(geo) + raw[[1, 5, 9]] = np.sum(raw[[1, 5, 9]], axis=1, keepdims=True) + assert_array_equal(la, raw) + + # 2) using a LGroup and scalar key (triggers advanced indexing/cross) + + # a) value has exactly the same shape as the target slice + la = self.larray.copy() + raw = self.array.copy() + + # using 1, 5, 8 and not 9 so that the list is not collapsed to slice + value = la[age[1, 5, 8], sex['M']] + 25.0 + la[age[1, 5, 8], sex['M']] = value + raw[[1, 5, 8], :, 0] = raw[[1, 5, 8], :, 0] + 25.0 + assert_array_equal(la, raw) + + # 3) using a string key + la = self.larray.copy() + raw = self.array.copy() + la['1, 5, 9'] = la['1, 5, 9'] + 27.0 + raw[[1, 5, 9]] = raw[[1, 5, 9]] + 27.0 + assert_array_equal(la, raw) + + # 4) using ellipsis keys + # only Ellipsis + la = self.larray.copy() + la[...] = 0 + assert_array_equal(la, np.zeros_like(raw)) + + # Ellipsis and LGroup + la = self.larray.copy() + raw = self.array.copy() + la[..., lipro['P01,P05,P09']] = 0 + raw[..., [0, 4, 8]] = 0 + assert_array_equal(la, raw) + + # 5) using a single slice(None) key + la = self.larray.copy() + la[:] = 0 + assert_array_equal(la, np.zeros_like(raw)) + + # 6) incompatible axes + la = self.small.copy() + la2 = la.copy() + + with pytest.raises(ValueError, match="Value {!s} axis is not present in target subset {!s}. " + "A value can only have the same axes or fewer axes than the subset " + "being targeted".format(la2.axes - la['P01'].axes, la['P01'].axes)): + la['P01'] = la2 + + la2 = la.rename('sex', 'gender') + with pytest.raises(ValueError, match="Value {!s} axis is not present in target subset {!s}. " + "A value can only have the same axes or fewer axes than the subset " + "being targeted".format(la2['P01'].axes - la['P01'].axes, la['P01'].axes)): + la['P01'] = la2['P01'] + + # 7) incompatible labels + sex2 = Axis('sex=F,M') + la2 = LArray(self.small_data, axes=(sex2, self.lipro)) + with pytest.raises(ValueError, match="incompatible axes:"): + la[:] = la2 + + def test_setitem_ndarray(self): + """ + tests LArray.__setitem__(key, value) where value is a raw ndarray. + In that case, value.shape is more restricted as we rely on numpy broadcasting. + """ + # a) value has exactly the same shape as the target slice + la = self.larray.copy() + raw = self.array.copy() + value = raw[[1, 5, 9]] + 25.0 + la[[1, 5, 9]] = value + raw[[1, 5, 9]] = value + assert_array_equal(la, raw) + + # b) value has the same axes than target but one has length 1 + la = self.larray.copy() + raw = self.array.copy() + value = np.sum(raw[[1, 5, 9]], axis=1, keepdims=True) + la[[1, 5, 9]] = value + raw[[1, 5, 9]] = value + assert_array_equal(la, raw) + + def test_setitem_scalar(self): + """ + tests LArray.__setitem__(key, value) where value is a scalar + """ + # a) list key (one dimension) + la = self.larray.copy() + raw = self.array.copy() + la[[1, 5, 9]] = 42 + raw[[1, 5, 9]] = 42 + assert_array_equal(la, raw) + + # b) full scalar key (ie set one cell) + la = self.larray.copy() + raw = self.array.copy() + la[0, 'P02', 'A12', 'M'] = 42 + raw[0, 1, 0, 1] = 42 + assert_array_equal(la, raw) + + def test_setitem_bool_array_key(self): + # XXX: this test is awfully slow (more than 1s) + age, geo, sex, lipro = self.larray.axes + + # LArray key + # a1) same shape, same order + la = self.larray.copy() + raw = self.array.copy() + la[la < 5] = 0 + raw[raw < 5] = 0 + assert_array_equal(la, raw) + + # a2) same shape, different order + la = self.larray.copy() + raw = self.array.copy() + key = (la < 5).T + la[key] = 0 + raw[raw < 5] = 0 + assert_array_equal(la, raw) + + # b) numpy-broadcastable shape + # la = self.larray.copy() + # raw = self.array.copy() + # key = la[sex['F,']] < 5 + # self.assertEqual(key.ndim, 4) + # la[key] = 0 + # raw[raw[:, :, [1]] < 5] = 0 + # assert_array_equal(la, raw) + + # c) LArray-broadcastable shape (missing axis) + la = self.larray.copy() + raw = self.array.copy() + key = la[sex['M']] < 5 + self.assertEqual(key.ndim, 3) + la[key] = 0 + + raw_key = raw[:, :, 0, :] < 5 + raw_d1, raw_d2, raw_d4 = raw_key.nonzero() + raw[raw_d1, raw_d2, :, raw_d4] = 0 + assert_array_equal(la, raw) + + # ndarray key + la = self.larray.copy() + raw = self.array.copy() + la[raw < 5] = 0 + raw[raw < 5] = 0 + assert_array_equal(la, raw) + + # d) LArray with extra axes + la = self.larray.copy() + raw = self.array.copy() + key = (la < 5).expand([Axis(2, 'extra')]) + self.assertEqual(key.ndim, 5) + # TODO: make this work + with self.assertRaises(ValueError): + la[key] = 0 + + def test_set(self): + age, geo, sex, lipro = self.larray.axes + + # 1) using a LGroup key + ages1_5_9 = age[[1, 5, 9]] + + # a) value has exactly the same shape as the target slice + la = self.larray.copy() + raw = self.array.copy() + + la.set(la[ages1_5_9] + 25.0, age=ages1_5_9) + raw[[1, 5, 9]] = raw[[1, 5, 9]] + 25.0 + assert_array_equal(la, raw) + + # b) same size but a different shape (extra length-1 axis) + la = self.larray.copy() + raw = self.array.copy() + + raw_value = raw[[1, 5, 9], np.newaxis] + 26.0 + fake_axis = Axis(['label'], 'fake') + age_axis = la[ages1_5_9].axes.age + value = LArray(raw_value, axes=(age_axis, fake_axis, self.geo, self.sex, self.lipro)) + la.set(value, age=ages1_5_9) + raw[[1, 5, 9]] = raw[[1, 5, 9]] + 26.0 + assert_array_equal(la, raw) + + # dimension of length 1 + # la = self.larray.copy() + # raw = self.array.copy() + # raw[[1, 5, 9]] = np.sum(raw[[1, 5, 9]], axis=1, keepdims=True) + # la.set(la[ages1_5_9].sum(geo=(geo.all(),)), age=ages1_5_9) + # assert_array_equal(la, raw) + + # c) missing dimension + la = self.larray.copy() + raw = self.array.copy() + la.set(la[ages1_5_9].sum(geo), age=ages1_5_9) + raw[[1, 5, 9]] = np.sum(raw[[1, 5, 9]], axis=1, keepdims=True) + assert_array_equal(la, raw) + + # 2) using a raw key + la = self.larray.copy() + raw = self.array.copy() + la.set(la[[1, 5, 9]] + 27.0, age=[1, 5, 9]) + raw[[1, 5, 9]] = raw[[1, 5, 9]] + 27.0 + assert_array_equal(la, raw) + + def test_filter(self): + la = self.larray + age, geo, sex, lipro = la.axes + + ages1_5_9 = age[(1, 5, 9)] + ages11 = age[11] + + # with LGroup + self.assertEqual(la.filter(age=ages1_5_9).shape, (3, 44, 2, 15)) + + # FIXME: this should raise a comprehensible error! + # self.assertEqual(la.filter(age=[ages1_5_9]).shape, (3, 44, 2, 15)) + + # LGroup with 1 value => collapse + self.assertEqual(la.filter(age=ages11).shape, (44, 2, 15)) + + # LGroup with a list of 1 value => do not collapse + self.assertEqual(la.filter(age=age[[11]]).shape, (1, 44, 2, 15)) + + # LGroup with a list of 1 value defined as a string => do not collapse + self.assertEqual(la.filter(lipro=lipro['P01,']).shape, (116, 44, 2, 1)) + + # LGroup with 1 value + # XXX: this does not work. Do we want to make this work? + # filtered = la.filter(age=(ages11,)) + # self.assertEqual(filtered.shape, (1, 44, 2, 15)) + + # list + self.assertEqual(la.filter(age=[1, 5, 9]).shape, (3, 44, 2, 15)) + + # string + self.assertEqual(la.filter(lipro='P01,P02').shape, (116, 44, 2, 2)) + + # multiple axes at once + self.assertEqual(la.filter(age=[1, 5, 9], lipro='P01,P02').shape, (3, 44, 2, 2)) + + # multiple axes one after the other + self.assertEqual(la.filter(age=[1, 5, 9]).filter(lipro='P01,P02').shape, (3, 44, 2, 2)) + + # a single value for one dimension => collapse the dimension + self.assertEqual(la.filter(sex='M').shape, (116, 44, 15)) + + # but a list with a single value for one dimension => do not collapse + self.assertEqual(la.filter(sex=['M']).shape, (116, 44, 1, 15)) + + self.assertEqual(la.filter(sex='M,').shape, (116, 44, 1, 15)) + + # with duplicate keys + # XXX: do we want to support this? I don't see any value in that but I might be short-sighted. + # filtered = la.filter(lipro='P01,P02,P01') + + # XXX: we could abuse python to allow naming groups via Axis.__getitem__ + # (but I doubt it is a good idea). + # child = age[':17', 'child'] + + # slices + # ------ + + # LGroup slice + self.assertEqual(la.filter(age=age[:17]).shape, (18, 44, 2, 15)) + # string slice + self.assertEqual(la.filter(lipro=':P03').shape, (116, 44, 2, 3)) + # raw slice + self.assertEqual(la.filter(age=slice(17)).shape, (18, 44, 2, 15)) + + # filter chain with a slice + self.assertEqual(la.filter(age=slice(17)).filter(geo='A12,A13').shape, (18, 2, 2, 15)) + + def test_filter_multiple_axes(self): + la = self.larray + + # multiple values in each group + self.assertEqual(la.filter(age=[1, 5, 9], lipro='P01,P02').shape, (3, 44, 2, 2)) + # with a group of one value + self.assertEqual(la.filter(age=[1, 5, 9], sex='M,').shape, (3, 44, 1, 15)) + + # with a discarded axis (there is a scalar in the key) + self.assertEqual(la.filter(age=[1, 5, 9], sex='M').shape, (3, 44, 15)) + + # with a discarded axis that is not adjacent to the ix_array axis ie with a sliced axis between the scalar axis + # and the ix_array axis since our array has a axes: age, geo, sex, lipro, any of the following should be tested: + # age+sex / age+lipro / geo+lipro + # additionally, if the ix_array axis was first (ie ix_array on age), it worked even before the issue was fixed, + # since the "indexing" subspace is tacked-on to the beginning (as the first dimension) + self.assertEqual(la.filter(age=57, sex='M,F').shape, (44, 2, 15)) + self.assertEqual(la.filter(age=57, lipro='P01,P05').shape, (44, 2, 2)) + self.assertEqual(la.filter(geo='A57', lipro='P01,P05').shape, (116, 2, 2)) + + def test_contains(self): + arr = ndtest('a=0..2;b=b0..b2;c=2..4') + # string label + assert 'b1' in arr + assert not 'b4' in arr + # int label + assert 1 in arr + assert 5 not in arr + # duplicate label + assert 2 in arr + # slice + assert not slice('b0', 'b2') in arr + + def test_sum_full_axes(self): + la = self.larray + age, geo, sex, lipro = la.axes + + # everything + self.assertEqual(la.sum(), np.asarray(la).sum()) + + # using axes numbers + self.assertEqual(la.sum(axis=2).shape, (116, 44, 15)) + self.assertEqual(la.sum(axis=(0, 2)).shape, (44, 15)) + + # using Axis objects + self.assertEqual(la.sum(age).shape, (44, 2, 15)) + self.assertEqual(la.sum(age, sex).shape, (44, 15)) + + # using axes names + self.assertEqual(la.sum('age', 'sex').shape, (44, 15)) + + # chained sum + self.assertEqual(la.sum(age, sex).sum(geo).shape, (15,)) + self.assertEqual(la.sum(age, sex).sum(lipro, geo), la.sum()) + + # getitem on aggregated + aggregated = la.sum(age, sex) + self.assertEqual(aggregated[self.vla_str].shape, (22, 15)) + + # filter on aggregated + self.assertEqual(aggregated.filter(geo=self.vla_str).shape, (22, 15)) + + def test_sum_full_axes_with_nan(self): + la = self.larray.copy() + la['M', 'P02', 'A12', 0] = np.nan + raw = la.data + + # everything + self.assertEqual(la.sum(), np.nansum(raw)) + self.assertTrue(isnan(la.sum(skipna=False))) + + # using Axis objects + assert_array_nan_equal(la.sum(X.age), np.nansum(raw, 0)) + assert_array_nan_equal(la.sum(X.age, skipna=False), raw.sum(0)) + + assert_array_nan_equal(la.sum(X.age, X.sex), np.nansum(raw, (0, 2))) + assert_array_nan_equal(la.sum(X.age, X.sex, skipna=False), raw.sum((0, 2))) + + def test_sum_full_axes_keep_axes(self): + la = self.larray + agg = la.sum(keepaxes=True) + self.assertEqual(agg.shape, (1, 1, 1, 1)) + for axis in agg.axes: + self.assertEqual(axis.labels, ['sum']) + + agg = la.sum(keepaxes='total') + self.assertEqual(agg.shape, (1, 1, 1, 1)) + for axis in agg.axes: + self.assertEqual(axis.labels, ['total']) + + def test_mean_full_axes(self): + la = self.larray + raw = self.array + + self.assertEqual(la.mean(), np.mean(raw)) + assert_array_nan_equal(la.mean(X.age), np.mean(raw, 0)) + assert_array_nan_equal(la.mean(X.age, X.sex), np.mean(raw, (0, 2))) + + def test_mean_groups(self): + # using int type to test that we get a float in return + la = self.larray.astype(int) + raw = self.array + res = la.mean(X.geo['A11', 'A13', 'A24', 'A31']) + assert_array_nan_equal(res, np.mean(raw[:, [0, 2, 4, 5]], 1)) + + def test_median_full_axes(self): + la = self.larray + raw = self.array + + self.assertEqual(la.median(), np.median(raw)) + assert_array_nan_equal(la.median(X.age), np.median(raw, 0)) + assert_array_nan_equal(la.median(X.age, X.sex), np.median(raw, (0, 2))) + + def test_median_groups(self): + la = self.larray + raw = self.array + + res = la.median(X.geo['A11', 'A13', 'A24']) + self.assertEqual(res.shape, (116, 2, 15)) + assert_array_nan_equal(res, np.median(raw[:, [0, 2, 4]], 1)) + + def test_percentile_full_axes(self): + arr = ndtest((2, 3, 4)) + raw = arr.data + self.assertEqual(arr.percentile(10), np.percentile(raw, 10)) + assert_array_nan_equal(arr.percentile(10, X.a), np.percentile(raw, 10, 0)) + assert_array_nan_equal(arr.percentile(10, X.c, X.a), np.percentile(raw, 10, (2, 0))) + + def test_percentile_groups(self): + arr = ndtest((2, 5, 3)) + raw = arr.data + + res = arr.percentile(10, X.b['b0', 'b2', 'b4']) + assert_array_nan_equal(res, np.percentile(raw[:, [0, 2, 4]], 10, 1)) + + def test_cumsum(self): + la = self.larray + + # using Axis objects + assert_array_equal(la.cumsum(X.age), self.array.cumsum(0)) + assert_array_equal(la.cumsum(X.lipro), self.array.cumsum(3)) + + # using axes numbers + assert_array_equal(la.cumsum(1), self.array.cumsum(1)) + + # using axes names + assert_array_equal(la.cumsum('sex'), self.array.cumsum(2)) + + def test_group_agg_kwargs(self): + la = self.larray + age, geo, sex, lipro = la.axes + vla, wal, bru = self.vla_str, self.wal_str, self.bru_str + belgium = self.belgium + + # a) group aggregate on a fresh array + + # a.1) one group => collapse dimension + self.assertEqual(la.sum(sex='M').shape, (116, 44, 15)) + self.assertEqual(la.sum(sex='M,F').shape, (116, 44, 15)) + self.assertEqual(la.sum(sex=sex['M']).shape, (116, 44, 15)) + + self.assertEqual(la.sum(geo='A11,A21,A25').shape, (116, 2, 15)) + self.assertEqual(la.sum(geo=['A11', 'A21', 'A25']).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo=geo['A11,A21,A25']).shape, (116, 2, 15)) + + self.assertEqual(la.sum(geo=':').shape, (116, 2, 15)) + self.assertEqual(la.sum(geo=geo[:]).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo=geo[':']).shape, (116, 2, 15)) + # Include everything between two labels. Since A11 is the first label + # and A21 is the last one, this should be equivalent to the previous + # tests. + self.assertEqual(la.sum(geo='A11:A21').shape, (116, 2, 15)) + assert_array_equal(la.sum(geo='A11:A21'), la.sum(geo=':')) + assert_array_equal(la.sum(geo=geo['A11:A21']), la.sum(geo=':')) + + # a.2) a tuple of one group => do not collapse dimension + self.assertEqual(la.sum(geo=(geo[:],)).shape, (116, 1, 2, 15)) + + # a.3) several groups + # string groups + self.assertEqual(la.sum(geo=(vla, wal, bru)).shape, (116, 3, 2, 15)) + # with one label in several groups + self.assertEqual(la.sum(sex=(['M'], ['M', 'F'])).shape, (116, 44, 2, 15)) + self.assertEqual(la.sum(sex=('M', 'M,F')).shape, (116, 44, 2, 15)) + self.assertEqual(la.sum(sex='M;M,F').shape, (116, 44, 2, 15)) + + res = la.sum(geo=(vla, wal, bru, belgium)) + self.assertEqual(res.shape, (116, 4, 2, 15)) + + # a.4) several dimensions at the same time + res = la.sum(lipro='P01,P03;P02,P05;:', geo=(vla, wal, bru, belgium)) + self.assertEqual(res.shape, (116, 4, 2, 3)) + + # b) both axis aggregate and group aggregate at the same time + # Note that you must list "full axes" aggregates first (Python does not allow non-kwargs after kwargs. + res = la.sum(age, sex, geo=(vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 15)) + + # c) chain group aggregate after axis aggregate + res = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 15)) + + def test_group_agg_guess_axis(self): + la = self.larray + raw = self.array + age, geo, sex, lipro = la.axes + vla, wal, bru = self.vla_str, self.wal_str, self.bru_str + belgium = self.belgium + + # a) group aggregate on a fresh array + + # a.1) one group => collapse dimension + # not sure I should support groups with a single item in an aggregate + self.assertEqual(la.sum('M').shape, (116, 44, 15)) + self.assertEqual(la.sum('M,').shape, (116, 44, 15)) + self.assertEqual(la.sum('M,F').shape, (116, 44, 15)) + + self.assertEqual(la.sum('A11,A21,A25').shape, (116, 2, 15)) + # with a name + self.assertEqual(la.sum('A11,A21,A25 >> g1').shape, (116, 2, 15)) + self.assertEqual(la.sum(['A11', 'A21', 'A25']).shape, (116, 2, 15)) + + # Include everything between two labels. Since A11 is the first label + # and A21 is the last one, this should be equivalent to taking the + # full axis. + self.assertEqual(la.sum('A11:A21').shape, (116, 2, 15)) + assert_array_equal(la.sum('A11:A21'), la.sum(geo=':')) + assert_array_equal(la.sum('A11:A21'), la.sum(geo)) + + # a.2) a tuple of one group => do not collapse dimension + self.assertEqual(la.sum((geo[:],)).shape, (116, 1, 2, 15)) + + # a.3) several groups + # string groups + self.assertEqual(la.sum((vla, wal, bru)).shape, (116, 3, 2, 15)) + + # XXX: do we also want to support this? I do not really like it because it gets tricky when we have some other + # axes into play. For now the error message is unclear because it first aggregates on "vla", then tries to + # aggregate on "wal", but there is no "geo" dimension anymore. + # self.assertEqual(la.sum(vla, wal, bru).shape, (116, 3, 2, 15)) + + # with one label in several groups + self.assertEqual(la.sum((['M'], ['M', 'F'])).shape, + (116, 44, 2, 15)) + self.assertEqual(la.sum(('M', 'M,F')).shape, (116, 44, 2, 15)) + self.assertEqual(la.sum('M;M,F').shape, (116, 44, 2, 15)) + # with group names + res = la.sum('M >> men;M,F >> all') + self.assertEqual(res.shape, (116, 44, 2, 15)) + self.assertTrue('sex' in res.axes) + men = sex['M'].named('men') + all_ = sex['M,F'].named('all') + assert_array_equal(res.axes.sex.labels, ['men', 'all']) + assert_array_equal(res['men'], raw[:, :, 0, :]) + assert_array_equal(res['all'], raw.sum(2)) + + res = la.sum(('M >> men', 'M,F >> all')) + self.assertEqual(res.shape, (116, 44, 2, 15)) + self.assertTrue('sex' in res.axes) + assert_array_equal(res.axes.sex.labels, ['men', 'all']) + assert_array_equal(res['men'], raw[:, :, 0, :]) + assert_array_equal(res['all'], raw.sum(2)) + + res = la.sum((vla, wal, bru, belgium)) + self.assertEqual(res.shape, (116, 4, 2, 15)) + + # a.4) several dimensions at the same time + res = la.sum('P01,P03;P02,P05;P01:', (vla, wal, bru, belgium)) + self.assertEqual(res.shape, (116, 4, 2, 3)) + + # b) both axis aggregate and group aggregate at the same time + res = la.sum(age, sex, (vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 15)) + + # c) chain group aggregate after axis aggregate + res = la.sum(age, sex).sum((vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 15)) + + def test_group_agg_label_group(self): + la = self.larray + age, geo, sex, lipro = la.axes + vla, wal, bru = geo[self.vla_str], geo[self.wal_str], geo[self.bru_str] + belgium = geo[self.belgium] + + # a) group aggregate on a fresh array + + # a.1) one group => collapse dimension + # not sure I should support groups with a single item in an aggregate + men = sex.i[[0]] + self.assertEqual(la.sum(men).shape, (116, 44, 15)) + self.assertEqual(la.sum(sex['M']).shape, (116, 44, 15)) + self.assertEqual(la.sum(sex['M,']).shape, (116, 44, 15)) + self.assertEqual(la.sum(sex['M,F']).shape, (116, 44, 15)) + + self.assertEqual(la.sum(geo['A11,A21,A25']).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo[['A11', 'A21', 'A25']]).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo['A11', 'A21', 'A25']).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo['A11,A21,A25']).shape, (116, 2, 15)) + + self.assertEqual(la.sum(geo[:]).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo[':']).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo[:]).shape, (116, 2, 15)) + + # Include everything between two labels. Since A11 is the first label and A21 is the last one, this should be + # equivalent to the previous tests. + self.assertEqual(la.sum(geo['A11:A21']).shape, (116, 2, 15)) + assert_array_equal(la.sum(geo['A11:A21']), la.sum(geo)) + assert_array_equal(la.sum(geo['A11':'A21']), la.sum(geo)) + + # a.2) a tuple of one group => do not collapse dimension + self.assertEqual(la.sum((geo[:],)).shape, (116, 1, 2, 15)) + + # a.3) several groups + # string groups + self.assertEqual(la.sum((vla, wal, bru)).shape, (116, 3, 2, 15)) + + # XXX: do we also want to support this? I do not really like it because it gets tricky when we have some other + # axes into play. For now the error message is unclear because it first aggregates on "vla", then tries to + # aggregate on "wal", but there is no "geo" dimension anymore. + # self.assertEqual(la.sum(vla, wal, bru).shape, (116, 3, 2, 15)) + + # with one label in several groups + self.assertEqual(la.sum((sex['M'], sex[['M', 'F']])).shape, (116, 44, 2, 15)) + self.assertEqual(la.sum((sex['M'], sex['M', 'F'])).shape, (116, 44, 2, 15)) + self.assertEqual(la.sum((sex['M'], sex['M,F'])).shape, (116, 44, 2, 15)) + # XXX: do we want to support this? + # self.assertEqual(la.sum(sex['M;H,F']).shape, (116, 44, 2, 15)) + + res = la.sum((vla, wal, bru, belgium)) + self.assertEqual(res.shape, (116, 4, 2, 15)) + + # a.4) several dimensions at the same time + # self.assertEqual(la.sum(lipro['P01,P03;P02,P05;P01:'], (vla, wal, bru, belgium)).shape, + # (116, 4, 2, 3)) + res = la.sum((lipro['P01,P03'], lipro['P02,P05'], lipro[:]), (vla, wal, bru, belgium)) + self.assertEqual(res.shape, (116, 4, 2, 3)) + + # b) both axis aggregate and group aggregate at the same time + res = la.sum(age, sex, (vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 15)) + + # c) chain group aggregate after axis aggregate + res = la.sum(age, sex).sum((vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 15)) + + def test_group_agg_label_group_no_axis(self): + la = self.larray + age, geo, sex, lipro = la.axes + vla, wal, bru = LGroup(self.vla_str), LGroup(self.wal_str), LGroup(self.bru_str) + belgium = LGroup(self.belgium) + + # a) group aggregate on a fresh array + + # a.1) one group => collapse dimension + # not sure I should support groups with a single item in an aggregate + self.assertEqual(la.sum(LGroup('M')).shape, (116, 44, 15)) + self.assertEqual(la.sum(LGroup('M,')).shape, (116, 44, 15)) + self.assertEqual(la.sum(LGroup('M,F')).shape, (116, 44, 15)) + + self.assertEqual(la.sum(LGroup('A11,A21,A25')).shape, (116, 2, 15)) + self.assertEqual(la.sum(LGroup(['A11', 'A21', 'A25'])).shape, (116, 2, 15)) + + # Include everything between two labels. Since A11 is the first label + # and A21 is the last one, this should be equivalent to the full axis. + self.assertEqual(la.sum(LGroup('A11:A21')).shape, (116, 2, 15)) + assert_array_equal(la.sum(LGroup('A11:A21')), la.sum(geo)) + assert_array_equal(la.sum(LGroup(slice('A11', 'A21'))), la.sum(geo)) + + # a.3) several groups + # string groups + self.assertEqual(la.sum((vla, wal, bru)).shape, (116, 3, 2, 15)) + + # XXX: do we also want to support this? I do not really like it because it gets tricky when we have some other + # axes into play. For now the error message is unclear because it first aggregates on "vla", then tries to + # aggregate on "wal", but there is no "geo" dimension anymore. + # self.assertEqual(la.sum(vla, wal, bru).shape, (116, 3, 2, 15)) + + # with one label in several groups + self.assertEqual(la.sum((LGroup('M'), LGroup(['M', 'F']))).shape, (116, 44, 2, 15)) + self.assertEqual(la.sum((LGroup('M'), LGroup('M,F'))).shape, (116, 44, 2, 15)) + # XXX: do we want to support this? + # self.assertEqual(la.sum(sex['M;M,F']).shape, (116, 44, 2, 15)) + + res = la.sum((vla, wal, bru, belgium)) + self.assertEqual(res.shape, (116, 4, 2, 15)) + + # a.4) several dimensions at the same time + # self.assertEqual(la.sum(lipro['P01,P03;P02,P05;P01:'], (vla, wal, bru, belgium)).shape, + # (116, 4, 2, 3)) + res = la.sum((LGroup('P01,P03'), LGroup('P02,P05')), (vla, wal, bru, belgium)) + self.assertEqual(res.shape, (116, 4, 2, 2)) + + # b) both axis aggregate and group aggregate at the same time + res = la.sum(age, sex, (vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 15)) + + # c) chain group aggregate after axis aggregate + res = la.sum(age, sex).sum((vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 15)) + + def test_group_agg_axis_ref_label_group(self): + la = self.larray + age, geo, sex, lipro = X.age, X.geo, X.sex, X.lipro + vla, wal, bru = geo[self.vla_str], geo[self.wal_str], geo[self.bru_str] + belgium = geo[self.belgium] + + # a) group aggregate on a fresh array + + # a.1) one group => collapse dimension + # not sure I should support groups with a single item in an aggregate + men = sex.i[[0]] + self.assertEqual(la.sum(men).shape, (116, 44, 15)) + self.assertEqual(la.sum(sex['M']).shape, (116, 44, 15)) + self.assertEqual(la.sum(sex['M,']).shape, (116, 44, 15)) + self.assertEqual(la.sum(sex['M,F']).shape, (116, 44, 15)) + + self.assertEqual(la.sum(geo['A11,A21,A25']).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo[['A11', 'A21', 'A25']]).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo['A11', 'A21', 'A25']).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo['A11,A21,A25']).shape, (116, 2, 15)) + + self.assertEqual(la.sum(geo[:]).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo[':']).shape, (116, 2, 15)) + self.assertEqual(la.sum(geo[:]).shape, (116, 2, 15)) + + # Include everything between two labels. Since A11 is the first label + # and A21 is the last one, this should be equivalent to the previous + # tests. + self.assertEqual(la.sum(geo['A11:A21']).shape, (116, 2, 15)) + assert_array_equal(la.sum(geo['A11:A21']), la.sum(geo)) + assert_array_equal(la.sum(geo['A11':'A21']), la.sum(geo)) + + # a.2) a tuple of one group => do not collapse dimension + self.assertEqual(la.sum((geo[:],)).shape, (116, 1, 2, 15)) + + # a.3) several groups + # string groups + self.assertEqual(la.sum((vla, wal, bru)).shape, (116, 3, 2, 15)) + + # XXX: do we also want to support this? I do not really like it because + # it gets tricky when we have some other axes into play. For now the + # error message is unclear because it first aggregates on "vla", then + # tries to aggregate on "wal", but there is no "geo" dimension anymore. + # self.assertEqual(la.sum(vla, wal, bru).shape, (116, 3, 2, 15)) + + # with one label in several groups + self.assertEqual(la.sum((sex['M'], sex[['M', 'F']])).shape, (116, 44, 2, 15)) + self.assertEqual(la.sum((sex['M'], sex['M', 'F'])).shape, (116, 44, 2, 15)) + self.assertEqual(la.sum((sex['M'], sex['M,F'])).shape, (116, 44, 2, 15)) + # XXX: do we want to support this? + # self.assertEqual(la.sum(sex['M;M,F']).shape, (116, 44, 2, 15)) + + res = la.sum((vla, wal, bru, belgium)) + self.assertEqual(res.shape, (116, 4, 2, 15)) + + # a.4) several dimensions at the same time + # self.assertEqual(la.sum(lipro['P01,P03;P02,P05;P01:'], + # (vla, wal, bru, belgium)).shape, + # (116, 4, 2, 3)) + res = la.sum((lipro['P01,P03'], lipro['P02,P05'], lipro[:]), (vla, wal, bru, belgium)) + self.assertEqual(res.shape, (116, 4, 2, 3)) + + # b) both axis aggregate and group aggregate at the same time + res = la.sum(age, sex, (vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 15)) + + # c) chain group aggregate after axis aggregate + res = la.sum(age, sex).sum((vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 15)) + + def test_group_agg_one_axis(self): + a = Axis(range(3), 'a') + la = ndtest(a) + raw = np.asarray(la) + + assert_array_equal(la.sum(a[0, 2]), raw[[0, 2]].sum()) + + def test_group_agg_anonymous_axis(self): + la = ndtest([Axis(2), Axis(3)]) + a1, a2 = la.axes + raw = np.asarray(la) + assert_array_equal(la.sum(a2[0, 2]), raw[:, [0, 2]].sum(1)) + + def test_group_agg_zero_padded_label(self): + arr = ndtest("a=01,02,03,10,11; b=b0..b2") + expected = LArray([36, 30, 39], "a=01_03,10,11") + assert_array_equal(arr.sum("01,02,03 >> 01_03; 10; 11", "b"), expected) + + def test_group_agg_on_int_array(self): + # issue 193 + arr = ndtest('year=2014..2018') + group = arr.year[:2016] + self.assertEqual(arr.mean(group), 1.0) + self.assertEqual(arr.median(group), 1.0) + self.assertEqual(arr.percentile(90, group), 1.8) + self.assertEqual(arr.std(group), 1.0) + self.assertEqual(arr.var(group), 1.0) + + def test_group_agg_on_bool_array(self): + # issue 194 + a = ndtest((2, 3)) + b = a > 1 + expected = from_string("""a,a0,a1 + , 1, 2""", sep=',') + assert_array_equal(b.sum('b1:'), expected) + + # TODO: fix this (and add other tests for references (x.) to anonymous axes + # def test_group_agg_anonymous_axis_ref(self): + # la = ndtest([Axis(2), Axis(3)]) + # raw = np.asarray(la) + # # this does not work because x[1] refers to an axis with name 1, + # # which does not exist. We might want to change this. + # assert_array_equal(la.sum(x[1][0, 2]), raw[:, [0, 2]].sum(1)) + + # group aggregates on a group-aggregated array + def test_group_agg_on_group_agg(self): + la = self.larray + age, geo, sex, lipro = la.axes + vla, wal, bru = self.vla_str, self.wal_str, self.bru_str + belgium = self.belgium + + reg = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) + + # 1) one group => collapse dimension + self.assertEqual(reg.sum(lipro='P01,P02').shape, (4,)) + + # 2) a tuple of one group => do not collapse dimension + self.assertEqual(reg.sum(lipro=('P01,P02',)).shape, (4, 1)) + + # 3) several groups + self.assertEqual(reg.sum(lipro='P01;P02;:').shape, (4, 3)) + + # this is INVALID + # TODO: raise a nice exception + # regsum = reg.sum(lipro='P01,P02,:') + + # this is currently allowed even though it can be confusing: + # P01 and P02 are both groups with one element each. + self.assertEqual(reg.sum(lipro=('P01', 'P02', ':')).shape, (4, 3)) + self.assertEqual(reg.sum(lipro=('P01', 'P02', lipro[:])).shape, (4, 3)) + + # explicit groups are better + self.assertEqual(reg.sum(lipro=('P01,', 'P02,', ':')).shape, (4, 3)) + self.assertEqual(reg.sum(lipro=(['P01'], ['P02'], ':')).shape, (4, 3)) + + # 4) groups on the aggregated dimension + + # self.assertEqual(reg.sum(geo=([vla, bru], [wal, bru])).shape, (2, 3)) + # vla, wal, bru + + # group aggregates on a group-aggregated array + def test_group_agg_on_group_agg_nokw(self): + la = self.larray + age, geo, sex, lipro = la.axes + vla, wal, bru = self.vla_str, self.wal_str, self.bru_str + belgium = self.belgium + + reg = la.sum(age, sex).sum((vla, wal, bru, belgium)) + # XXX: should this be supported too? (it currently fails) + # reg = la.sum(age, sex).sum(vla, wal, bru, belgium) + + # 1) one group => collapse dimension + self.assertEqual(reg.sum('P01,P02').shape, (4,)) + + # 2) a tuple of one group => do not collapse dimension + self.assertEqual(reg.sum(('P01,P02',)).shape, (4, 1)) + + # 3) several groups + # : is ambiguous + # self.assertEqual(reg.sum('P01;P02;:').shape, (4, 3)) + self.assertEqual(reg.sum('P01;P02;P01:').shape, (4, 3)) + + # this is INVALID + # TODO: raise a nice exception + # regsum = reg.sum(lipro='P01,P02,:') + + # this is currently allowed even though it can be confusing: + # P01 and P02 are both groups with one element each. + self.assertEqual(reg.sum(('P01', 'P02', 'P01:')).shape, (4, 3)) + self.assertEqual(reg.sum(('P01', 'P02', lipro[:])).shape, (4, 3)) + + # explicit groups are better + self.assertEqual(reg.sum(('P01,', 'P02,', 'P01:')).shape, (4, 3)) + self.assertEqual(reg.sum((['P01'], ['P02'], 'P01:')).shape, (4, 3)) + + # 4) groups on the aggregated dimension + + # self.assertEqual(reg.sum(geo=([vla, bru], [wal, bru])).shape, (2, 3)) + # vla, wal, bru + + def test_getitem_on_group_agg(self): + la = self.larray + age, geo, sex, lipro = la.axes + vla, wal, bru = self.vla_str, self.wal_str, self.bru_str + belgium = self.belgium + + # using a string + vla = self.vla_str + reg = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) + # the following are all equivalent + self.assertEqual(reg[vla].shape, (15,)) + self.assertEqual(reg[(vla,)].shape, (15,)) + self.assertEqual(reg[(vla, slice(None))].shape, (15,)) + self.assertEqual(reg[vla, slice(None)].shape, (15,)) + self.assertEqual(reg[vla, :].shape, (15,)) + + # one more level... + self.assertEqual(reg[vla]['P03'], 389049848.0) + + # using an anonymous LGroup + vla = self.geo[self.vla_str] + reg = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) + # the following are all equivalent + self.assertEqual(reg[vla].shape, (15,)) + self.assertEqual(reg[(vla,)].shape, (15,)) + self.assertEqual(reg[(vla, slice(None))].shape, (15,)) + self.assertEqual(reg[vla, slice(None)].shape, (15,)) + self.assertEqual(reg[vla, :].shape, (15,)) + + # using a named LGroup + vla = self.geo[self.vla_str] >> 'Vlaanderen' + reg = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) + # the following are all equivalent + self.assertEqual(reg[vla].shape, (15,)) + self.assertEqual(reg[(vla,)].shape, (15,)) + self.assertEqual(reg[(vla, slice(None))].shape, (15,)) + self.assertEqual(reg[vla, slice(None)].shape, (15,)) + self.assertEqual(reg[vla, :].shape, (15,)) + + def test_getitem_on_group_agg_nokw(self): + la = self.larray + age, geo, sex, lipro = la.axes + vla, wal, bru = self.vla_str, self.wal_str, self.bru_str + belgium = self.belgium + + # using a string + vla = self.vla_str + reg = la.sum(age, sex).sum((vla, wal, bru, belgium)) + # the following are all equivalent + self.assertEqual(reg[vla].shape, (15,)) + self.assertEqual(reg[(vla,)].shape, (15,)) + self.assertEqual(reg[(vla, slice(None))].shape, (15,)) + self.assertEqual(reg[vla, slice(None)].shape, (15,)) + self.assertEqual(reg[vla, :].shape, (15,)) + + # one more level... + self.assertEqual(reg[vla]['P03'], 389049848.0) + + # using an anonymous LGroup + vla = self.geo[self.vla_str] + reg = la.sum(age, sex).sum((vla, wal, bru, belgium)) + # the following are all equivalent + self.assertEqual(reg[vla].shape, (15,)) + self.assertEqual(reg[(vla,)].shape, (15,)) + self.assertEqual(reg[(vla, slice(None))].shape, (15,)) + self.assertEqual(reg[vla, slice(None)].shape, (15,)) + self.assertEqual(reg[vla, :].shape, (15,)) + + # using a named LGroup + vla = self.geo[self.vla_str] >> 'Vlaanderen' + reg = la.sum(age, sex).sum((vla, wal, bru, belgium)) + # the following are all equivalent + self.assertEqual(reg[vla].shape, (15,)) + self.assertEqual(reg[(vla,)].shape, (15,)) + self.assertEqual(reg[(vla, slice(None))].shape, (15,)) + self.assertEqual(reg[vla, slice(None)].shape, (15,)) + self.assertEqual(reg[vla, :].shape, (15,)) + + def test_filter_on_group_agg(self): + la = self.larray + age, geo, sex, lipro = la.axes + vla, wal, bru = self.vla_str, self.wal_str, self.bru_str + belgium = self.belgium + + # using a string + vla = self.vla_str + reg = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) + self.assertEqual(reg.filter(geo=vla).shape, (15,)) + + # using a named LGroup + vla = self.geo[self.vla_str] >> 'Vlaanderen' + reg = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) + self.assertEqual(reg.filter(geo=vla).shape, (15,)) + + # Note that reg.filter(geo=(vla,)) does NOT work. It might be a + # little confusing for users, because reg[(vla,)] works but it is + # normal because reg.filter(geo=(vla,)) is equivalent to: + # reg[((vla,),)] or reg[(vla,), :] + + # mixed LGroup/string slices + child = age[:17] + child_named = age[:17] >> 'child' + working = age[18:64] + retired = age[65:] + + byage = la.sum(age=(child, 5, working, retired)) + self.assertEqual(byage.shape, (4, 44, 2, 15)) + + byage = la.sum(age=(child, slice(5, 10), working, retired)) + self.assertEqual(byage.shape, (4, 44, 2, 15)) + + # filter on an aggregated larray created with mixed groups + self.assertEqual(byage.filter(age=':17').shape, (44, 2, 15)) + + byage = la.sum(age=(child_named, 5, working, retired)) + self.assertEqual(byage.filter(age=child_named).shape, (44, 2, 15)) + + def test_sum_several_lg_groups(self): + la, geo = self.larray, self.geo + fla = geo[self.vla_str] >> 'Flanders' + wal = geo[self.wal_str] >> 'Wallonia' + bru = geo[self.bru_str] >> 'Brussels' + + reg = la.sum(geo=(fla, wal, bru)) + self.assertEqual(reg.shape, (116, 3, 2, 15)) + + # the result is indexable + # a) by LGroup + self.assertEqual(reg.filter(geo=fla).shape, (116, 2, 15)) + self.assertEqual(reg.filter(geo=(fla, wal)).shape, (116, 2, 2, 15)) + + # b) by string (name of groups) + self.assertEqual(reg.filter(geo='Flanders').shape, (116, 2, 15)) + self.assertEqual(reg.filter(geo='Flanders,Wallonia').shape, (116, 2, 2, 15)) + + # using string groups + reg = la.sum(geo=(self.vla_str, self.wal_str, self.bru_str)) + self.assertEqual(reg.shape, (116, 3, 2, 15)) + # the result is indexable + # a) by string (def) + self.assertEqual(reg.filter(geo=self.vla_str).shape, (116, 2, 15)) + self.assertEqual(reg.filter(geo=(self.vla_str, self.wal_str)).shape, (116, 2, 2, 15)) + + # b) by LGroup + self.assertEqual(reg.filter(geo=self.vla_str).shape, (116, 2, 15)) + self.assertEqual(reg.filter(geo=(self.vla_str, self.wal_str)).shape, (116, 2, 2, 15)) + + def test_sum_with_groups_from_other_axis(self): + small = self.small + + # use a group from another *compatible* axis + lipro2 = Axis('lipro=P01..P15') + self.assertEqual(small.sum(lipro=lipro2['P01,P03']).shape, (2,)) + + # use (compatible) group from another *incompatible* axis + # XXX: I am unsure whether or not this should be allowed. Maybe we + # should simply check that the group is valid in axis, but that + # will trigger a pretty meaningful error anyway + lipro3 = Axis('lipro=P01,P03,P05') + self.assertEqual(small.sum(lipro3['P01,P03']).shape, (2,)) + + # use a group (from another axis) which is incompatible with the axis of + # the same name in the array + lipro4 = Axis('lipro=P01,P03,P16') + with self.assertRaisesRegexp(ValueError, "lipro\['P01', 'P16'\] is not a valid label for any axis"): + small.sum(lipro4['P01,P16']) + + def test_agg_kwargs(self): + la = self.larray + data = self.array + + # dtype + self.assertEqual(la.sum(dtype=int), data.sum(dtype=int)) + + # ddof + self.assertEqual(la.std(ddof=0), data.std(ddof=0)) + + # out + res = la.std(X.sex) + out = zeros_like(res) + la.std(X.sex, out=out) + assert_array_equal(res, out) + + def test_agg_by(self): + la = self.larray + age, geo, sex, lipro = la.axes + vla, wal, bru = self.vla_str, self.wal_str, self.bru_str + belgium = self.belgium + + # no group or axis + self.assertEqual(la.sum_by().shape, ()) + self.assertEqual(la.sum_by(), la.sum()) + + # a) group aggregate on a fresh array + + # a.1) one group + res = la.sum_by(geo='A11,A21,A25') + self.assertEqual(res.shape, ()) + self.assertEqual(res, la.sum(geo='A11,A21,A25').sum()) + + # a.2) a tuple of one group + res = la.sum_by(geo=(geo[:],)) + self.assertEqual(res.shape, (1,)) + assert_array_equal(res, la.sum(age, sex, lipro, geo=(geo[:],))) + + # a.3) several groups + # string groups + res = la.sum_by(geo=(vla, wal, bru)) + self.assertEqual(res.shape, (3,)) + assert_array_equal(res, la.sum(age, sex, lipro, geo=(vla, wal, bru))) + + # with one label in several groups + self.assertEqual(la.sum_by(sex=(['M'], ['M', 'F'])).shape, (2,)) + self.assertEqual(la.sum_by(sex=('M', 'M,F')).shape, (2,)) + + res = la.sum_by(sex='M;M,F') + self.assertEqual(res.shape, (2,)) + assert_array_equal(res, la.sum(age, geo, lipro, sex='M;M,F')) + + # a.4) several dimensions at the same time + res = la.sum_by(geo=(vla, wal, bru, belgium), lipro='P01,P03;P02,P05;:') + self.assertEqual(res.shape, (4, 3)) + assert_array_equal(res, la.sum(age, sex, geo=(vla, wal, bru, belgium), lipro='P01,P03;P02,P05;:')) + + # b) both axis aggregate and group aggregate at the same time + # Note that you must list "full axes" aggregates first (Python does not allow non-kwargs after kwargs. + res = la.sum_by(sex, geo=(vla, wal, bru, belgium)) + self.assertEqual(res.shape, (4, 2)) + assert_array_equal(res, la.sum(age, lipro, geo=(vla, wal, bru, belgium))) + + # c) chain group aggregate after axis aggregate + res = la.sum_by(geo, sex) + self.assertEqual(res.shape, (44, 2)) + assert_array_equal(res, la.sum(age, lipro)) + + res2 = res.sum_by(geo=(vla, wal, bru, belgium)) + self.assertEqual(res2.shape, (4,)) + assert_array_equal(res2, res.sum(sex, geo=(vla, wal, bru, belgium))) + + def test_agg_igroup(self): + arr = ndtest(3) + res = arr.sum((X.a.i[:2], X.a.i[1:])) + assert_array_equal(res.a.labels, [':a1', 'a1:']) + + def test_ratio(self): + la = self.larray + age, geo, sex, lipro = la.axes + + regions = (self.vla_str, self.wal_str, self.bru_str, self.belgium) + reg = la.sum(age, sex, regions) + self.assertEqual(reg.shape, (4, 15)) + + fla = geo[self.vla_str] >> 'Flanders' + wal = geo[self.wal_str] >> 'Wallonia' + bru = geo[self.bru_str] >> 'Brussels' + regions = (fla, wal, bru) + reg = la.sum(age, sex, regions) + + ratio = reg.ratio() + assert_array_equal(ratio, reg / reg.sum(geo, lipro)) + self.assertEqual(ratio.shape, (3, 15)) + + ratio = reg.ratio(geo) + assert_array_equal(ratio, reg / reg.sum(geo)) + self.assertEqual(ratio.shape, (3, 15)) + + ratio = reg.ratio(geo, lipro) + assert_array_equal(ratio, reg / reg.sum(geo, lipro)) + self.assertEqual(ratio.shape, (3, 15)) + self.assertEqual(ratio.sum(), 1.0) + + def test_percent(self): + la = self.larray + age, geo, sex, lipro = la.axes + + regions = (self.vla_str, self.wal_str, self.bru_str, self.belgium) + reg = la.sum(age, sex, regions) + self.assertEqual(reg.shape, (4, 15)) + + fla = geo[self.vla_str] >> 'Flanders' + wal = geo[self.wal_str] >> 'Wallonia' + bru = geo[self.bru_str] >> 'Brussels' + regions = (fla, wal, bru) + reg = la.sum(age, sex, regions) + + percent = reg.percent() + assert_array_equal(percent, reg * 100 / reg.sum(geo, lipro)) + self.assertEqual(percent.shape, (3, 15)) + + percent = reg.percent(geo) + assert_array_equal(percent, reg * 100 / reg.sum(geo)) + self.assertEqual(percent.shape, (3, 15)) + + percent = reg.percent(geo, lipro) + assert_array_equal(percent, reg * 100 / reg.sum(geo, lipro)) + self.assertEqual(percent.shape, (3, 15)) + self.assertAlmostEqual(percent.sum(), 100.0) + + def test_total(self): + la = self.larray + age, geo, sex, lipro = la.axes + # la = self.small + # sex, lipro = la.axes + + self.assertEqual(la.with_total().shape, (117, 45, 3, 16)) + self.assertEqual(la.with_total(sex).shape, (116, 44, 3, 15)) + self.assertEqual(la.with_total(lipro).shape, (116, 44, 2, 16)) + self.assertEqual(la.with_total(sex, lipro).shape, (116, 44, 3, 16)) + + fla = geo[self.vla_str] >> 'Flanders' + wal = geo[self.wal_str] >> 'Wallonia' + bru = geo[self.bru_str] >> 'Brussels' + bel = geo[:] >> 'Belgium' + + self.assertEqual(la.with_total(geo=(fla, wal, bru), op=mean).shape, (116, 47, 2, 15)) + self.assertEqual(la.with_total((fla, wal, bru), op=mean).shape, (116, 47, 2, 15)) + # works but "wrong" for x.geo (double what is expected because it includes fla wal & bru) + # TODO: we probably want to display a warning (or even an error?) in that case. + # If we really want that behavior, we can still split the operation: + # .with_total((fla, wal, bru)).with_total(x.geo) + # OR we might want to only sum the axis as it was before the op (but that does not play well when working with + # multiple axes). + a1 = la.with_total(X.sex, (fla, wal, bru), X.geo, X.lipro) + self.assertEqual(a1.shape, (116, 48, 3, 16)) + + # correct total but the order is not very nice + a2 = la.with_total(X.sex, X.geo, (fla, wal, bru), X.lipro) + self.assertEqual(a2.shape, (116, 48, 3, 16)) + + # the correct way to do it + a3 = la.with_total(X.sex, (fla, wal, bru, bel), X.lipro) + self.assertEqual(a3.shape, (116, 48, 3, 16)) + + # a4 = la.with_total((lipro[':P05'], lipro['P05:']), op=mean) + a4 = la.with_total((':P05', 'P05:'), op=mean) + self.assertEqual(a4.shape, (116, 44, 2, 17)) + + def test_transpose(self): + arr = ndtest((2, 3, 4)) + a, b, c = arr.axes + res = arr.transpose() + self.assertEqual(res.axes, [c, b, a]) + res = arr.transpose('b', 'c', 'a') + self.assertEqual(res.axes, [b, c, a]) + res = arr.transpose('b') + self.assertEqual(res.axes, [b, a, c]) + + # using Ellipsis instead of ... to avoid a syntax error on Python 2 (where ... is only available within []) + res = arr.transpose(Ellipsis, 'a') + self.assertEqual(res.axes, [b, c, a]) + res = arr.transpose('c', Ellipsis, 'a') + self.assertEqual(res.axes, [c, b, a]) + + def test_transpose_anonymous(self): + a = ndtest([Axis(2), Axis(3), Axis(4)]) + + # reordered = a.transpose(0, 2, 1) + # self.assertEqual(reordered.shape, (2, 4, 3)) + + # axes = self[1, 2] + # => union(axes, self) + # => axes.extend([self[0]]) + # => breaks because self[0] not compatible with axes[0] + # => breaks because self[0] not compatible with self[1] + + # a real union should not care and should return + # self[1, 2, 0] but will this break other stuff? My gut feeling is yes + + # when doing a binop between anonymous axes, we use union too (that might be the problem) and we need *that* + # union to match axes by position + reordered = a.transpose(1, 2) + self.assertEqual(reordered.shape, (3, 4, 2)) + + reordered = a.transpose(2, 0) + self.assertEqual(reordered.shape, (4, 2, 3)) + + reordered = a.transpose() + self.assertEqual(reordered.shape, (4, 3, 2)) + + def test_binary_ops(self): + raw = self.small_data + la = self.small + + assert_array_equal(la + la, raw + raw) + assert_array_equal(la + 1, raw + 1) + assert_array_equal(1 + la, 1 + raw) + + assert_array_equal(la - la, raw - raw) + assert_array_equal(la - 1, raw - 1) + assert_array_equal(1 - la, 1 - raw) + + assert_array_equal(la * la, raw * raw) + assert_array_equal(la * 2, raw * 2) + assert_array_equal(2 * la, 2 * raw) + + with np.errstate(invalid='ignore'): + raw_res = raw / raw + with pytest.warns(RuntimeWarning) as caught_warnings: + res = la / la + assert_array_nan_equal(res, raw_res) + assert len(caught_warnings) == 1 + warn_msg = "invalid value (NaN) encountered during operation (this is typically caused by a 0 / 0)" + assert caught_warnings[0].message.args[0] == warn_msg + assert caught_warnings[0].filename == __file__ + + assert_array_equal(la / 2, raw / 2) + + with np.errstate(divide='ignore'): + raw_res = 30 / raw + with pytest.warns(RuntimeWarning) as caught_warnings: + res = 30 / la + assert_array_equal(res, raw_res) + assert len(caught_warnings) == 1 + assert caught_warnings[0].message.args[0] == "divide by zero encountered during operation" + assert caught_warnings[0].filename == __file__ + + assert_array_equal(30 / (la + 1), 30 / (raw + 1)) + + raw_int = raw.astype(int) + la_int = LArray(raw_int, axes=(self.sex, self.lipro)) + assert_array_equal(la_int / 2, raw_int / 2) + assert_array_equal(la_int // 2, raw_int // 2) + + # test adding two larrays with different axes order + assert_array_equal(la + la.transpose(), raw * 2) + + # mixed operations + raw2 = raw / 2 + la_raw2 = la - raw2 + self.assertEqual(la_raw2.axes, la.axes) + assert_array_equal(la_raw2, raw - raw2) + raw2_la = raw2 - la + self.assertEqual(raw2_la.axes, la.axes) + assert_array_equal(raw2_la, raw2 - raw) + + la_ge_raw2 = la >= raw2 + self.assertEqual(la_ge_raw2.axes, la.axes) + assert_array_equal(la_ge_raw2, raw >= raw2) + + raw2_ge_la = raw2 >= la + self.assertEqual(raw2_ge_la.axes, la.axes) + assert_array_equal(raw2_ge_la, raw2 >= raw) + + def test_binary_ops_no_name_axes(self): + raw = self.small_data + raw2 = self.small_data + 1 + la = ndtest([Axis(l) for l in self.small.shape]) + la2 = ndtest([Axis(l) for l in self.small.shape]) + 1 + + assert_array_equal(la + la2, raw + raw2) + assert_array_equal(la + 1, raw + 1) + assert_array_equal(1 + la, 1 + raw) + + assert_array_equal(la - la2, raw - raw2) + assert_array_equal(la - 1, raw - 1) + assert_array_equal(1 - la, 1 - raw) + + assert_array_equal(la * la2, raw * raw2) + assert_array_equal(la * 2, raw * 2) + assert_array_equal(2 * la, 2 * raw) + + assert_array_nan_equal(la / la2, raw / raw2) + assert_array_equal(la / 2, raw / 2) + + with np.errstate(divide='ignore'): + raw_res = 30 / raw + with pytest.warns(RuntimeWarning) as caught_warnings: + res = 30 / la + assert_array_equal(res, raw_res) + assert len(caught_warnings) == 1 + assert caught_warnings[0].message.args[0] == "divide by zero encountered during operation" + assert caught_warnings[0].filename == __file__ + + assert_array_equal(30 / (la + 1), 30 / (raw + 1)) + + raw_int = raw.astype(int) + la_int = LArray(raw_int) + assert_array_equal(la_int / 2, raw_int / 2) + assert_array_equal(la_int // 2, raw_int // 2) + + # adding two larrays with different axes order cannot work with unnamed axes + # assert_array_equal(la + la.transpose(), raw * 2) + + # mixed operations + raw2 = raw / 2 + la_raw2 = la - raw2 + assert la_raw2.axes == la.axes + assert_array_equal(la_raw2, raw - raw2) + raw2_la = raw2 - la + assert raw2_la.axes == la.axes + assert_array_equal(raw2_la, raw2 - raw) + + la_ge_raw2 = la >= raw2 + assert la_ge_raw2.axes == la.axes + assert_array_equal(la_ge_raw2, raw >= raw2) + + raw2_ge_la = raw2 >= la + assert raw2_ge_la.axes == la.axes + assert_array_equal(raw2_ge_la, raw2 >= raw) + + def test_broadcasting_no_name(self): + a = ndtest([Axis(2), Axis(3)]) + b = ndtest(Axis(3)) + c = ndtest(Axis(2)) + + with self.assertRaises(ValueError): + # ValueError: incompatible axes: + # Axis(None, [0, 1, 2]) + # vs + # Axis(None, [0, 1]) + a * b + + d = a * c + self.assertEqual(d.shape, (2, 3)) + # {0}*\{1}* 0 1 2 + # 0 0 0 0 + # 1 3 4 5 + self.assertTrue(np.array_equal(d, [[0, 0, 0], + [3, 4, 5]])) + + # it is unfortunate that the behavior is different from numpy (even though I find our behavior more intuitive) + d = np.asarray(a) * np.asarray(b) + self.assertEqual(d.shape, (2, 3)) + self.assertTrue(np.array_equal(d, [[0, 1, 4], + [0, 4, 10]])) + + with self.assertRaises(ValueError): + # ValueError: operands could not be broadcast together with shapes (2,3) (2,) + np.asarray(a) * np.asarray(c) + + def test_unary_ops(self): + raw = self.small_data + la = self.small + + # using numpy functions + assert_array_equal(np.abs(la - 10), np.abs(raw - 10)) + assert_array_equal(np.negative(la), np.negative(raw)) + assert_array_equal(np.invert(la), np.invert(raw)) + + # using python builtin ops + assert_array_equal(abs(la - 10), abs(raw - 10)) + assert_array_equal(-la, -raw) + assert_array_equal(+la, +raw) + assert_array_equal(~la, ~raw) + + def test_mean(self): + la = self.small + raw = self.small_data + + sex, lipro = la.axes + assert_array_equal(la.mean(lipro), raw.mean(1)) + + def test_sequence(self): + res = sequence('b=b0..b2', ndtest(3) * 3, 1.0) + assert_array_equal(ndtest((3, 3), dtype=float), res) + + def test_sort_values(self): + # 1D arrays + arr = LArray([0, 1, 6, 3, -1], "a=a0..a4") + res = arr.sort_values() + expected = LArray([-1, 0, 1, 3, 6], "a=a4,a0,a1,a3,a2") + assert_array_equal(res, expected) + # ascending arg + res = arr.sort_values(ascending=False) + expected = LArray([6, 3, 1, 0, -1], "a=a2,a3,a1,a0,a4") + assert_array_equal(res, expected) + + # 3D arrays + arr = LArray([[[10, 2, 4], [3, 7, 1]], [[5, 1, 6], [2, 8, 9]]], + 'a=a0,a1; b=b0,b1; c=c0..c2') + res = arr.sort_values(axis='c') + expected = LArray([[[2, 4, 10], [1, 3, 7]], [[1, 5, 6], [2, 8, 9]]], + [Axis('a=a0,a1'), Axis('b=b0,b1'), Axis(3, 'c')]) + assert_array_equal(res, expected) + + def test_set_labels(self): + la = self.small.copy() + la.set_labels(X.sex, ['Man', 'Woman'], inplace=True) + assert_array_equal(la, self.small.set_labels(X.sex, ['Man', 'Woman'])) + + def test_replace_axes(self): + lipro2 = Axis([l.replace('P', 'Q') for l in self.lipro.labels], 'lipro2') + sex2 = Axis(['Man', 'Woman'], 'sex2') + + la = LArray(self.small_data, axes=(self.sex, lipro2), + title=self.small_title) + # replace one axis + la2 = self.small.set_axes(X.lipro, lipro2) + assert_array_equal(la, la2) + self.assertEqual(la.title, la2.title, "title of array returned by replace_axes should be the same as the " + "original one. We got '{}' instead of '{}'".format(la2.title, la.title)) + + la = LArray(self.small_data, axes=(sex2, lipro2), title=self.small_title) + # all at once + la2 = self.small.set_axes([sex2, lipro2]) + assert_array_equal(la, la2) + # using keywrods args + la2 = self.small.set_axes(sex=sex2, lipro=lipro2) + assert_array_equal(la, la2) + # using dict + la2 = self.small.set_axes({X.sex: sex2, X.lipro: lipro2}) + assert_array_equal(la, la2) + # using list of pairs (axis_to_replace, new_axis) + la2 = self.small.set_axes([(X.sex, sex2), (X.lipro, lipro2)]) + assert_array_equal(la, la2) + + def test_reindex(self): + arr = ndtest((2, 2)) + res = arr.reindex(X.b, ['b1', 'b2', 'b0'], fill_value=-1) + assert_array_equal(res, from_string("""a\\b b1 b2 b0 + a0 1 -1 0 + a1 3 -1 2""")) + + arr2 = ndtest((2, 2)) + arr2.reindex(X.b, ['b1', 'b2', 'b0'], fill_value=-1, inplace=True) + assert_array_equal(arr2, from_string("""a\\b b1 b2 b0 + a0 1 -1 0 + a1 3 -1 2""")) + + # LArray fill value + filler = ndtest(arr.a) + res = arr.reindex(X.b, ['b1', 'b2', 'b0'], fill_value=filler) + assert_array_equal(res, from_string("""a\\b b1 b2 b0 + a0 1 0 0 + a1 3 1 2""")) + + # using labels from another array + arr = ndtest('a=v0..v2;b=v0,v2,v1,v3') + res = arr.reindex('a', arr.b.labels, fill_value=-1) + assert_array_equal(res, from_string("""a\\b v0 v2 v1 v3 + v0 0 1 2 3 + v2 8 9 10 11 + v1 4 5 6 7 + v3 -1 -1 -1 -1""")) + res = arr.reindex('a', arr.b, fill_value=-1) + assert_array_equal(res, from_string("""a\\b v0 v2 v1 v3 + v0 0 1 2 3 + v2 8 9 10 11 + v1 4 5 6 7 + v3 -1 -1 -1 -1""")) + + # passing a list of Axis + arr = ndtest((2, 2)) + res = arr.reindex([Axis("a=a0,a1"), Axis("c=c0"), Axis("b=b1,b2")], fill_value=-1) + assert_array_equal(res, from_string(""" a b\\c c0 + a0 b1 1 + a0 b2 -1 + a1 b1 3 + a1 b2 -1""")) + + def test_append(self): + la = self.small + sex, lipro = la.axes + + la = la.append(lipro, la.sum(lipro), label='sum') + self.assertEqual(la.shape, (2, 16)) + la = la.append(sex, la.sum(sex), label='sum') + self.assertEqual(la.shape, (3, 16)) + + # crap the sex axis is different !!!! we don't have this problem with + # the kwargs syntax below + # la = la.append(la.mean(sex), axis=sex, label='mean') + # self.assertEqual(la.shape, (4, 16)) + + # another syntax (which implies we could not have an axis named "label") + # la = la.append(lipro=la.sum(lipro), label='sum') + # self.assertEqual(la.shape, (117, 44, 2, 15)) + + def test_insert(self): + # simple tests are in the docstring + arr1 = ndtest((2, 3)) + + # insert at multiple places at once + + # we cannot use from_string in these tests because it deduplicates ambiguous (column) labels automatically + res = arr1.insert([42, 43], before='b1', label='new') + assert_array_equal(res, from_lists([ + ['a\\b', 'b0', 'new', 'new', 'b1', 'b2'], + ['a0', 0, 42, 43, 1, 2], + ['a1', 3, 42, 43, 4, 5]])) + + res = arr1.insert(42, before=['b1', 'b2'], label='new') + assert_array_equal(res, from_lists([ + ['a\\b', 'b0', 'new', 'b1', 'new', 'b2'], + ['a0', 0, 42, 1, 42, 2], + ['a1', 3, 42, 4, 42, 5]])) + + res = arr1.insert(42, before='b1', label=['b0.1', 'b0.2']) + assert_array_equal(res, from_string(""" + a\\b b0 b0.1 b0.2 b1 b2 + a0 0 42 42 1 2 + a1 3 42 42 4 5""")) + + res = arr1.insert(42, before=['b1', 'b2'], label=['b0.5', 'b1.5']) + assert_array_equal(res, from_string(""" + a\\b b0 b0.5 b1 b1.5 b2 + a0 0 42 1 42 2 + a1 3 42 4 42 5""")) + + res = arr1.insert([42, 43], before='b1', label=['b0.1', 'b0.2']) + assert_array_equal(res, from_string(""" + a\\b b0 b0.1 b0.2 b1 b2 + a0 0 42 43 1 2 + a1 3 42 43 4 5""")) + res = arr1.insert([42, 43], before=['b1', 'b2'], label='new') + assert_array_equal(res, from_lists([ + ['a\\b', 'b0', 'new', 'b1', 'new', 'b2'], + [ 'a0', 0, 42, 1, 43, 2], + [ 'a1', 3, 42, 4, 43, 5]])) + + res = arr1.insert([42, 43], before=['b1', 'b2'], label=['b0.5', 'b1.5']) + assert_array_equal(res, from_string(""" + a\\b b0 b0.5 b1 b1.5 b2 + a0 0 42 1 43 2 + a1 3 42 4 43 5""")) + res = arr1.insert([42, 43], before='b1,b2', label=['b0.5', 'b1.5']) + assert_array_equal(res, from_string(""" + a\\b b0 b0.5 b1 b1.5 b2 + a0 0 42 1 43 2 + a1 3 42 4 43 5""")) + + arr2 = ndtest(2) + res = arr1.insert([arr2 + 42, arr2 + 43], before=['b1', 'b2'], label=['b0.5', 'b1.5']) + assert_array_equal(res, from_string(""" + a\\b b0 b0.5 b1 b1.5 b2 + a0 0 42 1 43 2 + a1 3 43 4 44 5""")) + + arr3 = ndtest('a=a0,a1;b=b0.1,b0.2') + 42 + res = arr1.insert(arr3, before='b1,b2') + assert_array_equal(res, from_string(""" + a\\b b0 b0.1 b1 b0.2 b2 + a0 0 42 1 43 2 + a1 3 44 4 45 5""")) + + # with ambiguous labels + arr4 = ndtest('a=v0,v1;b=v0,v1') + res = arr4.insert(42, before='v1', axis='b', label='v0.5') + assert_array_equal(res, from_string(""" + a\\b v0 v0.5 v1 + v0 0 42 1 + v1 2 42 3""")) + res = arr4.insert(42, before=arr4.b['v1'], label='v0.5') + assert_array_equal(res, from_string(""" + a\\b v0 v0.5 v1 + v0 0 42 1 + v1 2 42 3""")) + + # the aim of this test is to drop the last value of an axis, but instead + # of dropping the last axis tick/label, drop the first one. + def test_shift_axis(self): + la = self.small + sex, lipro = la.axes + + # TODO: check how awful the syntax is with an axis that is not last + # or first + l2 = LArray(la[:, :'P14'], axes=[sex, Axis(lipro.labels[1:], 'lipro')]) + l2 = LArray(la[:, :'P14'], axes=[sex, lipro.subaxis(slice(1, None))]) + + # We can also modify the axis in-place (dangerous!) + # lipro.labels = np.append(lipro.labels[1:], lipro.labels[0]) + l2 = la[:, 'P02':] + l2.axes.lipro.labels = lipro.labels[1:] + + def test_extend(self): + la = self.small + sex, lipro = la.axes + + all_lipro = lipro[:] + tail = la.sum(lipro=(all_lipro,)) + la = la.extend(lipro, tail) + self.assertEqual(la.shape, (2, 16)) + # test with a string axis + la = la.extend('sex', la.sum(sex=(sex[:],))) + self.assertEqual(la.shape, (3, 16)) + + def test_hdf_roundtrip(self): + a = ndtest((2, 3)) + fpath = self.tmp_path('test.h5') + a.to_hdf(fpath, 'a') + res = read_hdf(fpath, 'a') + + self.assertEqual(a.ndim, 2) + self.assertEqual(a.shape, (2, 3)) + self.assertEqual(a.axes.names, ['a', 'b']) + assert_array_equal(res, a) + + # issue 72: int-like strings should not be parsed (should round-trip correctly) + fpath = self.tmp_path('issue72.h5') + a = from_lists([['axis', '10', '20'], + ['', 0, 1]]) + a.to_hdf(fpath, 'a') + res = read_hdf(fpath, 'a') + self.assertEqual(res.ndim, 1) + axis = res.axes[0] + self.assertEqual(axis.name, 'axis') + assert_array_equal(axis.labels, ['10', '20']) + + # passing group as key to to_hdf + a3 = ndtest((4, 3, 4)) + fpath = self.tmp_path('test.h5') + os.remove(fpath) + # single element group + for label in a3.a: + a3[label].to_hdf(fpath, label) + # unnamed group + group = a3.c['c0,c2'] + a3[group].to_hdf(fpath, group) + # unnamed group + slice + group = a3.c['c0::2'] + a3[group].to_hdf(fpath, group) + # named group + group = a3.c['c0,c2'] >> 'even' + a3[group].to_hdf(fpath, group) + # group with name containing special characters (replaced by _) + group = a3.c['c0,c2'] >> ':name?with*special/\[characters]' + a3[group].to_hdf(fpath, group) + + # passing group as key to read_hdf + for label in a3.a: + subset = read_hdf(fpath, label) + assert_array_equal(subset, a3[label]) + + # load Session + from larray.core.session import Session + s = Session(fpath) + assert s.names == sorted(['a0', 'a1', 'a2', 'a3', 'c0,c2', 'c0::2', 'even', ':name?with*special__[characters]']) + + def test_from_string(self): + expected = ndtest("sex=M,F") + + res = from_string('''sex M F + \t 0 1''') + assert_array_equal(res, expected) + + res = from_string('''sex M F + nan 0 1''') + assert_array_equal(res, expected) + + res = from_string('''sex M F + NaN 0 1''') + assert_array_equal(res, expected) + + def test_read_csv(self): + res = read_csv(inputpath('test1d.csv')) + assert_array_equal(res, self.io_1d) + + res = read_csv(inputpath('test2d.csv')) + assert_array_equal(res, self.io_2d) + + res = read_csv(inputpath('test3d.csv')) + assert_array_equal(res, self.io_3d) + + res = read_csv(inputpath('testint_labels.csv')) + assert_array_equal(res, self.io_int_labels) + + res = read_csv(inputpath('test2d_classic.csv')) + assert_array_equal(res, ndtest("a=a0..a2; b0..b2")) + + la = read_csv(inputpath('test1d_liam2.csv'), dialect='liam2') + self.assertEqual(la.ndim, 1) + self.assertEqual(la.shape, (3,)) + self.assertEqual(la.axes.names, ['time']) + assert_array_equal(la, [3722, 3395, 3347]) + + la = read_csv(inputpath('test5d_liam2.csv'), dialect='liam2') + self.assertEqual(la.ndim, 5) + self.assertEqual(la.shape, (2, 5, 2, 2, 3)) + self.assertEqual(la.axes.names, ['arr', 'age', 'sex', 'nat', 'time']) + assert_array_equal(la[X.arr[1], 0, 'F', X.nat[1], :], [3722, 3395, 3347]) + + # missing values + res = read_csv(inputpath('testmissing_values.csv')) + assert_array_nan_equal(res, self.io_missing_values) + + # test StringIO + res = read_csv(StringIO('a,1,2\n,0,1\n')) + assert_array_equal(res, ndtest('a=1,2')) + + # sort_columns=True + res = read_csv(StringIO('a,a2,a0,a1\n,2,0,1\n'), sort_columns=True) + assert_array_equal(res, ndtest(3)) + + ################# + # narrow format # + ################# + res = read_csv(inputpath('test1d_narrow.csv'), wide=False) + assert_array_equal(res, self.io_1d) + + res = read_csv(inputpath('test2d_narrow.csv'), wide=False) + assert_array_equal(res, self.io_2d) + + res = read_csv(inputpath('test3d_narrow.csv'), wide=False) + assert_array_equal(res, self.io_3d) + + # missing values + res = read_csv(inputpath('testmissing_values_narrow.csv'), wide=False) + assert_array_nan_equal(res, self.io_narrow_missing_values) + + # unsorted values + res = read_csv(inputpath('testunsorted_narrow.csv'), wide=False) + assert_array_equal(res, self.io_unsorted) + + def test_read_eurostat(self): + la = read_eurostat(inputpath('test5d_eurostat.csv')) + self.assertEqual(la.ndim, 5) + self.assertEqual(la.shape, (2, 5, 2, 2, 3)) + self.assertEqual(la.axes.names, ['arr', 'age', 'sex', 'nat', 'time']) + # FIXME: integer labels should be parsed as such + assert_array_equal(la[X.arr['1'], '0', 'F', X.nat['1'], :], + [3722, 3395, 3347]) + + @pytest.mark.skipif(xw is None, reason="xlwings is not available") + def test_read_excel_xlwings(self): + arr = read_excel(inputpath('test.xlsx'), '1d') + assert_array_equal(arr, self.io_1d) + + arr = read_excel(inputpath('test.xlsx'), '2d') + assert_array_equal(arr, self.io_2d) + + arr = read_excel(inputpath('test.xlsx'), '3d') + assert_array_equal(arr, self.io_3d) + + arr = read_excel(inputpath('test.xlsx'), 'int_labels') + assert_array_equal(arr, self.io_int_labels) + + arr = read_excel(inputpath('test.xlsx'), '2d_classic') + assert_array_equal(arr, ndtest("a=a0..a2; b0..b2")) + + # passing a Group as sheet arg + axis = Axis('dim=1d,2d,3d,5d') + + arr = read_excel(inputpath('test.xlsx'), axis['1d']) + assert_array_equal(arr, self.io_1d) + + # missing rows + fill_value argument + arr = read_excel(inputpath('test.xlsx'), 'missing_values', fill_value=42) + expected = self.io_missing_values.copy() + expected[isnan(expected)] = 42 + assert_array_equal(arr, expected) + + ################# + # narrow format # + ################# + arr = read_excel(inputpath('test_narrow.xlsx'), '1d', wide=False) + assert_array_equal(arr, self.io_1d) + + arr = read_excel(inputpath('test_narrow.xlsx'), '2d', wide=False) + assert_array_equal(arr, self.io_2d) + + arr = read_excel(inputpath('test_narrow.xlsx'), '3d', wide=False) + assert_array_equal(arr, self.io_3d) + + # missing rows + fill_value argument + arr = read_excel(inputpath('test_narrow.xlsx'), 'missing_values', fill_value=42, wide=False) + expected = self.io_narrow_missing_values.copy() + expected[isnan(expected)] = 42 + assert_array_equal(arr, expected) + + # unsorted values + arr = read_excel(inputpath('test_narrow.xlsx'), 'unsorted', wide=False) + assert_array_equal(arr, self.io_unsorted) + + ############################## + # invalid keyword argument # + ############################## + + with self.assertRaisesRegexp(TypeError, "'dtype' is an invalid keyword argument for this function when using " + "the xlwings backend"): + read_excel(inputpath('test.xlsx'), engine='xlwings', dtype=float) + + ################# + # blank cells # + ################# + + # Excel sheet with blank cells on right/bottom border of the array to read + fpath = inputpath('test_blank_cells.xlsx') + good = read_excel(fpath, 'good') + bad1 = read_excel(fpath, 'blanksafter_morerowsthancols') + bad2 = read_excel(fpath, 'blanksafter_morecolsthanrows') + assert_array_equal(bad1, good) + assert_array_equal(bad2, good) + # with additional empty column in the middle of the array to read + good2 = ndtest('a=a0,a1;b=2003..2006').astype(object) + good2[2005] = None + good2 = good2.set_axes('b', Axis([2003, 2004, None, 2006], 'b')) + bad3 = read_excel(fpath, 'middleblankcol') + bad4 = read_excel(fpath, '16384col') + assert_array_equal(bad3, good2) + assert_array_equal(bad4, good2) + + def test_read_excel_pandas(self): + arr = read_excel(inputpath('test.xlsx'), '1d', engine='xlrd') + assert_array_equal(arr, self.io_1d) + + arr = read_excel(inputpath('test.xlsx'), '2d', nb_axes=2, engine='xlrd') + assert_array_equal(arr, self.io_2d) + + arr = read_excel(inputpath('test.xlsx'), '2d', engine='xlrd') + assert_array_equal(arr, self.io_2d) + + arr = read_excel(inputpath('test.xlsx'), '3d', index_col=[0, 1], engine='xlrd') + assert_array_equal(arr, self.io_3d) + + arr = read_excel(inputpath('test.xlsx'), '3d', engine='xlrd') + assert_array_equal(arr, self.io_3d) + + arr = read_excel(inputpath('test.xlsx'), 'int_labels', engine='xlrd') + assert_array_equal(arr, self.io_int_labels) + + arr = read_excel(inputpath('test.xlsx'), '2d_classic', engine='xlrd') + assert_array_equal(arr, ndtest("a=a0..a2; b0..b2")) + + # passing a Group as sheet arg + axis = Axis('dim=1d,2d,3d,5d') + + arr = read_excel(inputpath('test.xlsx'), axis['1d'], engine='xlrd') + assert_array_equal(arr, self.io_1d) + + # missing rows + fill_value argument + arr = read_excel(inputpath('test.xlsx'), 'missing_values', fill_value=42, engine='xlrd') + expected = self.io_missing_values.copy() + expected[isnan(expected)] = 42 + assert_array_equal(arr, expected) + + ################# + # narrow format # + ################# + arr = read_excel(inputpath('test_narrow.xlsx'), '1d', wide=False, engine='xlrd') + assert_array_equal(arr, self.io_1d) + + arr = read_excel(inputpath('test_narrow.xlsx'), '2d', wide=False, engine='xlrd') + assert_array_equal(arr, self.io_2d) + + arr = read_excel(inputpath('test_narrow.xlsx'), '3d', wide=False, engine='xlrd') + assert_array_equal(arr, self.io_3d) + + # missing rows + fill_value argument + arr = read_excel(inputpath('test_narrow.xlsx'), 'missing_values', + fill_value=42, wide=False, engine='xlrd') + expected = self.io_narrow_missing_values + expected[isnan(expected)] = 42 + assert_array_equal(arr, expected) + + # unsorted values + arr = read_excel(inputpath('test_narrow.xlsx'), 'unsorted', wide=False, engine='xlrd') + assert_array_equal(arr, self.io_unsorted) + + ################# + # blank cells # + ################# + + # Excel sheet with blank cells on right/bottom border of the array to read + fpath = inputpath('test_blank_cells.xlsx') + good1 = read_excel(fpath, 'good', engine='xlrd') + bad1 = read_excel(fpath, 'blanksafter_morerowsthancols', engine='xlrd') + bad2 = read_excel(fpath, 'blanksafter_morecolsthanrows', engine='xlrd') + assert_array_equal(bad1, good1) + assert_array_equal(bad2, good1) + + # with additional empty column in the middle of the array to read + good2 = ndtest('a=a0,a1;b=2003..2006').astype(float) + good2[2005] = np.nan + good2 = good2.set_axes('b', Axis([2003, 2004, 'Unnamed: 3', 2006], 'b')) + bad3 = read_excel(fpath, 'middleblankcol', engine='xlrd') + bad4 = read_excel(fpath, '16384col', engine='xlrd') + assert_array_nan_equal(bad3, good2) + assert_array_nan_equal(bad4, good2) + + def test_from_lists(self): + # sort_rows + arr = from_lists([['sex', 'nat\\year', 1991, 1992, 1993], + ['F', 'BE', 0, 0, 1], + ['F', 'FO', 0, 0, 2], + ['M', 'BE', 1, 0, 0], + ['M', 'FO', 2, 0, 0]]) + sorted_arr = from_lists([['sex', 'nat\\year', 1991, 1992, 1993], + ['M', 'BE', 1, 0, 0], + ['M', 'FO', 2, 0, 0], + ['F', 'BE', 0, 0, 1], + ['F', 'FO', 0, 0, 2]], sort_rows=True) + assert_array_equal(sorted_arr, arr) + + # sort_columns + arr = from_lists([['sex', 'nat\\year', 1991, 1992, 1993], + ['M', 'BE', 1, 0, 0], + ['M', 'FO', 2, 0, 0], + ['F', 'BE', 0, 0, 1], + ['F', 'FO', 0, 0, 2]]) + sorted_arr = from_lists([['sex', 'nat\\year', 1992, 1991, 1993], + ['M', 'BE', 0, 1, 0], + ['M', 'FO', 0, 2, 0], + ['F', 'BE', 0, 0, 1], + ['F', 'FO', 0, 0, 2]], sort_columns=True) + assert_array_equal(sorted_arr, arr) + + def test_from_series(self): + expected = ndtest(3) + s = pd.Series([0, 1, 2], index=pd.Index(['a0', 'a1', 'a2'], name='a')) + assert_array_equal(from_series(s), expected) + + s = pd.Series([2, 0, 1], index=pd.Index(['a2', 'a0', 'a1'], name='a')) + assert_array_equal(from_series(s, sort_rows=True), expected) + + expected = ndtest(3)[['a2', 'a0', 'a1']] + assert_array_equal(from_series(s), expected) + + def test_from_frame(self): + # 1) data = scalar + # ================ + # Dataframe becomes 1D LArray + data = np.array([10]) + index = ['i0'] + columns = ['c0'] + axis_index, axis_columns = Axis(index), Axis(columns) + + df = pd.DataFrame(data, index=index, columns=columns) + assert df.index.name is None + assert df.columns.name is None + assert list(df.index.values) == index + assert list(df.columns.values) == columns + + # anonymous indexes/columns + # input dataframe: + # ---------------- + # c0 + # i0 10 + # output LArray: + # -------------- + # {0}\{1} c0 + # i0 10 + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, 1) + assert la.axes.names == [None, None] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, 1)), [axis_index, axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous columns + # input dataframe: + # ---------------- + # c0 + # index + # i0 10 + # output LArray: + # -------------- + # index\{1} c0 + # i0 10 + df.index.name, df.columns.name = 'index', None + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, 1) + assert la.axes.names == ['index', None] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, 1)), [axis_index.rename('index'), axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous index + # input dataframe: + # ---------------- + # columns c0 + # i0 10 + # output LArray: + # -------------- + # {0}\columns c0 + # i0 10 + df.index.name, df.columns.name = None, 'columns' + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, 1) + assert la.axes.names == [None, 'columns'] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, 1)), [axis_index, axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # index and columns with name + # input dataframe: + # ---------------- + # columns c0 + # index + # i0 10 + # output LArray: + # -------------- + # index\columns c0 + # i0 10 + df.index.name, df.columns.name = 'index', 'columns' + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, 1) + assert la.axes.names == ['index', 'columns'] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, 1)), [axis_index.rename('index'), axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # 2) data = vector + # ================ + size = 3 + + # 2A) data = horizontal vector (1 x N) + # ==================================== + # Dataframe becomes 1D LArray + data = np.arange(size) + indexes = ['i0'] + columns = ['c{}'.format(i) for i in range(size)] + axis_index, axis_columns = Axis(indexes), Axis(columns) + + df = pd.DataFrame(data.reshape(1, size), index=indexes, columns=columns) + assert df.index.name is None + assert df.columns.name is None + assert list(df.index.values) == indexes + assert list(df.columns.values) == columns + + # anonymous indexes/columns + # input dataframe: + # ---------------- + # c0 c1 c2 + # i0 0 1 2 + # output LArray: + # -------------- + # {0}\{1} c0 c1 c2 + # i0 0 1 2 + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, size) + assert la.axes.names == [None, None] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, size)),[axis_index, axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous columns + # input dataframe: + # ---------------- + # c0 c1 c2 + # index + # i0 0 1 2 + # output LArray: + # -------------- + # index\{1} c0 c1 c2 + # i0 0 1 2 + df.index.name, df.columns.name = 'index', None + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, size) + assert la.axes.names == ['index', None] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, size)),[axis_index.rename('index'), axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous index + # input dataframe: + # ---------------- + # columns c0 c1 c2 + # i0 0 1 2 + # output LArray: + # -------------- + # {0}\columns c0 c1 c2 + # i0 0 1 2 + df.index.name, df.columns.name = None, 'columns' + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, size) + assert la.axes.names == [None, 'columns'] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, size)),[axis_index, axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # index and columns with name + # input dataframe: + # ---------------- + # columns c0 c1 c2 + # index + # i0 0 1 2 + # output LArray: + # -------------- + # index\columns c0 c1 c2 + # i0 0 1 2 + df.index.name, df.columns.name = 'index', 'columns' + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, size) + assert la.axes.names == ['index', 'columns'] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, size)),[axis_index.rename('index'), axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # 2B) data = vertical vector (N x 1) + # ================================== + # Dataframe becomes 2D LArray + data = data.reshape(size, 1) + indexes = ['i{}'.format(i) for i in range(size)] + columns = ['c0'] + axis_index, axis_columns = Axis(indexes), Axis(columns) + + df = pd.DataFrame(data, index=indexes, columns=columns) + assert df.index.name is None + assert df.columns.name is None + assert list(df.index.values) == indexes + assert list(df.columns.values) == columns + + # anonymous indexes/columns + # input dataframe: + # ---------------- + # c0 + # i0 0 + # i1 1 + # i2 2 + # output LArray: + # -------------- + # {0}\{1} c0 + # i0 0 + # i1 1 + # i2 2 + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (size, 1) + assert la.axes.names == [None, None] + assert list(la.axes.labels[0]) == indexes + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data, [axis_index, axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous columns + # input dataframe: + # ---------------- + # c0 + # index + # i0 0 + # i1 1 + # i2 2 + # output LArray: + # -------------- + # index\{1} c0 + # i0 0 + # i1 1 + # i2 2 + df.index.name, df.columns.name = 'index', None + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (size, 1) + assert la.axes.names == ['index', None] + assert list(la.axes.labels[0]) == indexes + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data, [axis_index.rename('index'), axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous index + # input dataframe: + # ---------------- + # columns c0 + # i0 0 + # i1 1 + # i2 2 + # output LArray: + # -------------- + # {0}\columns c0 + # i0 0 + # i1 1 + # i2 2 + df.index.name, df.columns.name = None, 'columns' + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (size, 1) + assert la.axes.names == [None, 'columns'] + assert list(la.axes.labels[0]) == indexes + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data, [axis_index, axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # index and columns with name + # input dataframe: + # ---------------- + # columns c0 + # index + # i0 0 + # i1 1 + # i2 2 + # output LArray: + # -------------- + # {0}\columns c0 + # i0 0 + # i1 1 + # i2 2 + df.index.name, df.columns.name = 'index', 'columns' + assert la.ndim == 2 + assert la.shape == (size, 1) + assert la.axes.names == [None, 'columns'] + assert list(la.axes.labels[0]) == indexes + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data, [axis_index, axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # 3) 3D array + # =========== + + # 3A) Dataframe with 2 index columns + # ================================== + dt = [('age', int), ('sex', 'U1'), + ('2007', int), ('2010', int), ('2013', int)] + data = np.array([ + (0, 'F', 3722, 3395, 3347), + (0, 'M', 338, 316, 323), + (1, 'F', 2878, 2791, 2822), + (1, 'M', 1121, 1037, 976), + (2, 'F', 4073, 4161, 4429), + (2, 'M', 1561, 1463, 1467), + (3, 'F', 3507, 3741, 3366), + (3, 'M', 2052, 2052, 2118), + ], dtype=dt) + df = pd.DataFrame(data) + df.set_index(['age', 'sex'], inplace=True) + df.columns.name = 'time' + + la = from_frame(df) + assert la.ndim == 3 + assert la.shape == (4, 2, 3) + assert la.axes.names == ['age', 'sex', 'time'] + assert_array_equal(la[0, 'F', :], [3722, 3395, 3347]) + + # 3B) Dataframe with columns.name containing \\ + # ============================================= + dt = [('age', int), ('sex\\time', 'U1'), + ('2007', int), ('2010', int), ('2013', int)] + data = np.array([ + (0, 'F', 3722, 3395, 3347), + (0, 'M', 338, 316, 323), + (1, 'F', 2878, 2791, 2822), + (1, 'M', 1121, 1037, 976), + (2, 'F', 4073, 4161, 4429), + (2, 'M', 1561, 1463, 1467), + (3, 'F', 3507, 3741, 3366), + (3, 'M', 2052, 2052, 2118), + ], dtype=dt) + df = pd.DataFrame(data) + df.set_index(['age', 'sex\\time'], inplace=True) + + la = from_frame(df, unfold_last_axis_name=True) + assert la.ndim == 3 + assert la.shape == (4, 2, 3) + assert la.axes.names == ['age', 'sex', 'time'] + assert_array_equal(la[0, 'F', :], [3722, 3395, 3347]) + + def test_to_csv(self): + arr = self.io_3d.copy() + + arr.to_csv(self.tmp_path('out.csv')) + result = ['a,b\\c,c0,c1,c2\n', + '1,b0,0,1,2\n', + '1,b1,3,4,5\n'] + with open(self.tmp_path('out.csv')) as f: + self.assertEqual(f.readlines()[:3], result) + + # stacked data (one column containing all the values and another column listing the context of the value) + arr.to_csv(self.tmp_path('out.csv'), wide=False) + result = ['a,b,c,value\n', + '1,b0,c0,0\n', + '1,b0,c1,1\n'] + with open(self.tmp_path('out.csv')) as f: + self.assertEqual(f.readlines()[:3], result) + + arr = self.io_1d.copy() + arr.to_csv(self.tmp_path('test_out1d.csv')) + result = ['a,a0,a1,a2\n', + ',0,1,2\n'] + with open(self.tmp_path('test_out1d.csv')) as f: + self.assertEqual(f.readlines(), result) + + def test_to_excel_xlsxwriter(self): + fpath = self.tmp_path('test_to_excel_xlsxwriter.xlsx') + + # 1D + a1 = ndtest(3) + + # fpath/Sheet1/A1 + a1.to_excel(fpath, overwrite_file=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # fpath/Sheet1/A1(transposed) + a1.to_excel(fpath, transpose=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # fpath/Sheet1/A1 + # stacked data (one column containing all the values and another column listing the context of the value) + a1.to_excel(fpath, wide=False, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + stacked_a1 = a1.reshape([a1.a, Axis(['value'])]) + assert_array_equal(res, stacked_a1) + + # 2D + a2 = ndtest((2, 3)) + + # fpath/Sheet1/A1 + a2.to_excel(fpath, overwrite_file=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a2) + + # fpath/Sheet1/A10 + # TODO: this is currently not supported (though we would only need to translate A10 to startrow=0 and startcol=0 + # a2.to_excel('fpath', 'Sheet1', 'A10', engine='xlsxwriter') + # res = read_excel('fpath', 'Sheet1', engine='xlrd', skiprows=9) + # assert_array_equal(res, a2) + + # fpath/other/A1 + a2.to_excel(fpath, 'other', engine='xlsxwriter') + res = read_excel(fpath, 'other', engine='xlrd') + assert_array_equal(res, a2) + + # 3D + a3 = ndtest((2, 3, 4)) + + # fpath/Sheet1/A1 + # FIXME: merge_cells=False should be the default (until Pandas is fixed to read its format) + a3.to_excel(fpath, overwrite_file=True, engine='xlsxwriter', merge_cells=False) + # a3.to_excel('fpath', overwrite_file=True, engine='openpyxl') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a3) + + # fpath/Sheet1/A20 + # TODO: implement position (see above) + # a3.to_excel('fpath', 'Sheet1', 'A20', engine='xlsxwriter', merge_cells=False) + # res = read_excel('fpath', 'Sheet1', engine='xlrd', skiprows=19) + # assert_array_equal(res, a3) + + # fpath/other/A1 + a3.to_excel(fpath, 'other', engine='xlsxwriter', merge_cells=False) + res = read_excel(fpath, 'other', engine='xlrd') + assert_array_equal(res, a3) + + # 1D + a1 = ndtest(3) + + # fpath/Sheet1/A1 + a1.to_excel(fpath, overwrite_file=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # fpath/Sheet1/A1(transposed) + a1.to_excel(fpath, transpose=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # fpath/Sheet1/A1 + # stacked data (one column containing all the values and another column listing the context of the value) + a1.to_excel(fpath, wide=False, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + stacked_a1 = a1.reshape([a1.a, Axis(['value'])]) + assert_array_equal(res, stacked_a1) + + # 2D + a2 = ndtest((2, 3)) + + # fpath/Sheet1/A1 + a2.to_excel(fpath, overwrite_file=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a2) + + # fpath/Sheet1/A10 + # TODO: this is currently not supported (though we would only need to translate A10 to startrow=0 and startcol=0 + # a2.to_excel(fpath, 'Sheet1', 'A10', engine='xlsxwriter') + # res = read_excel('fpath', 'Sheet1', engine='xlrd', skiprows=9) + # assert_array_equal(res, a2) + + # fpath/other/A1 + a2.to_excel(fpath, 'other', engine='xlsxwriter') + res = read_excel(fpath, 'other', engine='xlrd') + assert_array_equal(res, a2) + + # 3D + a3 = ndtest((2, 3, 4)) + + # fpath/Sheet1/A1 + # FIXME: merge_cells=False should be the default (until Pandas is fixed to read its format) + a3.to_excel(fpath, overwrite_file=True, engine='xlsxwriter', merge_cells=False) + # a3.to_excel('fpath', overwrite_file=True, engine='openpyxl') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a3) + + # fpath/Sheet1/A20 + # TODO: implement position (see above) + # a3.to_excel('fpath', 'Sheet1', 'A20', engine='xlsxwriter', merge_cells=False) + # res = read_excel('fpath', 'Sheet1', engine='xlrd', skiprows=19) + # assert_array_equal(res, a3) + + # fpath/other/A1 + a3.to_excel(fpath, 'other', engine='xlsxwriter', merge_cells=False) + res = read_excel(fpath, 'other', engine='xlrd') + assert_array_equal(res, a3) + + ################# + # narrow format # + ################# + arr = read_excel(inputpath('test_narrow.xlsx'), '1d', wide=False) + assert_array_equal(arr, io_1d) + + arr = read_excel(inputpath('test_narrow.xlsx'), '2d', wide=False) + assert_array_equal(arr, io_2d) + + arr = read_excel(inputpath('test_narrow.xlsx'), '3d', wide=False) + assert_array_equal(arr, io_3d) + + # missing rows + fill_value argument + arr = read_excel(inputpath('test_narrow.xlsx'), 'missing_values', fill_value=42, wide=False) + expected = io_narrow_missing_values.copy() + expected[isnan(expected)] = 42 + assert_array_equal(arr, expected) + + # unsorted values + arr = read_excel(inputpath('test_narrow.xlsx'), 'unsorted', wide=False) + assert_array_equal(arr, io_unsorted) + + ############################## + # invalid keyword argument # + ############################## + + with pytest.raises(TypeError, message="'dtype' is an invalid keyword argument for this function " + "when using the xlwings backend"): + read_excel(inputpath('test.xlsx'), engine='xlwings', dtype=float) + + ################# + # blank cells # + ################# + + # Excel sheet with blank cells on right/bottom border of the array to read + fpath = inputpath('test_blank_cells.xlsx') + good = read_excel(fpath, 'good') + bad1 = read_excel(fpath, 'blanksafter_morerowsthancols') + bad2 = read_excel(fpath, 'blanksafter_morecolsthanrows') + assert_array_equal(bad1, good) + assert_array_equal(bad2, good) + # with additional empty column in the middle of the array to read + good2 = ndtest('a=a0,a1;b=2003..2006').astype(object) + good2[2005] = None + good2 = good2.set_axes('b', Axis([2003, 2004, None, 2006], 'b')) + bad3 = read_excel(fpath, 'middleblankcol') + bad4 = read_excel(fpath, '16384col') + assert_array_equal(bad3, good2) + assert_array_equal(bad4, good2) + + +def test_read_excel_pandas(): + arr = read_excel(inputpath('test.xlsx'), '1d', engine='xlrd') + assert_array_equal(arr, io_1d) + + arr = read_excel(inputpath('test.xlsx'), '2d', nb_axes=2, engine='xlrd') + assert_array_equal(arr, io_2d) + + arr = read_excel(inputpath('test.xlsx'), '2d', engine='xlrd') + assert_array_equal(arr, io_2d) + + arr = read_excel(inputpath('test.xlsx'), '3d', index_col=[0, 1], engine='xlrd') + assert_array_equal(arr, io_3d) + + arr = read_excel(inputpath('test.xlsx'), '3d', engine='xlrd') + assert_array_equal(arr, io_3d) + + arr = read_excel(inputpath('test.xlsx'), 'int_labels', engine='xlrd') + assert_array_equal(arr, io_int_labels) + + arr = read_excel(inputpath('test.xlsx'), '2d_classic', engine='xlrd') + assert_array_equal(arr, ndtest("a=a0..a2; b0..b2")) + + # passing a Group as sheet arg + axis = Axis('dim=1d,2d,3d,5d') + + arr = read_excel(inputpath('test.xlsx'), axis['1d'], engine='xlrd') + assert_array_equal(arr, io_1d) + + # missing rows + fill_value argument + arr = read_excel(inputpath('test.xlsx'), 'missing_values', fill_value=42, engine='xlrd') + expected = io_missing_values.copy() + expected[isnan(expected)] = 42 + assert_array_equal(arr, expected) + + ################# + # narrow format # + ################# + arr = read_excel(inputpath('test_narrow.xlsx'), '1d', wide=False, engine='xlrd') + assert_array_equal(arr, io_1d) + + arr = read_excel(inputpath('test_narrow.xlsx'), '2d', wide=False, engine='xlrd') + assert_array_equal(arr, io_2d) + + arr = read_excel(inputpath('test_narrow.xlsx'), '3d', wide=False, engine='xlrd') + assert_array_equal(arr, io_3d) + + # missing rows + fill_value argument + arr = read_excel(inputpath('test_narrow.xlsx'), 'missing_values', + fill_value=42, wide=False, engine='xlrd') + expected = io_narrow_missing_values + expected[isnan(expected)] = 42 + assert_array_equal(arr, expected) + + # unsorted values + arr = read_excel(inputpath('test_narrow.xlsx'), 'unsorted', wide=False, engine='xlrd') + assert_array_equal(arr, io_unsorted) + + ################# + # blank cells # + ################# + + # Excel sheet with blank cells on right/bottom border of the array to read + fpath = inputpath('test_blank_cells.xlsx') + good1 = read_excel(fpath, 'good', engine='xlrd') + bad1 = read_excel(fpath, 'blanksafter_morerowsthancols', engine='xlrd') + bad2 = read_excel(fpath, 'blanksafter_morecolsthanrows', engine='xlrd') + assert_array_equal(bad1, good1) + assert_array_equal(bad2, good1) + + # with additional empty column in the middle of the array to read + good2 = ndtest('a=a0,a1;b=2003..2006').astype(float) + good2[2005] = nan + good2 = good2.set_axes('b', Axis([2003, 2004, 'Unnamed: 3', 2006], 'b')) + bad3 = read_excel(fpath, 'middleblankcol', engine='xlrd') + bad4 = read_excel(fpath, '16384col', engine='xlrd') + assert_array_nan_equal(bad3, good2) + assert_array_nan_equal(bad4, good2) + + +def test_from_lists(): + # sort_rows + arr = from_lists([['sex', 'nat\\year', 1991, 1992, 1993], + ['F', 'BE', 0, 0, 1], + ['F', 'FO', 0, 0, 2], + ['M', 'BE', 1, 0, 0], + ['M', 'FO', 2, 0, 0]]) + sorted_arr = from_lists([['sex', 'nat\\year', 1991, 1992, 1993], + ['M', 'BE', 1, 0, 0], + ['M', 'FO', 2, 0, 0], + ['F', 'BE', 0, 0, 1], + ['F', 'FO', 0, 0, 2]], sort_rows=True) + assert_array_equal(sorted_arr, arr) + + # sort_columns + arr = from_lists([['sex', 'nat\\year', 1991, 1992, 1993], + ['M', 'BE', 1, 0, 0], + ['M', 'FO', 2, 0, 0], + ['F', 'BE', 0, 0, 1], + ['F', 'FO', 0, 0, 2]]) + sorted_arr = from_lists([['sex', 'nat\\year', 1992, 1991, 1993], + ['M', 'BE', 0, 1, 0], + ['M', 'FO', 0, 2, 0], + ['F', 'BE', 0, 0, 1], + ['F', 'FO', 0, 0, 2]], sort_columns=True) + assert_array_equal(sorted_arr, arr) + + +def test_from_series(): + # Series with Index as index + expected = ndtest(3) + s = pd.Series([0, 1, 2], index=pd.Index(['a0', 'a1', 'a2'], name='a')) + assert_array_equal(from_series(s), expected) + + s = pd.Series([2, 0, 1], index=pd.Index(['a2', 'a0', 'a1'], name='a')) + assert_array_equal(from_series(s, sort_rows=True), expected) + + expected = ndtest(3)[['a2', 'a0', 'a1']] + assert_array_equal(from_series(s), expected) + + # Series with MultiIndex as index + age = Axis('age=0..3') + gender = Axis('gender=M,F') + time = Axis('time=2015..2017') + expected = ndtest((age, gender, time)) + + index = pd.MultiIndex.from_product(expected.axes.labels, names=expected.axes.names) + data = expected.data.flatten() + s = pd.Series(data, index) + + res = from_series(s) + assert_array_equal(res, expected) + + res = from_series(s, sort_rows=True) + assert_array_equal(res, expected.sort_axes()) + + expected[0, 'F'] = -1 + s = s.reset_index().drop([3, 4, 5]).set_index(['age', 'gender', 'time'])[0] + res = from_series(s, fill_value=-1) + assert_array_equal(res, expected) + + +def test_from_frame(): + # 1) data = scalar + # ================ + # Dataframe becomes 1D LArray + data = np.array([10]) + index = ['i0'] + columns = ['c0'] + axis_index, axis_columns = Axis(index), Axis(columns) + + df = pd.DataFrame(data, index=index, columns=columns) + assert df.index.name is None + assert df.columns.name is None + assert list(df.index.values) == index + assert list(df.columns.values) == columns + + # anonymous indexes/columns + # input dataframe: + # ---------------- + # c0 + # i0 10 + # output LArray: + # -------------- + # {0}\{1} c0 + # i0 10 + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, 1) + assert la.axes.names == [None, None] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, 1)), [axis_index, axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous columns + # input dataframe: + # ---------------- + # c0 + # index + # i0 10 + # output LArray: + # -------------- + # index\{1} c0 + # i0 10 + df.index.name, df.columns.name = 'index', None + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, 1) + assert la.axes.names == ['index', None] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, 1)), [axis_index.rename('index'), axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous index + # input dataframe: + # ---------------- + # columns c0 + # i0 10 + # output LArray: + # -------------- + # {0}\columns c0 + # i0 10 + df.index.name, df.columns.name = None, 'columns' + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, 1) + assert la.axes.names == [None, 'columns'] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, 1)), [axis_index, axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # index and columns with name + # input dataframe: + # ---------------- + # columns c0 + # index + # i0 10 + # output LArray: + # -------------- + # index\columns c0 + # i0 10 + df.index.name, df.columns.name = 'index', 'columns' + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, 1) + assert la.axes.names == ['index', 'columns'] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, 1)), [axis_index.rename('index'), axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # 2) data = vector + # ================ + size = 3 + + # 2A) data = horizontal vector (1 x N) + # ==================================== + # Dataframe becomes 1D LArray + data = np.arange(size) + indexes = ['i0'] + columns = ['c{}'.format(i) for i in range(size)] + axis_index, axis_columns = Axis(indexes), Axis(columns) + + df = pd.DataFrame(data.reshape(1, size), index=indexes, columns=columns) + assert df.index.name is None + assert df.columns.name is None + assert list(df.index.values) == indexes + assert list(df.columns.values) == columns + + # anonymous indexes/columns + # input dataframe: + # ---------------- + # c0 c1 c2 + # i0 0 1 2 + # output LArray: + # -------------- + # {0}\{1} c0 c1 c2 + # i0 0 1 2 + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, size) + assert la.axes.names == [None, None] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, size)), [axis_index, axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous columns + # input dataframe: + # ---------------- + # c0 c1 c2 + # index + # i0 0 1 2 + # output LArray: + # -------------- + # index\{1} c0 c1 c2 + # i0 0 1 2 + df.index.name, df.columns.name = 'index', None + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, size) + assert la.axes.names == ['index', None] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, size)), [axis_index.rename('index'), axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous index + # input dataframe: + # ---------------- + # columns c0 c1 c2 + # i0 0 1 2 + # output LArray: + # -------------- + # {0}\columns c0 c1 c2 + # i0 0 1 2 + df.index.name, df.columns.name = None, 'columns' + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, size) + assert la.axes.names == [None, 'columns'] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, size)), [axis_index, axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # index and columns with name + # input dataframe: + # ---------------- + # columns c0 c1 c2 + # index + # i0 0 1 2 + # output LArray: + # -------------- + # index\columns c0 c1 c2 + # i0 0 1 2 + df.index.name, df.columns.name = 'index', 'columns' + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (1, size) + assert la.axes.names == ['index', 'columns'] + assert list(la.axes.labels[0]) == index + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data.reshape((1, size)), [axis_index.rename('index'), axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # 2B) data = vertical vector (N x 1) + # ================================== + # Dataframe becomes 2D LArray + data = data.reshape(size, 1) + indexes = ['i{}'.format(i) for i in range(size)] + columns = ['c0'] + axis_index, axis_columns = Axis(indexes), Axis(columns) + + df = pd.DataFrame(data, index=indexes, columns=columns) + assert df.index.name is None + assert df.columns.name is None + assert list(df.index.values) == indexes + assert list(df.columns.values) == columns + + # anonymous indexes/columns + # input dataframe: + # ---------------- + # c0 + # i0 0 + # i1 1 + # i2 2 + # output LArray: + # -------------- + # {0}\{1} c0 + # i0 0 + # i1 1 + # i2 2 + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (size, 1) + assert la.axes.names == [None, None] + assert list(la.axes.labels[0]) == indexes + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data, [axis_index, axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous columns + # input dataframe: + # ---------------- + # c0 + # index + # i0 0 + # i1 1 + # i2 2 + # output LArray: + # -------------- + # index\{1} c0 + # i0 0 + # i1 1 + # i2 2 + df.index.name, df.columns.name = 'index', None + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (size, 1) + assert la.axes.names == ['index', None] + assert list(la.axes.labels[0]) == indexes + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data, [axis_index.rename('index'), axis_columns]) + assert_array_equal(la, expected_la) + + # anonymous index + # input dataframe: + # ---------------- + # columns c0 + # i0 0 + # i1 1 + # i2 2 + # output LArray: + # -------------- + # {0}\columns c0 + # i0 0 + # i1 1 + # i2 2 + df.index.name, df.columns.name = None, 'columns' + la = from_frame(df) + assert la.ndim == 2 + assert la.shape == (size, 1) + assert la.axes.names == [None, 'columns'] + assert list(la.axes.labels[0]) == indexes + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data, [axis_index, axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # index and columns with name + # input dataframe: + # ---------------- + # columns c0 + # index + # i0 0 + # i1 1 + # i2 2 + # output LArray: + # -------------- + # {0}\columns c0 + # i0 0 + # i1 1 + # i2 2 + df.index.name, df.columns.name = 'index', 'columns' + assert la.ndim == 2 + assert la.shape == (size, 1) + assert la.axes.names == [None, 'columns'] + assert list(la.axes.labels[0]) == indexes + assert list(la.axes.labels[1]) == columns + expected_la = LArray(data, [axis_index, axis_columns.rename('columns')]) + assert_array_equal(la, expected_la) + + # 3) 3D array + # =========== + + # 3A) Dataframe with 2 index columns + # ================================== + dt = [('age', int), ('sex', 'U1'), + ('2007', int), ('2010', int), ('2013', int)] + data = np.array([ + (0, 'F', 3722, 3395, 3347), + (0, 'M', 338, 316, 323), + (1, 'F', 2878, 2791, 2822), + (1, 'M', 1121, 1037, 976), + (2, 'F', 4073, 4161, 4429), + (2, 'M', 1561, 1463, 1467), + (3, 'F', 3507, 3741, 3366), + (3, 'M', 2052, 2052, 2118), + ], dtype=dt) + df = pd.DataFrame(data) + df.set_index(['age', 'sex'], inplace=True) + df.columns.name = 'time' + + la = from_frame(df) + assert la.ndim == 3 + assert la.shape == (4, 2, 3) + assert la.axes.names == ['age', 'sex', 'time'] + assert_array_equal(la[0, 'F', :], [3722, 3395, 3347]) + + # 3B) Dataframe with columns.name containing \\ + # ============================================= + dt = [('age', int), ('sex\\time', 'U1'), + ('2007', int), ('2010', int), ('2013', int)] + data = np.array([ + (0, 'F', 3722, 3395, 3347), + (0, 'M', 338, 316, 323), + (1, 'F', 2878, 2791, 2822), + (1, 'M', 1121, 1037, 976), + (2, 'F', 4073, 4161, 4429), + (2, 'M', 1561, 1463, 1467), + (3, 'F', 3507, 3741, 3366), + (3, 'M', 2052, 2052, 2118), + ], dtype=dt) + df = pd.DataFrame(data) + df.set_index(['age', 'sex\\time'], inplace=True) + + la = from_frame(df, unfold_last_axis_name=True) + assert la.ndim == 3 + assert la.shape == (4, 2, 3) + assert la.axes.names == ['age', 'sex', 'time'] + assert_array_equal(la[0, 'F', :], [3722, 3395, 3347]) + + # 4) test sort_rows and sort_columns arguments + # ============================================ + age = Axis('age=2,0,1,3') + gender = Axis('gender=M,F') + time = Axis('time=2016,2015,2017') + columns = pd.Index(time.labels, name=time.name) + + # df.index is an Index instance + expected = ndtest((gender, time)) + index = pd.Index(gender.labels, name=gender.name) + data = expected.data + df = pd.DataFrame(data, index=index, columns=columns) + + expected = expected.sort_axes() + res = from_frame(df, sort_rows=True, sort_columns=True) + assert_array_equal(res, expected) + + # df.index is a MultiIndex instance + expected = ndtest((age, gender, time)) + index = pd.MultiIndex.from_product(expected.axes[:-1].labels, names=expected.axes[:-1].names) + data = expected.data.reshape(len(age) * len(gender), len(time)) + df = pd.DataFrame(data, index=index, columns=columns) + + res = from_frame(df, sort_rows=True, sort_columns=True) + assert_array_equal(res, expected.sort_axes()) + + # 5) test fill_value + # ================== + expected[0, 'F'] = -1 + df = df.reset_index().drop([3]).set_index(['age', 'gender']) + res = from_frame(df, fill_value=-1) + assert_array_equal(res, expected) + + +def test_to_csv(tmpdir): + arr = io_3d.copy() + + arr.to_csv(tmp_path(tmpdir, 'out.csv')) + result = ['a,b\\c,c0,c1,c2\n', + '1,b0,0,1,2\n', + '1,b1,3,4,5\n'] + with open(tmp_path(tmpdir, 'out.csv')) as f: + assert f.readlines()[:3] == result + + # stacked data (one column containing all the values and another column listing the context of the value) + arr.to_csv(tmp_path(tmpdir, 'out.csv'), wide=False) + result = ['a,b,c,value\n', + '1,b0,c0,0\n', + '1,b0,c1,1\n'] + with open(tmp_path(tmpdir, 'out.csv')) as f: + assert f.readlines()[:3] == result + + arr = io_1d.copy() + arr.to_csv(tmp_path(tmpdir, 'test_out1d.csv')) + result = ['a,a0,a1,a2\n', + ',0,1,2\n'] + with open(tmp_path(tmpdir, 'test_out1d.csv')) as f: + assert f.readlines() == result + + +def test_to_excel_xlsxwriter(tmpdir): + fpath = tmp_path(tmpdir, 'test_to_excel_xlsxwriter.xlsx') + + # 1D + a1 = ndtest(3) + + # fpath/Sheet1/A1 + a1.to_excel(fpath, overwrite_file=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # fpath/Sheet1/A1(transposed) + a1.to_excel(fpath, transpose=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # fpath/Sheet1/A1 + # stacked data (one column containing all the values and another column listing the context of the value) + a1.to_excel(fpath, wide=False, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + stacked_a1 = a1.reshape([a1.a, Axis(['value'])]) + assert_array_equal(res, stacked_a1) + + # 2D + a2 = ndtest((2, 3)) + + # fpath/Sheet1/A1 + a2.to_excel(fpath, overwrite_file=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a2) + + # fpath/Sheet1/A10 + # TODO: this is currently not supported (though we would only need to translate A10 to startrow=0 and startcol=0 + # a2.to_excel('fpath', 'Sheet1', 'A10', engine='xlsxwriter') + # res = read_excel('fpath', 'Sheet1', engine='xlrd', skiprows=9) + # assert_array_equal(res, a2) + + # fpath/other/A1 + a2.to_excel(fpath, 'other', engine='xlsxwriter') + res = read_excel(fpath, 'other', engine='xlrd') + assert_array_equal(res, a2) + + # 3D + a3 = ndtest((2, 3, 4)) + + # fpath/Sheet1/A1 + # FIXME: merge_cells=False should be the default (until Pandas is fixed to read its format) + a3.to_excel(fpath, overwrite_file=True, engine='xlsxwriter', merge_cells=False) + # a3.to_excel('fpath', overwrite_file=True, engine='openpyxl') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a3) + + # fpath/Sheet1/A20 + # TODO: implement position (see above) + # a3.to_excel('fpath', 'Sheet1', 'A20', engine='xlsxwriter', merge_cells=False) + # res = read_excel('fpath', 'Sheet1', engine='xlrd', skiprows=19) + # assert_array_equal(res, a3) + + # fpath/other/A1 + a3.to_excel(fpath, 'other', engine='xlsxwriter', merge_cells=False) + res = read_excel(fpath, 'other', engine='xlrd') + assert_array_equal(res, a3) + + # 1D + a1 = ndtest(3) + + # fpath/Sheet1/A1 + a1.to_excel(fpath, overwrite_file=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # fpath/Sheet1/A1(transposed) + a1.to_excel(fpath, transpose=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # fpath/Sheet1/A1 + # stacked data (one column containing all the values and another column listing the context of the value) + a1.to_excel(fpath, wide=False, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + stacked_a1 = a1.reshape([a1.a, Axis(['value'])]) + assert_array_equal(res, stacked_a1) + + # 2D + a2 = ndtest((2, 3)) + + # fpath/Sheet1/A1 + a2.to_excel(fpath, overwrite_file=True, engine='xlsxwriter') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a2) + + # fpath/Sheet1/A10 + # TODO: this is currently not supported (though we would only need to translate A10 to startrow=0 and startcol=0 + # a2.to_excel(fpath, 'Sheet1', 'A10', engine='xlsxwriter') + # res = read_excel('fpath', 'Sheet1', engine='xlrd', skiprows=9) + # assert_array_equal(res, a2) + + # fpath/other/A1 + a2.to_excel(fpath, 'other', engine='xlsxwriter') + res = read_excel(fpath, 'other', engine='xlrd') + assert_array_equal(res, a2) + + # 3D + a3 = ndtest((2, 3, 4)) + + # fpath/Sheet1/A1 + # FIXME: merge_cells=False should be the default (until Pandas is fixed to read its format) + a3.to_excel(fpath, overwrite_file=True, engine='xlsxwriter', merge_cells=False) + # a3.to_excel('fpath', overwrite_file=True, engine='openpyxl') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a3) + + # fpath/Sheet1/A20 + # TODO: implement position (see above) + # a3.to_excel('fpath', 'Sheet1', 'A20', engine='xlsxwriter', merge_cells=False) + # res = read_excel('fpath', 'Sheet1', engine='xlrd', skiprows=19) + # assert_array_equal(res, a3) + + # fpath/other/A1 + a3.to_excel(fpath, 'other', engine='xlsxwriter', merge_cells=False) + res = read_excel(fpath, 'other', engine='xlrd') + assert_array_equal(res, a3) + + # passing group as sheet_name + a3 = ndtest((4, 3, 4)) + os.remove(fpath) + # single element group + for label in a3.a: + a3[label].to_excel(fpath, label, engine='xlsxwriter') + # unnamed group + group = a3.c['c0,c2'] + a3[group].to_excel(fpath, group, engine='xlsxwriter') + # unnamed group + slice + group = a3.c['c0::2'] + a3[group].to_excel(fpath, group, engine='xlsxwriter') + # named group + group = a3.c['c0,c2'] >> 'even' + a3[group].to_excel(fpath, group, engine='xlsxwriter') + # group with name containing special characters (replaced by _) + group = a3.c['c0,c2'] >> ':name?with*special/\[char]' + a3[group].to_excel(fpath, group, engine='xlsxwriter') + + +@pytest.mark.skipif(xw is None, reason="xlwings is not available") +def test_to_excel_xlwings(tmpdir): + fpath = tmp_path(tmpdir, 'test_to_excel_xlwings.xlsx') + + # 1D + a1 = ndtest(3) + + # live book/Sheet1/A1 + # a1.to_excel() + + # fpath/Sheet1/A1 (create a new file if does not exist) + if os.path.isfile(fpath): + os.remove(fpath) + # single element group + for label in a3.a: + a3[label].to_excel(fpath, label, engine='xlsxwriter') + # unnamed group + group = a3.c['c0,c2'] + a3[group].to_excel(fpath, group, engine='xlsxwriter') + # unnamed group + slice + group = a3.c['c0::2'] + a3[group].to_excel(fpath, group, engine='xlsxwriter') + # named group + group = a3.c['c0,c2'] >> 'even' + a3[group].to_excel(fpath, group, engine='xlsxwriter') + # group with name containing special characters (replaced by _) + group = a3.c['c0,c2'] >> ':name?with*special/\[char]' + a3[group].to_excel(fpath, group, engine='xlsxwriter') + + @pytest.mark.skipif(xw is None, reason="xlwings is not available") + def test_to_excel_xlwings(self): + fpath = self.tmp_path('test_to_excel_xlwings.xlsx') + + # 1D + a1 = ndtest(3) + + # live book/Sheet1/A1 + # a1.to_excel() + + # fpath/Sheet1/A1 (create a new file if does not exist) + if os.path.isfile(fpath): + os.remove(fpath) + a1.to_excel(fpath, engine='xlwings') + # we use xlrd to read back instead of xlwings even if that should work, to make the test faster + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # fpath/Sheet1/A1(transposed) + a1.to_excel(fpath, transpose=True, engine='xlwings') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # fpath/Sheet1/A1 + # stacked data (one column containing all the values and another column listing the context of the value) + a1.to_excel(fpath, wide=False, engine='xlwings') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a1) + + # 2D + a2 = ndtest((2, 3)) + + # fpath/Sheet1/A1 + a2.to_excel(fpath, overwrite_file=True, engine='xlwings') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a2) + + # fpath/Sheet1/A10 + a2.to_excel(fpath, 'Sheet1', 'A10', engine='xlwings') + res = read_excel(fpath, 'Sheet1', engine='xlrd', skiprows=9) + assert_array_equal(res, a2) + + # fpath/other/A1 + a2.to_excel(fpath, 'other', engine='xlwings') + res = read_excel(fpath, 'other', engine='xlrd') + assert_array_equal(res, a2) + + # transpose + a2.to_excel(fpath, 'transpose', transpose=True, engine='xlwings') + res = read_excel(fpath, 'transpose', engine='xlrd') + assert_array_equal(res, a2.T) + + # 3D + a3 = ndtest((2, 3, 4)) + + # fpath/Sheet1/A1 + a3.to_excel(fpath, overwrite_file=True, engine='xlwings') + res = read_excel(fpath, engine='xlrd') + assert_array_equal(res, a3) + + # fpath/Sheet1/A20 + a3.to_excel(fpath, 'Sheet1', 'A20', engine='xlwings') + res = read_excel(fpath, 'Sheet1', engine='xlrd', skiprows=19) + assert_array_equal(res, a3) + + # fpath/other/A1 + a3.to_excel(fpath, 'other', engine='xlwings') + res = read_excel(fpath, 'other', engine='xlrd') + assert_array_equal(res, a3) + + # passing group as sheet_name + a3 = ndtest((4, 3, 4)) + os.remove(fpath) + # single element group + for label in a3.a: + a3[label].to_excel(fpath, label, engine='xlwings') + # unnamed group + group = a3.c['c0,c2'] + a3[group].to_excel(fpath, group, engine='xlwings') + # unnamed group + slice + group = a3.c['c0::2'] + a3[group].to_excel(fpath, group, engine='xlwings') + # named group + group = a3.c['c0,c2'] >> 'even' + a3[group].to_excel(fpath, group, engine='xlwings') + # group with name containing special characters (replaced by _) + group = a3.c['c0,c2'] >> ':name?with*special/\[char]' + a3[group].to_excel(fpath, group, engine='xlwings') + # checks sheet names + sheet_names = sorted(open_excel(fpath).sheet_names()) + assert sheet_names == sorted(['a0', 'a1', 'a2', 'a3', 'c0,c2', 'c0__2', 'even', + '_name_with_special___char_']) + + @pytest.mark.skipif(xw is None, reason="xlwings is not available") + def test_open_excel(self): + # 1) Create new file + # ================== + fpath = inputpath('should_not_extist.xlsx') + # overwrite_file must be set to True to create a new file + with pytest.raises(ValueError): + open_excel(fpath) + + # 2) with headers + # =============== + with open_excel(visible=False) as wb: + # 1D + a1 = ndtest(3) + + # Sheet1/A1 + wb['Sheet1'] = a1.dump() + res = wb['Sheet1'].load() + assert_array_equal(res, a1) + + wb[0] = a1.dump() + res = wb[0].load() + assert_array_equal(res, a1) + + # Sheet1/A1(transposed) + # TODO: implement .options on Sheet so that one can write: + # wb[0].options(transpose=True).value = a1.dump() + wb[0]['A1'].options(transpose=True).value = a1.dump() + # TODO: implement .options on Range so that you can write: + # res = wb[0]['A1:B4'].options(transpose=True).load() + # res = from_lists(wb[0]['A1:B4'].options(transpose=True).value) + # assert_array_equal(res, a1) + + # 2D + a2 = ndtest((2, 3)) + + # Sheet1/A1 + wb[0] = a2.dump() + res = wb[0].load() + assert_array_equal(res, a2) + + # Sheet1/A10 + wb[0]['A10'] = a2.dump() + res = wb[0]['A10:D12'].load() + assert_array_equal(res, a2) + + # other/A1 + wb['other'] = a2.dump() + res = wb['other'].load() + assert_array_equal(res, a2) + + # new/A10 + # we need to create the sheet first + wb['new'] = '' + wb['new']['A10'] = a2.dump() + res = wb['new']['A10:D12'].load() + assert_array_equal(res, a2) + + # new2/A10 + # cannot store the return value of "add" because that's a raw xlwings Sheet + wb.sheets.add('new2') + wb['new2']['A10'] = a2.dump() + res = wb['new2']['A10:D12'].load() + assert_array_equal(res, a2) + + # 3D + a3 = ndtest((2, 3, 4)) + + # 3D/A1 + wb['3D'] = a3.dump() + res = wb['3D'].load() + assert_array_equal(res, a3) + + # 3D/A20 + wb['3D']['A20'] = a3.dump() + res = wb['3D']['A20:F26'].load() + assert_array_equal(res, a3) + + # 3D/A20 without name for columns + wb['3D']['A20'] = a3.dump() + # assume we have no name for the columns axis (ie change b\c to b) + wb['3D']['B20'] = 'b' + res = wb['3D']['A20:F26'].load(nb_index=2) + assert_array_equal(res, a3.data) + # the two first axes should be the same + self.assertEqual(res.axes[:2], a3.axes[:2]) + # the third axis should have the same labels (but not the same name obviously) + assert_array_equal(res.axes[2].labels, a3.axes[2].labels) + + with open_excel(inputpath('test.xlsx')) as wb: + expected = ndtest("a=a0..a2; b0..b2") + res = wb['2d_classic'].load() + assert_array_equal(res, expected) + + # 3) without headers + # ================== + with open_excel(visible=False) as wb: + # 1D + a1 = ndtest(3) + + # Sheet1/A1 + wb['Sheet1'] = a1 + res = wb['Sheet1'].load(header=False) + assert_array_equal(res, a1.data) + + wb[0] = a1 + res = wb[0].load(header=False) + assert_array_equal(res, a1.data) + + # Sheet1/A1(transposed) + # FIXME: we need to .dump(header=False) explicitly because otherwise we go via LArrayConverter which + # includes labels. for consistency's sake we should either change LArrayConverter to not include + # labels, or change wb[0] = a1 to include them (and use wb[0] = a1.data to avoid them?) but that + # would be heavily backward incompatible and how would I load them back? + # wb[0]['A1'].options(transpose=True).value = a1 + wb[0]['A1'].options(transpose=True).value = a1.dump(header=False) + res = wb[0]['A1:A3'].load(header=False) + assert_array_equal(res, a1.data) + + # 2D + a2 = ndtest((2, 3)) + + # Sheet1/A1 + wb[0] = a2 + res = wb[0].load(header=False) + assert_array_equal(res, a2.data) + + # Sheet1/A10 + wb[0]['A10'] = a2 + res = wb[0]['A10:C11'].load(header=False) + assert_array_equal(res, a2.data) + + # other/A1 + wb['other'] = a2 + res = wb['other'].load(header=False) + assert_array_equal(res, a2.data) + + # new/A10 + # we need to create the sheet first + wb['new'] = '' + wb['new']['A10'] = a2 + res = wb['new']['A10:C11'].load(header=False) + assert_array_equal(res, a2.data) + + # 3D + a3 = ndtest((2, 3, 4)) + + # 3D/A1 + wb['3D'] = a3 + res = wb['3D'].load(header=False) + assert_array_equal(res, a3.data.reshape((6, 4))) + + # 3D/A20 + wb['3D']['A20'] = a3 + res = wb['3D']['A20:D25'].load(header=False) + assert_array_equal(res, a3.data.reshape((6, 4))) + + # 4) Blank cells + # ======================== + # Excel sheet with blank cells on right/bottom border of the array to read + fpath = inputpath('test_blank_cells.xlsx') + with open_excel(fpath) as wb: + good = wb['good'].load() + bad1 = wb['blanksafter_morerowsthancols'].load() + bad2 = wb['blanksafter_morecolsthanrows'].load() + # with additional empty column in the middle of the array to read + good2 = wb['middleblankcol']['A1:E3'].load() + bad3 = wb['middleblankcol'].load() + bad4 = wb['16384col'].load() + assert_array_equal(bad1, good) + assert_array_equal(bad2, good) + assert_array_equal(bad3, good2) + assert_array_equal(bad4, good2) + + # 5) crash test + # ============= + arr = ndtest((2, 2)) + fpath = self.tmp_path('temporary_test_file.xlsx') + # create and save a test file + with open_excel(fpath, overwrite_file=True) as wb: + wb['arr'] = arr.dump() + wb.save() + # raise exception when the file is open + try: + with open_excel(fpath, overwrite_file=True) as wb: + raise ValueError("") + except ValueError: + pass + # check if file is still available + with open_excel(fpath) as wb: + assert wb.sheet_names() == ['arr'] + assert_array_equal(wb['arr'].load(), arr) + # remove file + if os.path.exists(fpath): + os.remove(fpath) + + def test_ufuncs(self): + la = self.small + raw = self.small_data + + # simple one-argument ufunc + assert_array_equal(exp(la), np.exp(raw)) + + # with out= + la_out = zeros(la.axes) + raw_out = np.zeros(raw.shape) + + la_out2 = exp(la, la_out) + raw_out2 = np.exp(raw, raw_out) + + # FIXME: this is not the case currently + # self.assertIs(la_out2, la_out) + assert_array_equal(la_out2, la_out) + self.assertIs(raw_out2, raw_out) + + assert_array_equal(la_out, raw_out) + + # with out= and broadcasting + # we need to put the 'a' axis first because raw numpy only supports that + la_out = zeros([Axis([0, 1, 2], 'a')] + list(la.axes)) + raw_out = np.zeros((3,) + raw.shape) + + la_out2 = exp(la, la_out) + raw_out2 = np.exp(raw, raw_out) + + # self.assertIs(la_out2, la_out) + # XXX: why is la_out2 transposed? + assert_array_equal(la_out2.transpose(X.a), la_out) + self.assertIs(raw_out2, raw_out) + + assert_array_equal(la_out, raw_out) + + sex, lipro = la.axes + + low = la.sum(sex) // 4 + 3 + raw_low = raw.sum(0) // 4 + 3 + high = la.sum(sex) // 4 + 13 + raw_high = raw.sum(0) // 4 + 13 + + # LA + scalars + assert_array_equal(la.clip(0, 10), raw.clip(0, 10)) + assert_array_equal(clip(la, 0, 10), np.clip(raw, 0, 10)) + + # LA + LA (no broadcasting) + assert_array_equal(clip(la, 21 - la, 9 + la // 2), + np.clip(raw, 21 - raw, 9 + raw // 2)) + + # LA + LA (with broadcasting) + assert_array_equal(clip(la, low, high), + np.clip(raw, raw_low, raw_high)) + + # where (no broadcasting) + assert_array_equal(where(la < 5, -5, la), + np.where(raw < 5, -5, raw)) + + # where (transposed no broadcasting) + assert_array_equal(where(la < 5, -5, la.T), + np.where(raw < 5, -5, raw)) + + # where (with broadcasting) + result = where(la['P01'] < 5, -5, la) + self.assertEqual(result.axes.names, ['sex', 'lipro']) + assert_array_equal(result, np.where(raw[:,[0]] < 5, -5, raw)) + + # round + small_float = self.small + 0.6 + rounded = round(small_float) + assert_array_equal(rounded, np.round(self.small_data + 0.6)) + + def test_diag(self): + # 2D -> 1D + a = ndtest((3, 3)) + d = diag(a) + self.assertEqual(d.ndim, 1) + self.assertEqual(d.i[0], a.i[0, 0]) + self.assertEqual(d.i[1], a.i[1, 1]) + self.assertEqual(d.i[2], a.i[2, 2]) + + # 1D -> 2D + a2 = diag(d) + self.assertEqual(a2.ndim, 2) + self.assertEqual(a2.i[0, 0], a.i[0, 0]) + self.assertEqual(a2.i[1, 1], a.i[1, 1]) + self.assertEqual(a2.i[2, 2], a.i[2, 2]) + + # 3D -> 2D + a = ndtest((3, 3, 3)) + d = diag(a) + self.assertEqual(d.ndim, 2) + self.assertEqual(d.i[0, 0], a.i[0, 0, 0]) + self.assertEqual(d.i[1, 1], a.i[1, 1, 1]) + self.assertEqual(d.i[2, 2], a.i[2, 2, 2]) + + # 3D -> 1D + d = diag(a, axes=(0, 1, 2)) + self.assertEqual(d.ndim, 1) + self.assertEqual(d.i[0], a.i[0, 0, 0]) + self.assertEqual(d.i[1], a.i[1, 1, 1]) + self.assertEqual(d.i[2], a.i[2, 2, 2]) + + # 1D (anon) -> 2D + d_anon = d.rename(0, None).drop_labels() + a2 = diag(d_anon) + self.assertEqual(a2.ndim, 2) + + # 1D (anon) -> 3D + a3 = diag(d_anon, ndim=3) + self.assertEqual(a2.ndim, 2) + self.assertEqual(a3.i[0, 0, 0], a.i[0, 0, 0]) + self.assertEqual(a3.i[1, 1, 1], a.i[1, 1, 1]) + self.assertEqual(a3.i[2, 2, 2], a.i[2, 2, 2]) + + # using Axis object + sex = Axis('sex=M,F') + a = eye(sex) + d = diag(a) + self.assertEqual(d.ndim, 1) + self.assertEqual(d.axes.names, ['sex_sex']) + assert_array_equal(d.axes.labels, [['M_M', 'F_F']]) + self.assertEqual(d.i[0], 1.0) + self.assertEqual(d.i[1], 1.0) + + @pytest.mark.skipif(sys.version_info < (3, 5), reason="@ unavailable (Python < 3.5)") + def test_matmul(self): + # 2D / anonymous axes + a1 = ndtest([Axis(3), Axis(3)]) + a2 = eye(3, 3) * 2 + # cannot use @ in the tests because that is an invalid syntax in Python 2 + # LArray value + assert_array_equal(a1.__matmul__(a2), ndtest([Axis(3), Axis(3)]) * 2) + + # ndarray value + assert_array_equal(a1.__matmul__(a2.data), ndtest([Axis(3), Axis(3)]) * 2) + + # non anonymous axes (N <= 2) + arr1d = ndtest(3) + arr2d = ndtest((3, 3)) + + # 1D @ 1D + self.assertEqual(arr1d.__matmul__(arr1d), 5) + + # 1D @ 2D + assert_array_equal(arr1d.__matmul__(arr2d), + LArray([15, 18, 21], 'b=b0..b2')) + + # 2D @ 1D + assert_array_equal(arr2d.__matmul__(arr1d), + LArray([5, 14, 23], 'a=a0..a2')) + + # 2D(a,b) @ 2D(a,b) -> 2D(a,b) + res = from_lists([['a\\b', 'b0', 'b1', 'b2'], + ['a0', 15, 18, 21], + ['a1', 42, 54, 66], + ['a2', 69, 90, 111]]) + assert_array_equal(arr2d.__matmul__(arr2d), res) + + # 2D(a,b) @ 2D(b,a) -> 2D(a,a) + res = from_lists([['a\\a', 'a0', 'a1', 'a2'], + ['a0', 5, 14, 23], + ['a1', 14, 50, 86], + ['a2', 23, 86, 149]]) + assert_array_equal(arr2d.__matmul__(arr2d.T), res) + + # ndarray value + assert_array_equal(arr1d.__matmul__(arr2d.data), + LArray([15, 18, 21])) + assert_array_equal(arr2d.data.__matmul__(arr2d.T.data), + res.data) + + # different axes + a1 = ndtest('a=a0..a1;b=b0..b2') + a2 = ndtest('b=b0..b2;c=c0..c3') + res = from_lists([['a\c', 'c0', 'c1', 'c2', 'c3'], + ['a0', 20, 23, 26, 29], + ['a1', 56, 68, 80, 92]]) + assert_array_equal(a1.__matmul__(a2), res) + + # non anonymous axes (N >= 2) + arr2d = ndtest((2, 2)) + arr3d = ndtest((2, 2, 2)) + arr4d = ndtest((2, 2, 2, 2)) + a, b, c, d = arr4d.axes + e = Axis('e=e0,e1') + f = Axis('f=f0,f1') + + # 4D(a, b, c, d) @ 3D(e, d, f) -> 5D(a, b, e, c, f) + arr3d = arr3d.set_axes([e, d, f]) + res = from_lists([['a', 'b', 'e', 'c\\f', 'f0', 'f1'], + ['a0', 'b0', 'e0', 'c0', 2, 3], + ['a0', 'b0', 'e0', 'c1', 6, 11], + ['a0', 'b0', 'e1', 'c0', 6, 7], + ['a0', 'b0', 'e1', 'c1', 26, 31], + ['a0', 'b1', 'e0', 'c0', 10, 19], + ['a0', 'b1', 'e0', 'c1', 14, 27], + ['a0', 'b1', 'e1', 'c0', 46, 55], + ['a0', 'b1', 'e1', 'c1', 66, 79], + ['a1', 'b0', 'e0', 'c0', 18, 35], + ['a1', 'b0', 'e0', 'c1', 22, 43], + ['a1', 'b0', 'e1', 'c0', 86, 103], + ['a1', 'b0', 'e1', 'c1', 106, 127], + ['a1', 'b1', 'e0', 'c0', 26, 51], + ['a1', 'b1', 'e0', 'c1', 30, 59], + ['a1', 'b1', 'e1', 'c0', 126, 151], + ['a1', 'b1', 'e1', 'c1', 146, 175]]) + assert_array_equal(arr4d.__matmul__(arr3d), res) + + # 3D(e, d, f) @ 4D(a, b, c, d) -> 5D(e, a, b, d, d) + res = from_lists([['e', 'a', 'b', 'd\\d', 'd0', 'd1'], + ['e0', 'a0', 'b0', 'd0', 2, 3], + ['e0', 'a0', 'b0', 'd1', 6, 11], + ['e0', 'a0', 'b1', 'd0', 6, 7], + ['e0', 'a0', 'b1', 'd1', 26, 31], + ['e0', 'a1', 'b0', 'd0', 10, 11], + ['e0', 'a1', 'b0', 'd1', 46, 51], + ['e0', 'a1', 'b1', 'd0', 14, 15], + ['e0', 'a1', 'b1', 'd1', 66, 71], + ['e1', 'a0', 'b0', 'd0', 10, 19], + ['e1', 'a0', 'b0', 'd1', 14, 27], + ['e1', 'a0', 'b1', 'd0', 46, 55], + ['e1', 'a0', 'b1', 'd1', 66, 79], + ['e1', 'a1', 'b0', 'd0', 82, 91], + ['e1', 'a1', 'b0', 'd1', 118, 131], + ['e1', 'a1', 'b1', 'd0', 118, 127], + ['e1', 'a1', 'b1', 'd1', 170, 183]]) + assert_array_equal(arr3d.__matmul__(arr4d), res) + + # 4D(a, b, c, d) @ 3D(b, d, f) -> 4D(a, b, c, f) + arr3d = arr3d.set_axes([b, d, f]) + res = from_lists([['a', 'b', 'c\\f', 'f0', 'f1'], + ['a0', 'b0', 'c0', 2, 3], + ['a0', 'b0', 'c1', 6, 11], + ['a0', 'b1', 'c0', 46, 55], + ['a0', 'b1', 'c1', 66, 79], + ['a1', 'b0', 'c0', 18, 35], + ['a1', 'b0', 'c1', 22, 43], + ['a1', 'b1', 'c0', 126, 151], + ['a1', 'b1', 'c1', 146, 175]]) + assert_array_equal(arr4d.__matmul__(arr3d), res) + + # 3D(b, d, f) @ 4D(a, b, c, d) -> 4D(b, a, d, d) + res = from_lists([['b', 'a', 'd\\d', 'd0', 'd1'], + ['b0', 'a0', 'd0', 2, 3], + ['b0', 'a0', 'd1', 6, 11], + ['b0', 'a1', 'd0', 10, 11], + ['b0', 'a1', 'd1', 46, 51], + ['b1', 'a0', 'd0', 46, 55], + ['b1', 'a0', 'd1', 66, 79], + ['b1', 'a1', 'd0', 118, 127], + ['b1', 'a1', 'd1', 170, 183]]) + assert_array_equal(arr3d.__matmul__(arr4d), res) + + # 4D(a, b, c, d) @ 2D(d, f) -> 5D(a, b, c, f) + arr2d = arr2d.set_axes([d, f]) + res = from_lists([['a', 'b', 'c\\f', 'f0', 'f1'], + ['a0', 'b0', 'c0', 2, 3], + ['a0', 'b0', 'c1', 6, 11], + ['a0', 'b1', 'c0', 10, 19], + ['a0', 'b1', 'c1', 14, 27], + ['a1', 'b0', 'c0', 18, 35], + ['a1', 'b0', 'c1', 22, 43], + ['a1', 'b1', 'c0', 26, 51], + ['a1', 'b1', 'c1', 30, 59]]) + assert_array_equal(arr4d.__matmul__(arr2d), res) + + # 2D(d, f) @ 4D(a, b, c, d) -> 5D(a, b, d, d) + res = from_lists([['a', 'b', 'd\\d', 'd0', 'd1'], + ['a0', 'b0', 'd0', 2, 3], + ['a0', 'b0', 'd1', 6, 11], + ['a0', 'b1', 'd0', 6, 7], + ['a0', 'b1', 'd1', 26, 31], + ['a1', 'b0', 'd0', 10, 11], + ['a1', 'b0', 'd1', 46, 51], + ['a1', 'b1', 'd0', 14, 15], + ['a1', 'b1', 'd1', 66, 71]]) + assert_array_equal(arr2d.__matmul__(arr4d), res) + + @pytest.mark.skipif(sys.version_info < (3, 5), reason="@ unavailable (Python < 3.5)") + def test_rmatmul(self): + a1 = eye(3) * 2 + a2 = ndtest([Axis(3), Axis(3)]) + + # equivalent to a1.data @ a2 + res = a2.__rmatmul__(a1.data) + self.assertIsInstance(res, LArray) + assert_array_equal(res, ndtest([Axis(3), Axis(3)]) * 2) + + def test_broadcast_with(self): + a1 = ndtest((3, 2)) + a2 = ndtest(3) + b = a2.broadcast_with(a1) + self.assertEqual(b.ndim, a1.ndim) + self.assertEqual(b.shape, (3, 1)) + assert_array_equal(b.i[:, 0], a2) + + # anonymous axes + a1 = ndtest([Axis(3), Axis(2)]) + a2 = ndtest(Axis(3)) + b = a2.broadcast_with(a1) + self.assertEqual(b.ndim, a1.ndim) + self.assertEqual(b.shape, (3, 1)) + assert_array_equal(b.i[:, 0], a2) + + a1 = ndtest([Axis(1), Axis(3)]) + a2 = ndtest([Axis(3), Axis(1)]) + b = a2.broadcast_with(a1) + self.assertEqual(b.ndim, 2) + # common axes are reordered according to target (a1 in this case) + self.assertEqual(b.shape, (1, 3)) + assert_larray_equiv(b, a2) + + a1 = ndtest([Axis(2), Axis(3)]) + a2 = ndtest([Axis(3), Axis(2)]) + b = a2.broadcast_with(a1) + self.assertEqual(b.ndim, 2) + self.assertEqual(b.shape, (2, 3)) + assert_larray_equiv(b, a2) + + def test_plot(self): + pass + # small_h = small['M'] + #small_h.plot(kind='bar') + #small_h.plot() + #small_h.hist() + + #large_data = np.random.randn(1000) + #tick_v = np.random.randint(ord('a'), ord('z'), size=1000) + #ticks = [chr(c) for c in tick_v] + #large_axis = Axis('large', ticks) + #large = LArray(large_data, axes=[large_axis]) + #large.plot() + #large.hist() + + def test_combine_axes(self): + # combine N axes into 1 + # ===================== + arr = ndtest((2, 3, 4, 5)) + res = arr.combine_axes((X.a, X.b)) + self.assertEqual(res.axes.names, ['a_b', 'c', 'd']) + self.assertEqual(res.size, arr.size) + self.assertEqual(res.shape, (2 * 3, 4, 5)) + assert_array_equal(res.axes.a_b.labels[:2], ['a0_b0', 'a0_b1']) + assert_array_equal(res['a1_b0'], arr['a1', 'b0']) + + res = arr.combine_axes((X.a, X.c)) + self.assertEqual(res.axes.names, ['a_c', 'b', 'd']) + self.assertEqual(res.size, arr.size) + self.assertEqual(res.shape, (2 * 4, 3, 5)) + assert_array_equal(res.axes.a_c.labels[:2], ['a0_c0', 'a0_c1']) + assert_array_equal(res['a1_c0'], arr['a1', 'c0']) + + res = arr.combine_axes((X.b, X.d)) + self.assertEqual(res.axes.names, ['a', 'b_d', 'c']) + self.assertEqual(res.size, arr.size) + self.assertEqual(res.shape, (2, 3 * 5, 4)) + assert_array_equal(res.axes.b_d.labels[:2], ['b0_d0', 'b0_d1']) + assert_array_equal(res['b1_d0'], arr['b1', 'd0']) + + # combine M axes into N + # ===================== + arr = ndtest((2, 3, 4, 4, 3, 2)) + + # using a list of tuples + res = arr.combine_axes([('a', 'c'), ('b', 'f'), ('d', 'e')]) + assert res.axes.names == ['a_c', 'b_f', 'd_e'] + assert res.size == arr.size + assert res.shape == (2 * 4, 3 * 2, 4 * 3) + assert list(res.axes.a_c.labels[:2]) == ['a0_c0', 'a0_c1'] + assert list(res.axes.b_f.labels[:2]) == ['b0_f0', 'b0_f1'] + assert list(res.axes.d_e.labels[:2]) == ['d0_e0', 'd0_e1'] + assert res['a0_c2', 'b1_f1', 'd3_e2'] == arr['a0', 'b1', 'c2', 'd3', 'e2', 'f1'] + + res = arr.combine_axes([('a', 'c'), ('b', 'e', 'f')]) + assert res.axes.names == ['a_c', 'b_e_f', 'd'] + assert res.size == arr.size + assert res.shape == (2 * 4, 3 * 3 * 2, 4) + assert list(res.axes.b_e_f.labels[:4]) == ['b0_e0_f0', 'b0_e0_f1', 'b0_e1_f0', 'b0_e1_f1'] + assert_array_equal(res['a0_c2', 'b1_e2_f1'], arr['a0', 'b1', 'c2', 'e2', 'f1']) + + # using a dict (-> user defined axes names) + res = arr.combine_axes({('a', 'c'): 'AC', ('b', 'f'): 'BF', ('d', 'e'): 'DE'}) + assert res.axes.names == ['AC', 'BF', 'DE'] + assert res.size == arr.size + assert res.shape == (2 * 4, 3 * 2, 4 * 3) + + res = arr.combine_axes({('a', 'c'): 'AC', ('b', 'e', 'f'): 'BEF'}) + assert res.axes.names == ['AC', 'BEF', 'd'] + assert res.size == arr.size + assert res.shape == (2 * 4, 3 * 3 * 2, 4) + + def test_split_axes(self): + # split one axis + # ============== + + # default sep + arr = ndtest((2, 3, 4, 5)) + combined = arr.combine_axes(('b', 'd')) + self.assertEqual(combined.axes.names, ['a', 'b_d', 'c']) + res = combined.split_axes('b_d') + self.assertEqual(res.axes.names, ['a', 'b', 'd', 'c']) + self.assertEqual(res.shape, (2, 3, 5, 4)) + assert_array_equal(res.transpose('a', 'b', 'c', 'd'), arr) + + # regex + res = combined.split_axes('b_d', names=['b', 'd'], regex='(\w+)_(\w+)') + self.assertEqual(res.axes.names, ['a', 'b', 'd', 'c']) + self.assertEqual(res.shape, (2, 3, 5, 4)) + assert_array_equal(res.transpose('a', 'b', 'c', 'd'), arr) + + # custom sep + combined = ndtest('a|b=a0|b0,a0|b1') + res = combined.split_axes(sep='|') + assert_array_equal(res, ndtest('a=a0;b=b0,b1')) + + # split several axes at once + # ========================== + arr = ndtest('a_b=a0_b0..a1_b2; c=c0..c3; d=d0..d3; e_f=e0_f0..e2_f1') + + # using a list of tuples + res = arr.split_axes(['a_b', 'e_f']) + assert res.axes.names == ['a', 'b', 'c', 'd', 'e', 'f'] + assert res.size == arr.size + assert res.shape == (2, 3, 4, 4, 3, 2) + assert list(res.axes.a.labels) == ['a0', 'a1'] + assert list(res.axes.b.labels) == ['b0', 'b1', 'b2'] + assert list(res.axes.e.labels) == ['e0', 'e1', 'e2'] + assert list(res.axes.f.labels) == ['f0', 'f1'] + assert res['a0', 'b1', 'c2', 'd3', 'e2', 'f1'] == arr['a0_b1', 'c2', 'd3', 'e2_f1'] + + # default to all axes with name containing the delimiter _ + assert_array_equal(arr.split_axes(), res) + + # using a dict (-> user defined axes names) + res = arr.split_axes({'a_b': ('A', 'B'), 'e_f': ('E', 'F')}) + assert res.axes.names == ['A', 'B', 'c', 'd', 'E', 'F'] + assert res.size == arr.size + assert res.shape == (2, 3, 4, 4, 3, 2) + + # split an axis in more than 2 axes + arr = ndtest('a_b_c=a0_b0_c0..a1_b2_c3; d=d0..d3; e_f=e0_f0..e2_f1') + res = arr.split_axes(['a_b_c', 'e_f']) + assert res.axes.names == ['a', 'b', 'c', 'd', 'e', 'f'] + assert res.size == arr.size + assert res.shape == (2, 3, 4, 4, 3, 2) + assert list(res.axes.a.labels) == ['a0', 'a1'] + assert list(res.axes.b.labels) == ['b0', 'b1', 'b2'] + assert list(res.axes.e.labels) == ['e0', 'e1', 'e2'] + assert list(res.axes.f.labels) == ['f0', 'f1'] + assert res['a0', 'b1', 'c2', 'd3', 'e2', 'f1'] == arr['a0_b1_c2', 'd3', 'e2_f1'] + + # split an axis in more than 2 axes + passing a dict + res = arr.split_axes({'a_b_c': ('A', 'B', 'C'), 'e_f': ('E', 'F')}) + assert res.axes.names == ['A', 'B', 'C', 'd', 'E', 'F'] + assert res.size == arr.size + assert res.shape == (2, 3, 4, 4, 3, 2) + + # using regex + arr = ndtest('ab=a0b0..a1b2; c=c0..c3; d=d0..d3; ef=e0f0..e2f1') + res = arr.split_axes({'ab': ('a', 'b'), 'ef': ('e', 'f')}, regex='(\w{2})(\w{2})') + assert res.axes.names == ['a', 'b', 'c', 'd', 'e', 'f'] + assert res.size == arr.size + assert res.shape == (2, 3, 4, 4, 3, 2) + assert list(res.axes.a.labels) == ['a0', 'a1'] + assert list(res.axes.b.labels) == ['b0', 'b1', 'b2'] + assert list(res.axes.e.labels) == ['e0', 'e1', 'e2'] + assert list(res.axes.f.labels) == ['f0', 'f1'] + assert res['a0', 'b1', 'c2', 'd3', 'e2', 'f1'] == arr['a0b1', 'c2', 'd3', 'e2f1'] + + # labels with object dtype + arr = ndtest((2, 2, 2)).combine_axes(('a', 'b')) + arr = arr.set_axes([Axis(a.labels.astype(object), a.name) for a in arr.axes]) + + res = arr.split_axes() + expected_kind = 'U' if sys.version_info[0] >= 3 else 'S' + assert res.a.labels.dtype.kind == expected_kind + assert res.b.labels.dtype.kind == expected_kind + assert res.c.labels.dtype.kind == 'O' + assert_array_equal(res, ndtest((2, 2, 2))) + + # not sorted by first part then second part (issue #364) + arr = ndtest((2, 3)) + combined = arr.combine_axes()['a0_b0, a1_b0, a0_b1, a1_b1, a0_b2, a1_b2'] + assert_array_equal(combined.split_axes('a_b'), arr) + + # another weirdly sorted test + combined = arr.combine_axes()['a0_b1, a0_b0, a0_b2, a1_b1, a1_b0, a1_b2'] + assert_array_equal(combined.split_axes('a_b'), arr['b1,b0,b2']) + + # combined does not contain all combinations of labels (issue #369) + combined_partial = combined[['a0_b0', 'a0_b1', 'a1_b1', 'a0_b2', 'a1_b2']] + expected = arr.astype(float) + expected['a1', 'b0'] = np.nan + assert_array_nan_equal(combined_partial.split_axes('a_b'), expected) + + # split labels are ambiguous (issue #485) + combined = ndtest('a_b=a0_b0..a1_b1;c_d=a0_b0..a1_b1') + expected = ndtest('a=a0,a1;b=b0,b1;c=a0,a1;d=b0,b1') + assert_array_equal(combined.split_axes(('a_b', 'c_d')), expected) + + def test_stack(self): + # simple + arr0 = ndtest(3) + arr1 = ndtest(3, start=-1) + a = arr0.axes[0] + b = Axis('b=b0,b1') + expected = LArray([[0, -1], + [1, 0], + [2, 1]], [a, b]) + res = stack((arr0, arr1), b) + assert_array_equal(res, expected) + + # simple with anonymous axis + arr0 = ndtest(Axis(3)) + arr1 = ndtest(Axis(3), start=-1) + a = arr0.axes[0] + b = Axis('b=b0,b1') + expected = LArray([[0, -1], + [1, 0], + [2, 1]], [a, b]) + res = stack((arr0, arr1), b) + assert_array_equal(res, expected) + + # nd + sex = Axis('sex=M,F') + arr1 = ones('nat=BE, FO') + # not using the same length as nat, otherwise numpy gets confused :( + arr2 = zeros('type=1..3') + nd = LArray([arr1, arr2], sex) + res = stack(nd, sex) + expected = from_string("""nat type\\sex M F + BE 1 1.0 0.0 + BE 2 1.0 0.0 + BE 3 1.0 0.0 + FO 1 1.0 0.0 + FO 2 1.0 0.0 + FO 3 1.0 0.0""") + assert_array_equal(res, expected) + + def test_0darray_convert(self): + int_arr = LArray(1) + assert int(int_arr) == 1 + assert float(int_arr) == 1.0 + assert int_arr.__index__() == 1 + + float_arr = LArray(1.0) + assert int(float_arr) == 1 + assert float(float_arr) == 1.0 + with pytest.raises(TypeError) as e_info: + float_arr.__index__() + + msg = e_info.value.args[0] + expected_np11 = "only integer arrays with one element can be converted to an index" + expected_np12 = "only integer scalar arrays can be converted to a scalar index" + assert msg in {expected_np11, expected_np12} + + def test_deprecated_methods(self): + with pytest.warns(FutureWarning) as caught_warnings: + ndtest((2, 2)).with_axes('a', 'd=d0,d1') + assert len(caught_warnings) == 1 + assert caught_warnings[0].message.args[0] == "with_axes() is deprecated. Use set_axes() instead." + assert caught_warnings[0].filename == __file__ + + with pytest.warns(FutureWarning) as caught_warnings: + ndtest((2, 2)).combine_axes().split_axis() + assert len(caught_warnings) == 1 + assert caught_warnings[0].message.args[0] == "split_axis() is deprecated. Use split_axes() instead." + assert caught_warnings[0].filename == __file__ + + def test_nan_equal(self): + a = ndtest((2, 3, 4)) + ao = a.astype(object) + assert_array_equal(nan_equal(ao, ao['c0']), a == a['c0']) + + +if __name__ == "__main__": + # import doctest + # import unittest + # from larray import core + # doctest.testmod(core) + # unittest.main() + pytest.main() diff --git a/larray/tests/test_axis.py b/larray/tests/test_axis.py new file mode 100644 index 000000000..da7aefb6c --- /dev/null +++ b/larray/tests/test_axis.py @@ -0,0 +1,881 @@ +from __future__ import absolute_import, division, print_function + +from unittest import TestCase + +import pytest +import numpy as np + +from larray.tests.common import assert_array_equal +from larray import Axis, AxisCollection, LGroup, IGroup + + +class TestAxis(TestCase): + def setUp(self): + pass + + def tearDown(self): + pass + + def test_init(self): + sex_tuple = ('M', 'F') + sex_list = ['M', 'F'] + sex_array = np.array(sex_list) + + # wildcard axis + axis = Axis(10, 'axis') + assert len(axis) == 10 + assert list(axis.labels) == list(range(10)) + # tuple of strings + assert_array_equal(Axis(sex_tuple, 'sex').labels, sex_array) + # list of strings + assert_array_equal(Axis(sex_list, 'sex').labels, sex_array) + # array of strings + assert_array_equal(Axis(sex_array, 'sex').labels, sex_array) + # single string + assert_array_equal(Axis('sex=M,F').labels, sex_array) + # list of ints + assert_array_equal(Axis(range(116), 'age').labels, np.arange(116)) + # range-string + axis = Axis('0..115', 'age') + assert_array_equal(axis.labels, np.arange(116)) + # int-like labels with 0 padding + assert_array_equal(Axis('01..12', 'zero_padding').labels, [str(i).zfill(2) for i in range(1, 13)]) + assert_array_equal(Axis('01,02,03,10,11,12', 'zero_padding').labels, ['01', '02', '03', '10', '11', '12']) + + # another axis group + group = axis[:10] + group_axis = Axis(group) + assert_array_equal(group_axis.labels, np.arange(11)) + assert_array_equal(group_axis.name, 'age') + # another axis as labels argument + other = Axis('other=0..10') + axis = Axis(other, 'age') + assert_array_equal(axis.labels, other.labels) + assert_array_equal(axis.name, 'age') + + def test_equals(self): + self.assertTrue(Axis('sex=M,F').equals(Axis('sex=M,F'))) + self.assertTrue(Axis('sex=M,F').equals(Axis(['M', 'F'], 'sex'))) + self.assertFalse(Axis('sex=M,W').equals(Axis('sex=M,F'))) + self.assertFalse(Axis('sex1=M,F').equals(Axis('sex2=M,F'))) + self.assertFalse(Axis('sex1=M,W').equals(Axis('sex2=M,F'))) + + def test_getitem(self): + age = Axis('age=0..10') + # a tuple + a159 = age[1, 5, 9] + self.assertEqual(a159.key, [1, 5, 9]) + self.assertIs(a159.name, None) + self.assertIs(a159.axis, age) + + # a normal list + a159 = age[[1, 5, 9]] + self.assertEqual(a159.key, [1, 5, 9]) + self.assertIs(a159.name, None) + self.assertIs(a159.axis, age) + + # a string list + a159 = age['1,5,9'] + self.assertEqual(a159.key, [1, 5, 9]) + self.assertIs(a159.name, None) + self.assertIs(a159.axis, age) + + # a normal slice + a10to20 = age[5:9] + self.assertEqual(a10to20.key, slice(5, 9)) + self.assertIs(a10to20.axis, age) + + # a string slice + a10to20 = age['5:9'] + self.assertEqual(a10to20.key, slice(5, 9)) + self.assertIs(a10to20.axis, age) + + # with name + group = age[[1, 5, 9]] >> 'test' + self.assertEqual(group.key, [1, 5, 9]) + self.assertEqual(group.name, 'test') + self.assertIs(group.axis, age) + + # all + group = age[:] >> 'all' + self.assertEqual(group.key, slice(None)) + self.assertIs(group.axis, age) + + # an axis + age2 = Axis('age=0..5') + group = age[age2] + assert list(group.key) == list(age2.labels) + + def test_translate(self): + # an axis with labels having the object dtype + a = Axis(np.array(["a0", "a1"], dtype=object), 'a') + + self.assertEqual(a.index('a1'), 1) + self.assertEqual(a.index('a1 >> A1'), 1) + + def test_getitem_lgroup_keys(self): + def group_equal(g1, g2): + return (g1.key == g2.key and g1.name == g2.name and + g1.axis is g2.axis) + + age = Axis(range(100), 'age') + ages = [1, 5, 9] + + val_only = LGroup(ages) + self.assertTrue(group_equal(age[val_only], LGroup(ages, axis=age))) + self.assertTrue(group_equal(age[val_only] >> 'a_name', LGroup(ages, 'a_name', axis=age))) + + val_name = LGroup(ages, 'val_name') + self.assertTrue(group_equal(age[val_name], LGroup(ages, 'val_name', age))) + self.assertTrue(group_equal(age[val_name] >> 'a_name', LGroup(ages, 'a_name', age))) + + val_axis = LGroup(ages, axis=age) + self.assertTrue(group_equal(age[val_axis], LGroup(ages, axis=age))) + self.assertTrue(group_equal(age[val_axis] >> 'a_name', LGroup(ages, 'a_name', axis=age))) + + val_axis_name = LGroup(ages, 'val_axis_name', age) + self.assertTrue(group_equal(age[val_axis_name], LGroup(ages, 'val_axis_name', age))) + self.assertTrue(group_equal(age[val_axis_name] >> 'a_name', LGroup(ages, 'a_name', age))) + + def test_getitem_group_keys(self): + a = Axis('a=a0..a2') + alt_a = Axis('a=a1..a3') + + # a) key is a single LGroup + # ------------------------- + + # a.1) containing a scalar + key = a['a1'] + # use it on the same axis + g = a[key] + self.assertEqual(g.key, 'a1') + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[key] + self.assertEqual(g.key, 'a1') + self.assertIs(g.axis, alt_a) + + # a.2) containing a slice + key = a['a1':'a2'] + # use it on the same axis + g = a[key] + self.assertEqual(g.key, slice('a1', 'a2')) + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[key] + self.assertEqual(g.key, slice('a1', 'a2')) + self.assertIs(g.axis, alt_a) + + # a.3) containing a list + key = a[['a1', 'a2']] + # use it on the same axis + g = a[key] + self.assertEqual(g.key, ['a1', 'a2']) + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[key] + self.assertEqual(g.key, ['a1', 'a2']) + self.assertIs(g.axis, alt_a) + + # b) key is a single IGroup + # ------------------------- + + # b.1) containing a scalar + key = a.i[1] + # use it on the same axis + g = a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, 'a1') + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, 'a1') + self.assertIs(g.axis, alt_a) + + # b.2) containing a slice + key = a.i[1:3] + # use it on the same axis + g = a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, slice('a1', 'a2')) + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, slice('a1', 'a2')) + self.assertIs(g.axis, alt_a) + + # b.3) containing a list + key = a.i[[1, 2]] + # use it on the same axis + g = a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(list(g.key), ['a1', 'a2']) + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(list(g.key), ['a1', 'a2']) + self.assertIs(g.axis, alt_a) + + # c) key is a slice + # ----------------- + + # c.1) with LGroup bounds + lg_a1 = a['a1'] + lg_a2 = a['a2'] + # use it on the same axis + g = a[lg_a1:lg_a2] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, slice('a1', 'a2')) + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[lg_a1:lg_a2] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, slice('a1', 'a2')) + self.assertIs(g.axis, alt_a) + + # c.2) with IGroup bounds + pg_a1 = a.i[1] + pg_a2 = a.i[2] + # use it on the same axis + g = a[pg_a1:pg_a2] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, slice('a1', 'a2')) + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[pg_a1:pg_a2] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, slice('a1', 'a2')) + self.assertIs(g.axis, alt_a) + + # d) key is a list of scalar groups => create a single LGroup + # --------------------------------- + + # d.1) with LGroup + key = [a['a1'], a['a2']] + # use it on the same axis + g = a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, ['a1', 'a2']) + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, ['a1', 'a2']) + self.assertIs(g.axis, alt_a) + + # d.2) with IGroup + key = [a.i[1], a.i[2]] + # use it on the same axis + g = a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, ['a1', 'a2']) + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, ['a1', 'a2']) + self.assertIs(g.axis, alt_a) + + # e) key is a list of non-scalar groups => retarget multiple groups to axis + # ------------------------------------- + + # e.1) with LGroup + key = [a['a1', 'a2'], a['a2', 'a1']] + # use it on the same axis => nothing happens + g = a[key] + self.assertIsInstance(g, list) + self.assertIsInstance(g[0], LGroup) + self.assertIsInstance(g[1], LGroup) + self.assertEqual(g[0].key, ['a1', 'a2']) + self.assertEqual(g[1].key, ['a2', 'a1']) + self.assertIs(g[0].axis, a) + self.assertIs(g[1].axis, a) + # use it on a different axis => change axis + g = alt_a[key] + self.assertIsInstance(g, list) + self.assertIsInstance(g[0], LGroup) + self.assertIsInstance(g[1], LGroup) + self.assertEqual(g[0].key, ['a1', 'a2']) + self.assertEqual(g[1].key, ['a2', 'a1']) + self.assertIs(g[0].axis, alt_a) + self.assertIs(g[1].axis, alt_a) + + # e.2) with IGroup + key = (a.i[1, 2], a.i[2, 1]) + # use it on the same axis => change to LGroup + g = a[key] + self.assertIsInstance(g, tuple) + self.assertIsInstance(g[0], LGroup) + self.assertIsInstance(g[1], LGroup) + self.assertEqual(list(g[0].key), ['a1', 'a2']) + self.assertEqual(list(g[1].key), ['a2', 'a1']) + self.assertIs(g[0].axis, a) + self.assertIs(g[1].axis, a) + # use it on a different axis => retarget to axis + g = alt_a[key] + self.assertIsInstance(g, tuple) + self.assertIsInstance(g[0], LGroup) + self.assertIsInstance(g[1], LGroup) + self.assertEqual(list(g[0].key), ['a1', 'a2']) + self.assertEqual(list(g[1].key), ['a2', 'a1']) + self.assertIs(g[0].axis, alt_a) + self.assertIs(g[1].axis, alt_a) + + # f) key is a tuple of scalar groups => create a single LGroup + # ---------------------------------- + + # f.1) with LGroups + key = (a['a1'], a['a2']) + # use it on the same axis + g = a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, ['a1', 'a2']) + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, ['a1', 'a2']) + self.assertIs(g.axis, alt_a) + + # f.2) with IGroup + key = (a.i[1], a.i[2]) + # use it on the same axis + g = a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, ['a1', 'a2']) + self.assertIs(g.axis, a) + # use it on a different axis + g = alt_a[key] + self.assertIsInstance(g, LGroup) + self.assertEqual(g.key, ['a1', 'a2']) + self.assertIs(g.axis, alt_a) + + # g) key is a tuple of non-scalar groups => retarget multiple groups to axis + # -------------------------------------- + + # g.1) with LGroups + key = (a['a1', 'a2'], a['a2', 'a1']) + # use it on the same axis + g = a[key] + self.assertIsInstance(g, tuple) + self.assertIsInstance(g[0], LGroup) + self.assertIsInstance(g[1], LGroup) + self.assertEqual(g[0].key, ['a1', 'a2']) + self.assertEqual(g[1].key, ['a2', 'a1']) + self.assertIs(g[0].axis, a) + self.assertIs(g[1].axis, a) + # use it on a different axis + g = alt_a[key] + self.assertIsInstance(g, tuple) + self.assertIsInstance(g[0], LGroup) + self.assertIsInstance(g[1], LGroup) + self.assertEqual(g[0].key, ['a1', 'a2']) + self.assertEqual(g[1].key, ['a2', 'a1']) + self.assertIs(g[0].axis, alt_a) + self.assertIs(g[1].axis, alt_a) + + # g.2) with IGroup + key = (a.i[1, 2], a.i[2, 1]) + # use it on the same axis + g = a[key] + self.assertIsInstance(g, tuple) + self.assertIsInstance(g[0], LGroup) + self.assertIsInstance(g[1], LGroup) + self.assertEqual(list(g[0].key), ['a1', 'a2']) + self.assertEqual(list(g[1].key), ['a2', 'a1']) + self.assertIs(g[0].axis, a) + self.assertIs(g[1].axis, a) + # use it on a different axis + g = alt_a[key] + self.assertIsInstance(g, tuple) + self.assertIsInstance(g[0], LGroup) + self.assertIsInstance(g[1], LGroup) + self.assertEqual(list(g[0].key), ['a1', 'a2']) + self.assertEqual(list(g[1].key), ['a2', 'a1']) + self.assertIs(g[0].axis, alt_a) + self.assertIs(g[1].axis, alt_a) + + def test_init_from_group(self): + code = Axis('code=C01..C03') + code_group = code[:'C02'] + subset_axis = Axis(code_group, 'code_subset') + assert_array_equal(subset_axis.labels, ['C01', 'C02']) + + def test_matching(self): + sutcode = Axis(['A23', 'A2301', 'A25', 'A2501'], 'sutcode') + self.assertEqual(sutcode.matching('^...$'), LGroup(['A23', 'A25'])) + self.assertEqual(sutcode.startingwith('A23'), LGroup(['A23', 'A2301'])) + self.assertEqual(sutcode.endingwith('01'), LGroup(['A2301', 'A2501'])) + + def test_iter(self): + sex = Axis('sex=M,F') + self.assertEqual(list(sex), [IGroup(0, axis=sex), IGroup(1, axis=sex)]) + + def test_positional(self): + age = Axis('age=0..115') + + # these are NOT equivalent (not translated until used in an LArray + # self.assertEqual(age.i[:17], age[':17']) + key = age.i[:-1] + self.assertEqual(key.key, slice(None, -1)) + self.assertIs(key.axis, age) + + def test_contains(self): + # normal Axis + age = Axis('age=0..10') + + age2 = age[2] + age2bis = age[(2,)] + age2ter = age[[2]] + age2qua = '2,' + + age20 = LGroup('20') + age20bis = LGroup('20,') + age20ter = LGroup(['20']) + age20qua = '20,' + + # TODO: move assert to another test + # self.assertEqual(age2bis, age2ter) + + age247 = age['2,4,7'] + age247bis = age[['2', '4', '7']] + age359 = age[['3', '5', '9']] + age468 = age['4,6,8'] >> 'even' + + self.assertTrue(5 in age) + self.assertFalse('5' in age) + + self.assertTrue(age2 in age) + # only single ticks are "contained" in the axis, not "collections" + self.assertFalse(age2bis in age) + self.assertFalse(age2ter in age) + self.assertFalse(age2qua in age) + + self.assertFalse(age20 in age) + self.assertFalse(age20bis in age) + self.assertFalse(age20ter in age) + self.assertFalse(age20qua in age) + self.assertFalse(['3', '5', '9'] in age) + self.assertFalse('3,5,9' in age) + self.assertFalse('3:9' in age) + self.assertFalse(age247 in age) + self.assertFalse(age247bis in age) + self.assertFalse(age359 in age) + self.assertFalse(age468 in age) + + # aggregated Axis + # FIXME: _to_tick(age2) == 2, but then np.asarray([2, '2,4,7', ...]) returns np.array(['2', '2,4,7']) + # instead of returning an object array + agg = Axis((age2, age247, age359, age468, '2,6', ['3', '5', '7'], ('6', '7', '9')), "agg") + # fails because of above FIXME + # self.assertTrue(age2 in agg) + self.assertFalse(age2bis in agg) + self.assertFalse(age2ter in agg) + self.assertFalse(age2qua in age) + + self.assertTrue(age247 in agg) + self.assertTrue(age247bis in agg) + self.assertTrue('2,4,7' in agg) + self.assertTrue(['2', '4', '7'] in agg) + + self.assertTrue(age359 in agg) + self.assertTrue('3,5,9' in agg) + self.assertTrue(['3', '5', '9'] in agg) + + self.assertTrue(age468 in agg) + # no longer the case + # self.assertTrue('4,6,8' in agg) + # self.assertTrue(['4', '6', '8'] in agg) + self.assertTrue('even' in agg) + + self.assertTrue('2,6' in agg) + self.assertTrue(['2', '6'] in agg) + self.assertTrue(age['2,6'] in agg) + self.assertTrue(age[['2', '6']] in agg) + + self.assertTrue('3,5,7' in agg) + self.assertTrue(['3', '5', '7'] in agg) + self.assertTrue(age['3,5,7'] in agg) + self.assertTrue(age[['3', '5', '7']] in agg) + + self.assertTrue('6,7,9' in agg) + self.assertTrue(['6', '7', '9'] in agg) + self.assertTrue(age['6,7,9'] in agg) + self.assertTrue(age[['6', '7', '9']] in agg) + + self.assertFalse(5 in agg) + self.assertFalse('5' in agg) + self.assertFalse(age20 in agg) + self.assertFalse(age20bis in agg) + self.assertFalse(age20ter in agg) + self.assertFalse(age20qua in agg) + self.assertFalse('2,7' in agg) + self.assertFalse(['2', '7'] in agg) + self.assertFalse(age['2,7'] in agg) + self.assertFalse(age[['2', '7']] in agg) + + +class TestAxisCollection(TestCase): + def setUp(self): + self.lipro = Axis('lipro=P01..P04') + self.sex = Axis('sex=M,F') + self.sex2 = Axis('sex=F,M') + self.age = Axis('age=0..7') + self.geo = Axis('geo=A11,A12,A13') + self.value = Axis('value=0..10') + self.collection = AxisCollection((self.lipro, self.sex, self.age)) + + def test_init_from_group(self): + lipro_subset = self.lipro[:'P03'] + col2 = AxisCollection((lipro_subset, self.sex)) + self.assertEqual(col2.names, ['lipro', 'sex']) + assert_array_equal(col2.lipro.labels, ['P01', 'P02', 'P03']) + assert_array_equal(col2.sex.labels, ['M', 'F']) + + def test_init_from_string(self): + col = AxisCollection('age=10;sex=M,F;year=2000..2017') + assert col.names == ['age', 'sex', 'year'] + assert list(col.age.labels) == [10] + assert list(col.sex.labels) == ['M', 'F'] + assert list(col.year.labels) == [y for y in range(2000, 2018)] + + def test_eq(self): + col = self.collection + self.assertEqual(col, col) + self.assertEqual(col, AxisCollection((self.lipro, self.sex, self.age))) + self.assertEqual(col, (self.lipro, self.sex, self.age)) + self.assertNotEqual(col, (self.lipro, self.age, self.sex)) + + def test_getitem_name(self): + col = self.collection + self.assert_axis_eq(col['lipro'], self.lipro) + self.assert_axis_eq(col['sex'], self.sex) + self.assert_axis_eq(col['age'], self.age) + + def test_getitem_int(self): + col = self.collection + self.assert_axis_eq(col[0], self.lipro) + self.assert_axis_eq(col[-3], self.lipro) + self.assert_axis_eq(col[1], self.sex) + self.assert_axis_eq(col[-2], self.sex) + self.assert_axis_eq(col[2], self.age) + self.assert_axis_eq(col[-1], self.age) + + def test_getitem_slice(self): + col = self.collection[:2] + self.assertEqual(len(col), 2) + self.assert_axis_eq(col[0], self.lipro) + self.assert_axis_eq(col[1], self.sex) + + def test_setitem_name(self): + col = self.collection[:] + # replace an axis with one with another name + col['lipro'] = self.geo + self.assertEqual(len(col), 3) + self.assertEqual(col, [self.geo, self.sex, self.age]) + # replace an axis with one with the same name + col['sex'] = self.sex2 + self.assertEqual(col, [self.geo, self.sex2, self.age]) + col['geo'] = self.lipro + self.assertEqual(col, [self.lipro, self.sex2, self.age]) + col['age'] = self.geo + self.assertEqual(col, [self.lipro, self.sex2, self.geo]) + col['sex'] = self.sex + col['geo'] = self.age + self.assertEqual(col, self.collection) + + def test_setitem_name_axis_def(self): + col = self.collection[:] + # replace an axis with one with another name + col['lipro'] = 'geo=A11,A12,A13' + self.assertEqual(len(col), 3) + self.assertEqual(col, [self.geo, self.sex, self.age]) + # replace an axis with one with the same name + col['sex'] = 'sex=F,M' + self.assertEqual(col, [self.geo, self.sex2, self.age]) + col['geo'] = 'lipro=P01..P04' + self.assertEqual(col, [self.lipro, self.sex2, self.age]) + col['age'] = 'geo=A11,A12,A13' + self.assertEqual(col, [self.lipro, self.sex2, self.geo]) + col['sex'] = 'sex=M,F' + col['geo'] = 'age=0..7' + self.assertEqual(col, self.collection) + + def test_setitem_int(self): + col = self.collection[:] + col[1] = self.geo + self.assertEqual(len(col), 3) + self.assertEqual(col, [self.lipro, self.geo, self.age]) + col[2] = self.sex + self.assertEqual(col, [self.lipro, self.geo, self.sex]) + col[-1] = self.age + self.assertEqual(col, [self.lipro, self.geo, self.age]) + + def test_setitem_list_replace(self): + col = self.collection[:] + col[['lipro', 'age']] = [self.geo, self.lipro] + self.assertEqual(col, [self.geo, self.sex, self.lipro]) + + def test_setitem_slice_replace(self): + col = self.collection[:] + # replace by list + col[1:] = [self.geo, self.sex] + self.assertEqual(col, [self.lipro, self.geo, self.sex]) + # replace by collection + col[1:] = self.collection[1:] + self.assertEqual(col, self.collection) + + def test_setitem_slice_insert(self): + col = self.collection[:] + col[1:1] = [self.geo] + self.assertEqual(col, [self.lipro, self.geo, self.sex, self.age]) + + def test_setitem_slice_delete(self): + col = self.collection[:] + col[1:2] = [] + self.assertEqual(col, [self.lipro, self.age]) + col[0:1] = [] + self.assertEqual(col, [self.age]) + + def assert_axis_eq(self, axis1, axis2): + self.assertTrue(axis1.equals(axis2)) + + def test_delitem(self): + col = self.collection[:] + self.assertEqual(len(col), 3) + del col[0] + self.assertEqual(len(col), 2) + self.assert_axis_eq(col[0], self.sex) + self.assert_axis_eq(col[1], self.age) + del col['age'] + self.assertEqual(len(col), 1) + self.assert_axis_eq(col[0], self.sex) + del col[self.sex] + self.assertEqual(len(col), 0) + + def test_delitem_slice(self): + col = self.collection[:] + self.assertEqual(len(col), 3) + del col[0:2] + self.assertEqual(len(col), 1) + self.assertEqual(col, [self.age]) + del col[:] + self.assertEqual(len(col), 0) + + def test_pop(self): + col = self.collection[:] + lipro, sex, age = col + self.assertEqual(len(col), 3) + self.assertIs(col.pop(), age) + self.assertEqual(len(col), 2) + self.assertIs(col[0], lipro) + self.assertIs(col[1], sex) + self.assertIs(col.pop(), sex) + self.assertEqual(len(col), 1) + self.assertIs(col[0], lipro) + self.assertIs(col.pop(), lipro) + self.assertEqual(len(col), 0) + + def test_replace(self): + col = self.collection[:] + newcol = col.replace('sex', self.geo) + # original collection is not modified + self.assertEqual(col, self.collection) + self.assertEqual(len(newcol), 3) + self.assertEqual(newcol.names, ['lipro', 'geo', 'age']) + self.assertEqual(newcol.shape, (4, 3, 8)) + newcol = newcol.replace(self.geo, self.sex) + self.assertEqual(len(newcol), 3) + self.assertEqual(newcol.names, ['lipro', 'sex', 'age']) + self.assertEqual(newcol.shape, (4, 2, 8)) + + # from now on, reuse original collection + newcol = col.replace(self.sex, 3) + self.assertEqual(len(newcol), 3) + self.assertEqual(newcol.names, ['lipro', None, 'age']) + self.assertEqual(newcol.shape, (4, 3, 8)) + + newcol = col.replace(self.sex, ['a', 'b', 'c']) + self.assertEqual(len(newcol), 3) + self.assertEqual(newcol.names, ['lipro', None, 'age']) + self.assertEqual(newcol.shape, (4, 3, 8)) + + newcol = col.replace(self.sex, "letters=a,b,c") + self.assertEqual(len(newcol), 3) + self.assertEqual(newcol.names, ['lipro', 'letters', 'age']) + self.assertEqual(newcol.shape, (4, 3, 8)) + + def test_contains(self): + col = self.collection + self.assertTrue('lipro' in col) + self.assertFalse('nonexisting' in col) + + self.assertTrue(0 in col) + self.assertTrue(1 in col) + self.assertTrue(2 in col) + self.assertTrue(-1 in col) + self.assertTrue(-2 in col) + self.assertTrue(-3 in col) + self.assertFalse(3 in col) + + # objects actually in col + self.assertTrue(self.lipro in col) + self.assertTrue(self.sex in col) + self.assertTrue(self.age in col) + # other axis with the same name + self.assertTrue(self.sex2 in col) + self.assertFalse(self.geo in col) + self.assertFalse(self.value in col) + + # test anonymous axes + anon = Axis([0, 1]) + col.append(anon) + self.assertTrue(anon in col) + # different object, same values + anon2 = anon.copy() + self.assertTrue(anon2 in col) + # different values + anon3 = Axis([0, 2]) + self.assertFalse(anon3 in col) + + def test_index(self): + col = self.collection + self.assertEqual(col.index('lipro'), 0) + with self.assertRaises(ValueError): + col.index('nonexisting') + self.assertEqual(col.index(0), 0) + self.assertEqual(col.index(1), 1) + self.assertEqual(col.index(2), 2) + self.assertEqual(col.index(-1), -1) + self.assertEqual(col.index(-2), -2) + self.assertEqual(col.index(-3), -3) + with self.assertRaises(ValueError): + col.index(3) + + # objects actually in col + self.assertEqual(col.index(self.lipro), 0) + self.assertEqual(col.index(self.sex), 1) + self.assertEqual(col.index(self.age), 2) + # other axis with the same name + self.assertEqual(col.index(self.sex2), 1) + # non existing + with self.assertRaises(ValueError): + col.index(self.geo) + with self.assertRaises(ValueError): + col.index(self.value) + + # test anonymous axes + anon = Axis([0, 1]) + col.append(anon) + self.assertEqual(col.index(anon), 3) + # different object, same values + anon2 = anon.copy() + self.assertEqual(col.index(anon2), 3) + # different values + anon3 = Axis([0, 2]) + with self.assertRaises(ValueError): + col.index(anon3) + + def test_get(self): + col = self.collection + self.assert_axis_eq(col.get('lipro'), self.lipro) + self.assertIsNone(col.get('nonexisting')) + self.assertIs(col.get('nonexisting', self.value), self.value) + + def test_keys(self): + self.assertEqual(self.collection.keys(), ['lipro', 'sex', 'age']) + + def test_getattr(self): + col = self.collection + self.assert_axis_eq(col.lipro, self.lipro) + self.assert_axis_eq(col.sex, self.sex) + self.assert_axis_eq(col.age, self.age) + + def test_append(self): + col = self.collection + geo = Axis('geo=A11,A12,A13') + col.append(geo) + self.assertEqual(col, [self.lipro, self.sex, self.age, geo]) + + def test_extend(self): + col = self.collection + col.extend([self.geo, self.value]) + self.assertEqual(col, + [self.lipro, self.sex, self.age, self.geo, self.value]) + + def test_insert(self): + col = self.collection + col.insert(1, self.geo) + self.assertEqual(col, [self.lipro, self.geo, self.sex, self.age]) + + def test_add(self): + col = self.collection.copy() + lipro, sex, age = self.lipro, self.sex, self.age + geo, value = self.geo, self.value + + # 1) list + # a) no dupe + new = col + [self.geo, value] + self.assertEqual(new, [lipro, sex, age, geo, value]) + # check the original has not been modified + self.assertEqual(col, self.collection) + + # b) with compatible dupe + # the "new" age axis is ignored (because it is compatible) + new = col + [Axis('geo=A11,A12,A13'), Axis('age=0..7')] + self.assertEqual(new, [lipro, sex, age, geo]) + + # c) with incompatible dupe + # XXX: the "new" age axis is ignored. We might want to ignore it if it + # is the same but raise an exception if it is different + with self.assertRaises(ValueError): + col + [Axis('geo=A11,A12,A13'), Axis('age=0..6')] + + # 2) other AxisCollection + new = col + AxisCollection([geo, value]) + self.assertEqual(new, [lipro, sex, age, geo, value]) + + def test_combine(self): + col = self.collection.copy() + lipro, sex, age = self.lipro, self.sex, self.age + res = col.combine_axes((lipro, sex)) + self.assertEqual(res.names, ['lipro_sex', 'age']) + self.assertEqual(res.size, col.size) + self.assertEqual(res.shape, (4 * 2, 8)) + print(res.info) + assert_array_equal(res.lipro_sex.labels[0], 'P01_M') + res = col.combine_axes((lipro, age)) + self.assertEqual(res.names, ['lipro_age', 'sex']) + self.assertEqual(res.size, col.size) + self.assertEqual(res.shape, (4 * 8, 2)) + assert_array_equal(res.lipro_age.labels[0], 'P01_0') + res = col.combine_axes((sex, age)) + self.assertEqual(res.names, ['lipro', 'sex_age']) + self.assertEqual(res.size, col.size) + self.assertEqual(res.shape, (4, 2 * 8)) + assert_array_equal(res.sex_age.labels[0], 'M_0') + + def test_info(self): + expected = """\ +4 x 2 x 8 + lipro [4]: 'P01' 'P02' 'P03' 'P04' + sex [2]: 'M' 'F' + age [8]: 0 1 2 ... 5 6 7""" + self.assertEqual(self.collection.info, expected) + + def test_str(self): + self.assertEqual(str(self.collection), "{lipro, sex, age}") + + def test_repr(self): + self.assertEqual(repr(self.collection), """AxisCollection([ + Axis(['P01', 'P02', 'P03', 'P04'], 'lipro'), + Axis(['M', 'F'], 'sex'), + Axis([0, 1, 2, 3, 4, 5, 6, 7], 'age') +])""") + + +if __name__ == "__main__": + pytest.main() diff --git a/larray/tests/test_excel.py b/larray/tests/test_excel.py new file mode 100644 index 000000000..0f04eeafa --- /dev/null +++ b/larray/tests/test_excel.py @@ -0,0 +1,245 @@ +from __future__ import absolute_import, division, print_function + +import re + +import pytest +import numpy as np + +try: + import xlwings as xw +except ImportError: + xw = None + +from larray import ndtest, larray_equal, open_excel, aslarray, Axis +from larray.inout import excel + + +@pytest.mark.skipif(xw is None, reason="xlwings is not available") +class TestWorkbook(object): + def test_open_excel(self): + # not using context manager because we call .quit manually + wb1 = open_excel(visible=False) + app1 = wb1.app + wb1.close() + # anything using wb1 will fail + with pytest.raises(Exception): + wb1.sheet_names() + wb2 = open_excel(visible=False) + app2 = wb2.app + assert app1 == app2 == excel.global_app + # this effectively close all workbooks but leaves the instance intact (this is probably due to us keeping a + # reference to it). + app1.quit() + # anything using wb2 will fail + with pytest.raises(Exception): + wb2.sheet_names() + + # in any case, this should work + with open_excel(visible=False) as wb: + wb['test'] = 'content' + + def test_repr(self): + with open_excel(visible=False) as wb: + assert re.match('', repr(wb)) + + def test_getitem(self): + with open_excel(visible=False) as wb: + sheet = wb[0] + assert isinstance(sheet, excel.Sheet) + # this might not be true on non-English locale + assert sheet.name == 'Sheet1' + + # this might not work on non-English locale + sheet = wb['Sheet1'] + assert isinstance(sheet, excel.Sheet) + assert sheet.name == 'Sheet1' + + with pytest.raises(KeyError) as e_info: + wb['this_sheet_does_not_exist'] + assert e_info.value.args[0] == "Workbook has no sheet named this_sheet_does_not_exist" + + def test_setitem(self): + with open_excel(visible=False) as wb: + # sheet did not exist, str value + wb['sheet1'] = 'sheet1 content' + wb['sheet2'] = 'sheet2 content' + assert wb.sheet_names() == ['sheet1', 'sheet2'] + + # sheet did exist, str value + wb['sheet2'] = 'sheet2 content v2' + assert wb.sheet_names() == ['sheet1', 'sheet2'] + assert wb['sheet2']['A1'].value == 'sheet2 content v2' + + # sheet did not exist, Sheet value + wb['sheet3'] = wb['sheet1'] + assert wb.sheet_names() == ['sheet1', 'sheet2', 'sheet3'] + assert wb['sheet3']['A1'].value == 'sheet1 content' + + # sheet did exist, Sheet value + wb['sheet2'] = wb['sheet1'] + assert wb.sheet_names() == ['sheet1', 'sheet2', 'sheet3'] + assert wb['sheet2']['A1'].value == 'sheet1 content' + + with open_excel(visible=False, app="new") as wb2: + with pytest.raises(ValueError) as e_info: + wb2['sheet1'] = wb['sheet1'] + assert e_info.value.args[0] == "cannot copy a sheet from one instance of Excel to another" + + # group key + arr = ndtest((3, 3)) + for label in arr.b: + wb[label] = arr[label].dump() + assert arr[label].equals(wb[label].load()) + + def test_delitem(self): + with open_excel(visible=False) as wb: + wb['sheet1'] = 'sheet1 content' + wb['sheet2'] = 'sheet2 content' + del wb['sheet1'] + assert wb.sheet_names() == ['sheet2'] + + def test_rename(self): + with open_excel(visible=False) as wb: + wb['sheet_name'] = 'sheet content' + wb['sheet_name'].name = 'renamed' + assert wb.sheet_names() == ['renamed'] + + +@pytest.mark.skipif(xw is None, reason="xlwings is not available") +class TestSheet(object): + def test_get_and_set_item(self): + arr = ndtest((2, 3)) + + with open_excel(visible=False) as wb: + sheet = wb[0] + # set a few values + sheet['A1'] = 1.5 + sheet['A2'] = 2 + sheet['A3'] = True + sheet['A4'] = 'toto' + # array without header + sheet['A5'] = arr + # array with header + sheet['A8'] = arr.dump() + + # read them back + assert sheet['A1'].value == 1.5 + assert sheet['A2'].value == 2 + assert sheet['A3'].value == True + assert sheet['A4'].value == 'toto' + # array without header + assert np.array_equal(sheet['A5:C6'].value, arr.data) + # array with header + assert arr.equals(sheet['A8:D10'].load()) + + def test_asarray(self): + with open_excel(visible=False) as wb: + sheet = wb[0] + + arr1 = ndtest((2, 3)) + # no header so that we have an uniform dtype for the whole sheet + sheet['A1'] = arr1 + res1 = np.asarray(sheet) + assert np.array_equal(res1, arr1.data) + assert res1.dtype == arr1.dtype + + def test_array_method(self): + with open_excel(visible=False) as wb: + sheet = wb[0] + + # normal test array + arr1 = ndtest((2, 3)) + sheet['A1'] = arr1.dump() + res1 = sheet.array('B2:D3', 'A2:A3', 'B1:D1', names=['a', 'b']) + assert arr1.equals(res1) + + # array with int labels + arr2 = ndtest('0..1;0..2') + sheet['A1'] = arr2.dump() + res2 = sheet.array('B2:D3', 'A2:A3', 'B1:D1') + # larray_equal passes even if the labels are floats... + assert arr2.equals(res2) + # so we check the dtype explicitly + assert res2.axes[0].labels.dtype == arr2.axes[0].labels.dtype + assert res2.axes[1].labels.dtype == arr2.axes[1].labels.dtype + + def test_repr(self): + with open_excel(visible=False) as wb: + sheet = wb[0] + assert re.match('', repr(sheet)) + + +@pytest.mark.skipif(xw is None, reason="xlwings is not available") +class TestRange(object): + def test_scalar_convert(self): + with open_excel(visible=False) as wb: + sheet = wb[0] + # set a few values + sheet['A1'] = 1 + rng = sheet['A1'] + assert int(rng) == 1 + assert float(rng) == 1.0 + assert rng.__index__() == 1 + + sheet['A2'] = 1.0 + rng = sheet['A2'] + assert int(rng) == 1 + assert float(rng) == 1.0 + # Excel stores everything as float so we cannot really make the difference between 1 and 1.0 + assert rng.__index__() == 1 + + sheet['A3'] = 1.5 + rng = sheet['A3'] + assert int(rng) == 1 + assert float(rng) == 1.5 + with pytest.raises(TypeError) as e_info: + rng.__index__() + assert e_info.value.args[0] == "only integer scalars can be converted to a scalar index" + + def test_asarray(self): + with open_excel(visible=False) as wb: + sheet = wb[0] + + arr1 = ndtest((2, 3)) + # no header so that we have an uniform dtype for the whole sheet + sheet['A1'] = arr1 + res1 = np.asarray(sheet['A1:C2']) + assert np.array_equal(res1, arr1.data) + assert res1.dtype == arr1.dtype + + def test_aslarray(self): + with open_excel(visible=False) as wb: + sheet = wb[0] + + arr1 = ndtest([Axis(2), Axis(3)]) + # no header so that we have an uniform dtype for the whole sheet + sheet['A1'] = arr1 + res1 = aslarray(sheet['A1:C2']) + assert res1.equals(arr1) + assert res1.dtype == arr1.dtype + + # this tests Range.__getattr__ with an LArray attribute + def test_aggregate(self): + with open_excel(visible=False) as wb: + sheet = wb[0] + + arr1 = ndtest((2, 3)) + # no header so that we have an uniform dtype for the whole sheet + sheet['A1'] = arr1 + res = sheet['A1:C2'].sum() + assert res == 15 + + def test_repr(self): + with open_excel(visible=False) as wb: + sheet = wb[0] + + arr1 = ndtest((2, 3)) + sheet['A1'] = arr1 + res = repr(sheet['A1:C2']) + assert res == """\ +{0}*\{1}* 0 1 2 + 0 0 1 2 + 1 3 4 5""" + +if __name__ == "__main__": + pytest.main() diff --git a/larray/tests/test_group.py b/larray/tests/test_group.py new file mode 100644 index 000000000..bbf6f2f14 --- /dev/null +++ b/larray/tests/test_group.py @@ -0,0 +1,294 @@ +from __future__ import absolute_import, division, print_function + +from unittest import TestCase + +import pytest +import numpy as np + +from larray.tests.common import assert_array_equal +from larray import Axis, LGroup, LSet, ndtest + + +class TestLGroup(TestCase): + def setUp(self): + self.age = Axis('age=0..10') + self.lipro = Axis('lipro=P01..P05') + self.anonymous = Axis(range(3)) + + self.slice_both_named_wh_named_axis = LGroup('1:5', "full", self.age) + self.slice_both_named = LGroup('1:5', "named") + self.slice_both = LGroup('1:5') + self.slice_start = LGroup('1:') + self.slice_stop = LGroup(':5') + self.slice_none_no_axis = LGroup(':') + self.slice_none_wh_named_axis = LGroup(':', axis=self.lipro) + self.slice_none_wh_anonymous_axis = LGroup(':', axis=self.anonymous) + + self.single_value = LGroup('P03') + self.list = LGroup('P01,P03,P04') + self.list_named = LGroup('P01,P03,P04', "P134") + + def test_init(self): + self.assertEqual(self.slice_both_named_wh_named_axis.name, "full") + self.assertEqual(self.slice_both_named_wh_named_axis.key, slice(1, 5, None)) + self.assertIs(self.slice_both_named_wh_named_axis.axis, self.age) + + self.assertEqual(self.slice_both_named.name, "named") + self.assertEqual(self.slice_both_named.key, slice(1, 5, None)) + + self.assertEqual(self.slice_both.key, slice(1, 5, None)) + self.assertEqual(self.slice_start.key, slice(1, None, None)) + self.assertEqual(self.slice_stop.key, slice(None, 5, None)) + self.assertEqual(self.slice_none_no_axis.key, slice(None, None, None)) + self.assertIs(self.slice_none_wh_named_axis.axis, self.lipro) + self.assertIs(self.slice_none_wh_anonymous_axis.axis, self.anonymous) + + self.assertEqual(self.single_value.key, 'P03') + self.assertEqual(self.list.key, ['P01', 'P03', 'P04']) + + # passing an axis as name + group = LGroup('1:5', self.age, self.age) + assert group.name == self.age.name + group = self.age['1:5'] >> self.age + assert group.name == self.age.name + # passing an unnamed group as name + group2 = LGroup('1', axis=self.age) + group = LGroup('1', group2, axis=self.age) + assert group.name == '1' + group = self.age['1'] >> group2 + assert group.name == '1' + # passing a named group as name + group2 = LGroup('1:5', 'age', self.age) + group = LGroup('1:5', group2, axis=self.age) + assert group.name == group2.name + group = self.age['1:5'] >> group2 + assert group.name == group2.name + # additional test + axis = Axis('axis=a,a0..a3,b,b0..b3,c,c0..c3') + for code in axis.matching('^.$'): + group = axis.startingwith(code) >> code + assert group == axis.startingwith(code) >> str(code) + + def test_eq(self): + # with axis vs no axis do not compare equal + # self.assertEqual(self.slice_both, self.slice_both_named_wh_named_axis) + self.assertEqual(self.slice_both, self.slice_both_named) + + res = self.slice_both_named_wh_named_axis == self.age[1:5] + self.assertIsInstance(res, np.ndarray) + self.assertEqual(res.shape, (5,)) + self.assertTrue(res.all()) + + self.assertEqual(self.slice_both, LGroup(slice(1, 5))) + self.assertEqual(self.slice_start, LGroup(slice(1, None))) + self.assertEqual(self.slice_stop, LGroup(slice(5))) + self.assertEqual(self.slice_none_no_axis, LGroup(slice(None))) + + self.assertEqual(self.single_value, LGroup('P03')) + self.assertEqual(self.list, LGroup(['P01', 'P03', 'P04'])) + self.assertEqual(self.list_named, LGroup(['P01', 'P03', 'P04'])) + + # test with raw objects + self.assertEqual(self.slice_both, slice(1, 5)) + self.assertEqual(self.slice_start, slice(1, None)) + self.assertEqual(self.slice_stop, slice(5)) + self.assertEqual(self.slice_none_no_axis, slice(None)) + + self.assertEqual(self.single_value, 'P03') + self.assertEqual(self.list, ['P01', 'P03', 'P04']) + self.assertEqual(self.list_named, ['P01', 'P03', 'P04']) + + def test_getitem(self): + axis = Axis("a=a0,a1") + assert axis['a0'][0] == 'a' + assert axis['a0'][1] == '0' + assert axis['a0':'a1'][1] == 'a1' + assert axis[:][1] == 'a1' + assert list(axis[:][0:2]) == ['a0', 'a1'] + assert list((axis[:][[1, 0]])) == ['a1', 'a0'] + assert axis[['a0', 'a1', 'a0']][2] == 'a0' + assert axis[('a0', 'a1', 'a0')][2] == 'a0' + assert axis[ndtest("a=a0,a1,a0")][2] == 2 + + def test_sorted(self): + self.assertEqual(sorted(LGroup(['c', 'd', 'a', 'b'])), + [LGroup('a'), LGroup('b'), LGroup('c'), LGroup('d')]) + + def test_asarray(self): + assert_array_equal(np.asarray(self.slice_both_named_wh_named_axis), np.array([1, 2, 3, 4, 5])) + assert_array_equal(np.asarray(self.slice_none_wh_named_axis), np.array(['P01', 'P02', 'P03', 'P04', 'P05'])) + + def test_hash(self): + # this test is a lot less important than what it used to, because we cannot have Group ticks on an axis anymore + d = {self.slice_both: 1, + self.single_value: 2, + self.list_named: 3} + # target a LGroup with an equivalent LGroup + self.assertEqual(d.get(self.slice_both), 1) + self.assertEqual(d.get(self.single_value), 2) + self.assertEqual(d.get(self.list), 3) + self.assertEqual(d.get(self.list_named), 3) + + def test_repr(self): + self.assertEqual(repr(self.slice_both_named_wh_named_axis), "age[1:5] >> 'full'") + self.assertEqual(repr(self.slice_both_named), "LGroup(slice(1, 5, None)) >> 'named'") + self.assertEqual(repr(self.slice_both), "LGroup(slice(1, 5, None))") + self.assertEqual(repr(self.list), "LGroup(['P01', 'P03', 'P04'])") + self.assertEqual(repr(self.slice_none_no_axis), "LGroup(slice(None, None, None))") + self.assertEqual(repr(self.slice_none_wh_named_axis), "lipro[:]") + self.assertEqual(repr(self.slice_none_wh_anonymous_axis), + "LGroup(slice(None, None, None), axis=Axis([0, 1, 2], None))") + + def test_to_int(self): + a = Axis(['42'], 'a') + self.assertEqual(int(a['42']), 42) + + def test_to_float(self): + a = Axis(['42'], 'a') + self.assertEqual(float(a['42']), 42.0) + + +class TestLSet(TestCase): + def test_or(self): + # without axis + self.assertEqual(LSet(['a', 'b']) | LSet(['c', 'd']), + LSet(['a', 'b', 'c', 'd'])) + self.assertEqual(LSet(['a', 'b', 'c']) | LSet(['c', 'd']), + LSet(['a', 'b', 'c', 'd'])) + # with axis (pure) + alpha = Axis('alpha=a,b,c,d') + res = alpha['a', 'b'].set() | alpha['c', 'd'].set() + self.assertIs(res.axis, alpha) + self.assertEqual(res, alpha['a', 'b', 'c', 'd'].set()) + self.assertEqual(alpha['a', 'b', 'c'].set() | alpha['c', 'd'].set(), + alpha['a', 'b', 'c', 'd'].set()) + + # with axis (mixed) + alpha = Axis('alpha=a,b,c,d') + res = alpha['a', 'b'].set() | alpha['c', 'd'] + self.assertIs(res.axis, alpha) + self.assertEqual(res, alpha['a', 'b', 'c', 'd'].set()) + self.assertEqual(alpha['a', 'b', 'c'].set() | alpha['c', 'd'], + alpha['a', 'b', 'c', 'd'].set()) + + # with axis & name + alpha = Axis('alpha=a,b,c,d') + res = alpha['a', 'b'].set().named('ab') | alpha['c', 'd'].set().named('cd') + self.assertIs(res.axis, alpha) + self.assertEqual(res.name, 'ab | cd') + self.assertEqual(res, alpha['a', 'b', 'c', 'd'].set()) + self.assertEqual(alpha['a', 'b', 'c'].set() | alpha['c', 'd'], + alpha['a', 'b', 'c', 'd'].set()) + + # numeric axis + num = Axis(range(10), 'num') + # single int + self.assertEqual(num[1, 5, 3].set() | 4, num[1, 5, 3, 4].set()) + self.assertEqual(num[1, 5, 3].set() | num[4], num[1, 5, 3, 4].set()) + self.assertEqual(num[4].set() | num[1, 5, 3], num[4, 1, 5, 3].set()) + # slices + self.assertEqual(num[:2].set() | num[8:], num[0, 1, 2, 8, 9].set()) + self.assertEqual(num[:2].set() | num[5], num[0, 1, 2, 5].set()) + + def test_and(self): + # without axis + self.assertEqual(LSet(['a', 'b', 'c']) & LSet(['c', 'd']), LSet(['c'])) + # with axis & name + alpha = Axis('alpha=a,b,c,d') + res = alpha['a', 'b', 'c'].named('abc').set() & alpha['c', 'd'].named('cd') + self.assertIs(res.axis, alpha) + self.assertEqual(res.name, 'abc & cd') + self.assertEqual(res, alpha[['c']].set()) + + def test_sub(self): + self.assertEqual(LSet(['a', 'b', 'c']) - LSet(['c', 'd']), LSet(['a', 'b'])) + self.assertEqual(LSet(['a', 'b', 'c']) - ['c', 'd'], LSet(['a', 'b'])) + self.assertEqual(LSet(['a', 'b', 'c']) - 'b', LSet(['a', 'c'])) + self.assertEqual(LSet([1, 2, 3]) - 4, LSet([1, 2, 3])) + self.assertEqual(LSet([1, 2, 3]) - 2, LSet([1, 3])) + + +class TestIGroup(TestCase): + def _assert_array_equal_is_true_array(self, a, b): + res = a == b + self.assertIsInstance(res, np.ndarray) + self.assertEqual(res.shape, np.asarray(b).shape) + self.assertTrue(res.all()) + + def setUp(self): + self.code_axis = Axis('code=a0..a4') + + self.slice_both_named = self.code_axis.i[1:4] >> 'a123' + self.slice_both = self.code_axis.i[1:4] + self.slice_start = self.code_axis.i[1:] + self.slice_stop = self.code_axis.i[:4] + self.slice_none = self.code_axis.i[:] + + self.first_value = self.code_axis.i[0] + self.last_value = self.code_axis.i[-1] + self.list = self.code_axis.i[[0, 1, -2, -1]] + self.tuple = self.code_axis.i[0, 1, -2, -1] + + def test_asarray(self): + assert_array_equal(np.asarray(self.slice_both), np.array(['a1', 'a2', 'a3'])) + + def test_eq(self): + self._assert_array_equal_is_true_array(self.slice_both, ['a1', 'a2', 'a3']) + self._assert_array_equal_is_true_array(self.slice_both_named, ['a1', 'a2', 'a3']) + self._assert_array_equal_is_true_array(self.slice_both, self.slice_both_named) + self._assert_array_equal_is_true_array(self.slice_both_named, self.slice_both) + self._assert_array_equal_is_true_array(self.slice_start, ['a1', 'a2', 'a3', 'a4']) + self._assert_array_equal_is_true_array(self.slice_stop, ['a0', 'a1', 'a2', 'a3']) + self._assert_array_equal_is_true_array(self.slice_none, ['a0', 'a1', 'a2', 'a3', 'a4']) + + self.assertEqual(self.first_value, 'a0') + self.assertEqual(self.last_value, 'a4') + + self._assert_array_equal_is_true_array(self.list, ['a0', 'a1', 'a3', 'a4']) + self._assert_array_equal_is_true_array(self.tuple, ['a0', 'a1', 'a3', 'a4']) + + def test_getitem(self): + axis = Axis("a=a0,a1") + assert axis.i[0][0] == 'a' + assert axis.i[0][1] == '0' + assert axis.i[0:1][1] == 'a1' + assert axis.i[:][1] == 'a1' + assert list(axis.i[:][0:2]) == ['a0', 'a1'] + assert list((axis.i[:][[1, 0]])) == ['a1', 'a0'] + assert axis.i[[0, 1, 0]][2] == 'a0' + assert axis.i[(0, 1, 0)][2] == 'a0' + + def test_getattr(self): + agg = Axis(['a1:a2', ':a2', 'a1:'], 'agg') + self.assertEqual(agg.i[0].split(':'), ['a1', 'a2']) + self.assertEqual(agg.i[1].split(':'), ['', 'a2']) + self.assertEqual(agg.i[2].split(':'), ['a1', '']) + + def test_dir(self): + agg = Axis(['a', 1], 'agg') + self.assertTrue('split' in dir(agg.i[0])) + self.assertTrue('strip' in dir(agg.i[0])) + self.assertTrue('strip' in dir(agg.i[0])) + + def test_repr(self): + self.assertEqual(repr(self.slice_both_named), "code.i[1:4] >> 'a123'") + self.assertEqual(repr(self.slice_both), "code.i[1:4]") + self.assertEqual(repr(self.slice_start), "code.i[1:]") + self.assertEqual(repr(self.slice_stop), "code.i[:4]") + self.assertEqual(repr(self.slice_none), "code.i[:]") + self.assertEqual(repr(self.first_value), "code.i[0]") + self.assertEqual(repr(self.last_value), "code.i[-1]") + self.assertEqual(repr(self.list), "code.i[0, 1, -2, -1]") + self.assertEqual(repr(self.tuple), "code.i[0, 1, -2, -1]") + + def test_to_int(self): + a = Axis(['42'], 'a') + self.assertEqual(int(a.i[0]), 42) + + def test_to_float(self): + a = Axis(['42'], 'a') + self.assertEqual(float(a.i[0]), 42.0) + + +if __name__ == "__main__": + pytest.main() diff --git a/larray/tests/test_ipfp.py b/larray/tests/test_ipfp.py new file mode 100644 index 000000000..fd7961a81 --- /dev/null +++ b/larray/tests/test_ipfp.py @@ -0,0 +1,198 @@ +from __future__ import absolute_import, division, print_function + +from unittest import TestCase + +import pytest + +from larray.tests.common import assert_array_equal +from larray import Axis, LArray, ndtest, ipfp, X + + +class TestIPFP(TestCase): + def test_ipfp(self): + a = Axis('a=a0,a1') + b = Axis('b=b0,b1') + initial = LArray([[2, 1], [1, 2]], [a, b]) + + # array sums already match target sums + # [3, 3], [3, 3] + r = ipfp([initial.sum(a), initial.sum(b)], initial) + assert_array_equal(r, initial) + + # array sums do not match target sums (ie the usual case) + along_a = LArray([2, 1], b) + along_b = LArray([1, 2], a) + r = ipfp([along_a, along_b], initial) + assert_array_equal(r, [[0.8, 0.2], [1.0, 1.0]]) + + # same as above but using a more precise threshold + r = ipfp([along_a, along_b], initial, threshold=0.01) + assert_array_equal(r, [[0.8450704225352113, 0.15492957746478875], + [1.1538461538461537, 0.8461538461538463]]) + + # inverted target sums + with self.assertRaisesRegexp(ValueError, "axes of target sum along a \(axis 0\) do not match corresponding " + "array axes: got {a} but expected {b}. Are the target sums in the " + "correct order\?"): + ipfp([along_b, along_a], initial) + + # different target sums totals + along_a = LArray([2, 1], b) + along_b = LArray([1, 3], a) + with self.assertRaisesRegexp(ValueError, "target sum along b \(axis 1\) is different than target sum along " + "a \(axis 0\): 4 vs 3"): + ipfp([along_a, along_b], initial) + + # all zero values + initial = LArray([[0, 0], [1, 2]], [a, b]) + along_a = LArray([2, 1], b) + along_b = LArray([1, 2], a) + with self.assertRaisesRegexp(ValueError, "found all zero values sum along b \(axis 1\) but non zero target " + "sum:\na0: 1"): + ipfp([along_a, along_b], initial) + + # zero target sum + initial = LArray([[2, 1], [1, 2]], [a, b]) + along_a = LArray([0, 1], b) + along_b = LArray([1, 0], a) + with self.assertRaisesRegexp(ValueError, "found Non Zero Values but Zero target Sum \(nzvzs\) along a " + "\(axis 0\), use nzvzs='warn' or 'fix' to set them to zero " + "automatically:\nb0: 3"): + ipfp([along_a, along_b], initial) + + # negative initial values + initial = LArray([[2, -1], [1, 2]], [a, b]) + with self.assertRaisesRegexp(ValueError, "negative value\(s\) found:\na0_b1: -1"): + ipfp([along_a, along_b], initial) + + # def test_ipfp_big(self): + # initial = ndtest((4000, 4000)) + # targets = [initial.sum(axis) for axis in initial.axes] + # ipfp(targets, display_progress='condensed') + + def test_ipfp_3d(self): + initial = ndtest((2, 2, 2)) + initial_axes = initial.axes + + # array sums already match target sums + targets = [initial.sum(axis) for axis in initial.axes] + r = ipfp(targets, initial) + assert_array_equal(r, initial) + self.assertEqual(r.axes, initial_axes) + + # array sums do not match target sums (ie the usual case) + targets = [initial.sum(axis) + 1 for axis in initial.axes] + r = ipfp(targets, initial) + assert_array_equal(r, [[[0.0, 2.0], + [2.688963210702341, 3.311036789297659]], + [[4.551453540217585, 5.448546459782415], + [6.450132391879964, 7.549867608120035]]]) + self.assertEqual(r.axes, initial_axes) + + # same as above but using a more precise threshold + r = ipfp(targets, initial, threshold=0.01) + assert_array_equal(r, [[[0.0, 1.9999999999999998], + [2.994320023433978, 3.0056799765660225]], + [[4.990248916408187, 5.009751083591813], + [6.009541632308118, 7.990458367691883]]]) + self.assertEqual(r.axes, initial_axes) + + def test_ipfp_3d_with_axes(self): + initial = ndtest((2, 2, 2)) + initial_axes = initial.axes + + # array sums already match target sums (first axes) + axes = (X.a, X.b) + targets = [initial.sum(axis) for axis in axes] + r = ipfp(targets, initial, axes=axes) + assert_array_equal(r, initial) + self.assertEqual(r.axes, initial_axes) + + # array sums already match target sums (other axes) + axes = (X.a, X.c) + targets = [initial.sum(axis) for axis in axes] + r = ipfp(targets, initial, axes=axes) + assert_array_equal(r, initial) + self.assertEqual(r.axes, initial_axes) + + # array sums do not match target sums (ie the usual case) (first axes) + axes = (X.a, X.b) + targets = [initial.sum(axis) + 1 for axis in axes] + r = ipfp(targets, initial, axes=axes) + assert_array_equal(r, [[[0.0, 1.3059701492537312], + [3.0, 3.6940298507462686]], + [[4.680851063829787, 5.603448275862069 ], + [6.319148936170213, 7.3965517241379315]]]) + self.assertEqual(r.axes, initial_axes) + # check that the result is the same as N 2D ipfp calls + assert_array_equal(r['c0'], ipfp([t['c0'] for t in targets], initial['c0'])) + assert_array_equal(r['c1'], ipfp([t['c1'] for t in targets], initial['c1'])) + + # array sums do not match target sums (ie the usual case) (other axes) + axes = (X.a, X.c) + targets = [initial.sum(axis) + 1 for axis in axes] + r = ipfp(targets, initial, axes=axes) + assert_array_equal(r, [[[0.0, 2.0 ], + [2.432432432432432, 3.567567567567567]], + [[4.615384615384615, 5.384615384615385], + [6.539792387543252, 7.460207612456748]]]) + self.assertEqual(r.axes, initial_axes) + # check that the result is the same as N 2D ipfp calls + assert_array_equal(r['b0'], ipfp([t['b0'] for t in targets], initial['b0'])) + assert_array_equal(r['b1'], ipfp([t['b1'] for t in targets], initial['b1'])) + + def test_ipfp_no_values(self): + # 6, 12, 18 + along_a = ndtest([(3, 'b')], start=1) * 6 + # 6, 12, 18 + along_b = ndtest([(3, 'a')], start=1) * 6 + r = ipfp([along_a, along_b]) + assert_array_equal(r, [[1.0, 2.0, 3.0], + [2.0, 4.0, 6.0], + [3.0, 6.0, 9.0]]) + + along_a = LArray([2, 1], Axis(2, 'b')) + along_b = LArray([1, 2], Axis(2, 'a')) + r = ipfp([along_a, along_b]) + assert_array_equal(r, [[2 / 3, 1 / 3], + [4 / 3, 2 / 3]]) + + def test_ipfp_no_values_no_name(self): + r = ipfp([[6, 12, 18], [6, 12, 18]]) + assert_array_equal(r, [[1.0, 2.0, 3.0], + [2.0, 4.0, 6.0], + [3.0, 6.0, 9.0]]) + + r = ipfp([[2, 1], [1, 2]]) + assert_array_equal(r, [[2 / 3, 1 / 3], + [4 / 3, 2 / 3]]) + + def test_ipfp_no_name(self): + initial = LArray([[2, 1], [1, 2]]) + + # sums already correct + # [3, 3], [3, 3] + r = ipfp([initial.sum(axis=0), initial.sum(axis=1)], initial) + assert_array_equal(r, [[2, 1], [1, 2]]) + + # different sums (ie the usual case) + along_a = LArray([2, 1]) + along_b = LArray([1, 2]) + r = ipfp([along_a, along_b], initial) + assert_array_equal(r, [[0.8, 0.2], [1.0, 1.0]]) + + def test_ipfp_non_larray(self): + initial = [[2, 1], [1, 2]] + + # sums already correct + r = ipfp([[3, 3], [3, 3]], initial) + assert_array_equal(r, [[2, 1], [1, 2]]) + + # different sums (ie the usual case) + r = ipfp([[2, 1], [1, 2]], initial) + assert_array_equal(r, [[0.8, 0.2], [1.0, 1.0]]) + + +if __name__ == "__main__": + pytest.main() + diff --git a/larray/tests/test_la.py b/larray/tests/test_la.py deleted file mode 100644 index ae75fd44d..000000000 --- a/larray/tests/test_la.py +++ /dev/null @@ -1,2551 +0,0 @@ -from __future__ import absolute_import, division, print_function - -import os.path -import sys -from unittest import TestCase -import unittest - -import numpy as np -import pandas as pd - -from larray import (LArray, Axis, AxisCollection, LGroup, union, - read_csv, zeros, zeros_like, ndrange, ones, eye, diag, - clip, exp, where, x, view, mean, var, std, isnan, - round, local_arrays) -from larray.core import to_ticks, to_key, srange, df_aslarray - - -TESTDATADIR = os.path.dirname(__file__) - - -def abspath(relpath): - """ - :param relpath: path relative to current module - :return: absolute path - """ - return os.path.join(TESTDATADIR, relpath) - -# XXX: maybe we should force value groups to use tuple and families (group of -# groups to use lists, or vice versa, so that we know which is which) -# or use a class, just for that? -# group(a, b, c) -# family(group(a), b, c) - - -def assert_equal_factory(test_func, check_shape=True, check_axes=True): - def assert_equal(a, b): - if isinstance(a, LArray) and isinstance(b, LArray) and a.axes != b.axes: - raise AssertionError("axes differ:\n%s\n\nvs\n\n%s" - % (a.axes.info, b.axes.info)) - if not isinstance(a, (np.ndarray, LArray)): - a = np.asarray(a) - if not isinstance(b, (np.ndarray, LArray)): - b = np.asarray(b) - if a.shape != b.shape: - raise AssertionError("shapes differ: %s != %s" % (a.shape, b.shape)) - equal = test_func(a, b) - if not equal.all(): - # XXX: for some reason ndarray[bool_larray] does not work as we - # would like, so we cannot do b[~equal] directly. I should - # at least understand why this happens and fix this if - # possible. - notequal = np.asarray(~equal) - assert equal.all(), "\ngot:\n\n%s\n\nexpected:\n\n%s" % (a[notequal], - b[notequal]) - return assert_equal - - -def equal(a, b): - return a == b - - -def nan_equal(a, b): - return (a == b) | (np.isnan(a) & np.isnan(b)) - - -# numpy.testing.assert_array_equal/assert_equal would work too but it does not -# (as of numpy 1.10) display specifically the non equal items -assert_array_equal = assert_equal_factory(equal) -assert_array_nan_equal = assert_equal_factory(nan_equal) - - -class TestValueStrings(TestCase): - def test_split(self): - self.assertEqual(to_ticks('H,F'), ['H', 'F']) - self.assertEqual(to_ticks('H, F'), ['H', 'F']) - - def test_union(self): - self.assertEqual(union('A11,A22', 'A12,A22'), ['A11', 'A22', 'A12']) - - def test_range(self): - # XXX: we might want to return real int instead, because if we ever - # want to have more complex queries, such as: - # arr.filter(age > 10 and age < 20) - # this would break for string values (because '10' < '2') - self.assertEqual(to_ticks('0:115'), srange(116)) - self.assertEqual(to_ticks(':115'), srange(116)) - self.assertRaises(ValueError, to_ticks, '10:') - self.assertRaises(ValueError, to_ticks, ':') - - -class TestKeyStrings(TestCase): - def test_nonstring(self): - self.assertEqual(to_key(('H', 'F')), ['H', 'F']) - self.assertEqual(to_key(['H', 'F']), ['H', 'F']) - - def test_split(self): - self.assertEqual(to_key('H,F'), ['H', 'F']) - self.assertEqual(to_key('H, F'), ['H', 'F']) - self.assertEqual(to_key('H,'), ['H']) - self.assertEqual(to_key('H'), 'H') - - def test_slice_strings(self): - # XXX: we might want to return real int instead, because if we ever - # want to have more complex queries, such as: - # arr.filter(age > 10 and age < 20) - # this would break for string values (because '10' < '2') - # XXX: these two examples return different things, do we want that? - self.assertEqual(to_key('0:115'), slice('0', '115')) - self.assertEqual(to_key(':115'), slice('115')) - self.assertEqual(to_key('10:'), slice('10', None)) - self.assertEqual(to_key(':'), slice(None)) - - -class TestAxis(TestCase): - def setUp(self): - pass - - def tearDown(self): - pass - - def test_init(self): - sex_tuple = ('H', 'F') - sex_list = ['H', 'F'] - sex_array = np.array(sex_list) - - # tuple of strings - assert_array_equal(Axis('sex', sex_tuple).labels, sex_array) - # list of strings - assert_array_equal(Axis('sex', sex_list).labels, sex_array) - # array of strings - assert_array_equal(Axis('sex', sex_array).labels, sex_array) - # single string - assert_array_equal(Axis('sex', 'H,F').labels, sex_array) - # list of ints - assert_array_equal((Axis('age', range(116))).labels, np.arange(116)) - # range-string - assert_array_equal((Axis('age', ':115')).labels, np.array(srange(116))) - - def test_equals(self): - self.assertTrue(Axis('sex', 'H,F').equals(Axis('sex', 'H,F'))) - self.assertTrue(Axis('sex', 'H,F').equals(Axis('sex', ['H', 'F']))) - self.assertFalse(Axis('sex', 'M,F').equals(Axis('sex', 'H,F'))) - self.assertFalse(Axis('sex1', 'H,F').equals(Axis('sex2', 'H,F'))) - self.assertFalse(Axis('sex1', 'M,F').equals(Axis('sex2', 'H,F'))) - - def test_group(self): - age = Axis('age', ':115') - ages_list = ['1', '5', '9'] - self.assertEqual(age.group(ages_list), LGroup(ages_list, axis=age)) - self.assertEqual(age.group(ages_list), LGroup(ages_list)) - self.assertEqual(age.group('1,5,9'), LGroup(ages_list)) - self.assertEqual(age.group('1', '5', '9'), LGroup(ages_list)) - - # with a slice string - self.assertEqual(age.group('10:20'), LGroup(slice('10', '20'))) - - # with name - group = age.group(srange(10, 20), name='teens') - self.assertEqual(group.key, srange(10, 20)) - self.assertEqual(group.name, 'teens') - self.assertIs(group.axis, age) - - # TODO: support more stuff in string groups - # arr3x = geo.group('A3*') # * match one or more chars - # arr3x = geo.group('A3?') # ? matches one char (equivalent in this case) - # arr3x = geo.seq('A31', 'A38') # not equivalent to geo['A31:A38'] ! - # # (if A22 is between A31 and A38) - - def test_getitem(self): - age = Axis('age', ':115') - vg = age.group(':17') - # these are equivalent - self.assertEqual(age[:'17'], vg) - self.assertEqual(age[':17'], vg) - - group = age[:] - self.assertEqual(group.key, slice(None)) - self.assertIs(group.axis, age) - - def test_iter(self): - self.assertEqual(list(Axis('sex', 'H,F')), ['H', 'F']) - - def test_positional(self): - age = Axis('age', ':115') - - # these are NOT equivalent (not translated until used in an LArray - # self.assertEqual(age.i[:17], age[':17']) - key = age.i[:-1] - self.assertEqual(key.key, slice(None, -1)) - self.assertIs(key.axis, age) - - def test_all(self): - age = Axis('age', ':115') - group = age.all() - self.assertEqual(group.key, slice(None)) - self.assertIs(group.axis, age) - - def test_contains(self): - # normal Axis - age = Axis('age', ':10') - - age2 = age.group('2') - age2bis = age.group('2,') - age2ter = age.group(['2']) - age2qua = '2,' - - age20 = LGroup('20') - age20bis = LGroup('20,') - age20ter = LGroup(['20']) - age20qua = '20,' - - # TODO: move assert to another test - self.assertEqual(age2bis, age2ter) - - age247 = age.group('2,4,7') - age247bis = age.group(['2', '4', '7']) - age359 = age.group(['3', '5', '9']) - age468 = age.group('4,6,8', name='even') - - self.assertFalse(5 in age) - self.assertTrue('5' in age) - - self.assertTrue(age2 in age) - # only single ticks are "contained" in the axis, not "collections" - self.assertFalse(age2bis in age) - self.assertFalse(age2ter in age) - self.assertFalse(age2qua in age) - - self.assertFalse(age20 in age) - self.assertFalse(age20bis in age) - self.assertFalse(age20ter in age) - self.assertFalse(age20qua in age) - self.assertFalse(['3', '5', '9'] in age) - self.assertFalse('3,5,9' in age) - self.assertFalse('3:9' in age) - self.assertFalse(age247 in age) - self.assertFalse(age247bis in age) - self.assertFalse(age359 in age) - self.assertFalse(age468 in age) - - # aggregated Axis - agg = Axis("agg", (age2, age247, age359, age468, - '2,6', ['3', '5', '7'], ('6', '7', '9'))) - self.assertTrue(age2 in agg) - self.assertFalse(age2bis in agg) - self.assertFalse(age2ter in agg) - self.assertFalse(age2qua in age) - - self.assertTrue(age247 in agg) - self.assertTrue(age247bis in agg) - self.assertTrue('2,4,7' in agg) - self.assertTrue(['2', '4', '7'] in agg) - - self.assertTrue(age359 in agg) - self.assertTrue('3,5,9' in agg) - self.assertTrue(['3', '5', '9'] in agg) - - self.assertTrue(age468 in agg) - self.assertTrue('4,6,8' in agg) - self.assertTrue(['4', '6', '8'] in agg) - self.assertTrue('even' in agg) - - self.assertTrue('2,6' in agg) - self.assertTrue(['2', '6'] in agg) - self.assertTrue(age.group('2,6') in agg) - self.assertTrue(age.group(['2', '6']) in agg) - - self.assertTrue('3,5,7' in agg) - self.assertTrue(['3', '5', '7'] in agg) - self.assertTrue(age.group('3,5,7') in agg) - self.assertTrue(age.group(['3', '5', '7']) in agg) - - self.assertTrue('6,7,9' in agg) - self.assertTrue(['6', '7', '9'] in agg) - self.assertTrue(age.group('6,7,9') in agg) - self.assertTrue(age.group(['6', '7', '9']) in agg) - - self.assertFalse(5 in agg) - self.assertFalse('5' in agg) - self.assertFalse(age20 in agg) - self.assertFalse(age20bis in agg) - self.assertFalse(age20ter in agg) - self.assertFalse(age20qua in agg) - self.assertFalse('2,7' in agg) - self.assertFalse(['2', '7'] in agg) - self.assertFalse(age.group('2,7') in agg) - self.assertFalse(age.group(['2', '7']) in agg) - - -class TestLGroup(TestCase): - def setUp(self): - self.age = Axis('age', ':115') - self.lipro = Axis('lipro', ['P%02d' % i for i in range(1, 10)]) - self.anonymous = Axis(None, range(3)) - - self.slice_both_named_wh_named_axis = LGroup('1:5', "full", self.age) - self.slice_both_named = LGroup('1:5', "named") - self.slice_both = LGroup('1:5') - self.slice_start = LGroup('1:') - self.slice_stop = LGroup(':5') - self.slice_none_no_axis = LGroup(':') - self.slice_none_wh_named_axis = LGroup(':', axis=self.lipro) - self.slice_none_wh_anonymous_axis = LGroup(':', axis=self.anonymous) - - self.single_value = LGroup('P03') - self.list = LGroup('P01,P03,P07') - self.list_named = LGroup('P01,P03,P07', "P137") - - def test_init(self): - self.assertEqual(self.slice_both_named_wh_named_axis.name, "full") - self.assertEqual(self.slice_both_named_wh_named_axis.key, '1:5') - self.assertEqual(self.slice_both_named.name, "named") - self.assertEqual(self.slice_both_named.key, '1:5') - self.assertEqual(self.slice_both.key, '1:5') - self.assertEqual(self.slice_start.key, '1:') - self.assertEqual(self.slice_stop.key, ':5') - self.assertEqual(self.slice_none_no_axis.key, ':') - self.assertIs(self.slice_none_wh_named_axis.axis, self.lipro) - self.assertIs(self.slice_none_wh_anonymous_axis.axis, self.anonymous) - - self.assertEqual(self.single_value.key, 'P03') - self.assertEqual(self.list.key, 'P01,P03,P07') - - def test_eq(self): - self.assertEqual(self.slice_both, self.slice_both_named_wh_named_axis) - self.assertEqual(self.slice_both, self.slice_both_named) - self.assertEqual(self.slice_both, LGroup(slice('1', '5'))) - self.assertEqual(self.slice_start, LGroup(slice('1', None))) - self.assertEqual(self.slice_stop, LGroup(slice('5'))) - self.assertEqual(self.slice_none_no_axis, LGroup(slice(None))) - self.assertEqual(self.list, LGroup(['P01', 'P03', 'P07'])) - # test with raw objects - self.assertEqual(self.slice_both, '1:5') - self.assertEqual(self.slice_start, '1:') - self.assertEqual(self.slice_stop, ':5') - self.assertEqual(self.slice_none_no_axis, ':') - self.assertEqual(self.slice_both, slice('1', '5')) - self.assertEqual(self.slice_start, slice('1', None)) - self.assertEqual(self.slice_stop, slice('5')) - self.assertEqual(self.slice_none_no_axis, slice(None)) - self.assertEqual(self.list, 'P01,P03,P07') - self.assertEqual(self.list, ' P01 , P03 , P07 ') - self.assertEqual(self.list, ['P01', 'P03', 'P07']) - self.assertEqual(self.list, ('P01', 'P03', 'P07')) - - def test_hash(self): - d = {self.slice_both: 1, - self.single_value: 2, - self.list_named: 3} - # target a LGroup with an equivalent LGroup - self.assertEqual(d.get(self.slice_both), 1) - self.assertEqual(d.get(self.single_value), 2) - self.assertEqual(d.get(self.list), 3) - self.assertEqual(d.get(self.list_named), 3) - # this cannot and will never work, because we cannot have the LGroup - # hash both like its key and like its name! - # we could make it work with a special dict class, but do we WANT to - # make it work? - # yes, probably - # self.assertEqual(d.get("P137"), 3) - - # target a LGroup with an equivalent key - self.assertEqual(d.get('1:5'), 1) - self.assertEqual(d.get('P03'), 2) - self.assertEqual(d.get('P01,P03,P07'), 3) - - # this cannot and will never work! - # hash(str) and hash(tuple) are not special, so ' P01 ,...' and - # ('P01', ...) do not hash to the same value than 'P01,P03...", which is - # our "canonical hash" - # self.assertEqual(d.get(' P01 , P03 , P07 '), 3) - # self.assertEqual(d.get(('P01', 'P03', 'P07')), 3) - - # target a simple key with an equivalent LGroup - d = {'1:5': 1, - 'P03': 2, - 'P01,P03,P07': 3} - self.assertEqual(d.get(self.slice_both), 1) - self.assertEqual(d.get(self.single_value), 2) - self.assertEqual(d.get(self.list), 3) - self.assertEqual(d.get(LGroup(' P01 , P03 , P07 ')), 3) - self.assertEqual(d.get(LGroup(('P01', 'P03', 'P07'))), 3) - - def test_str(self): - self.assertEqual(str(self.slice_both_named_wh_named_axis), - "'full' ('1':'5')") - self.assertEqual(str(self.slice_both_named), "'named' ('1':'5')") - self.assertEqual(str(self.slice_both), "'1':'5'") - self.assertEqual(str(self.slice_start), "'1':") - self.assertEqual(str(self.slice_stop), ":'5'") - self.assertEqual(str(self.slice_none_no_axis), ':') - self.assertEqual(str(self.single_value), "'P03'") - self.assertEqual(str(self.list), "['P01' ... 'P07']") - - def test_repr(self): - self.assertEqual(repr(self.slice_both_named), - "LGroup('1:5', name='named')") - self.assertEqual(repr(self.slice_both), "LGroup('1:5')") - self.assertEqual(repr(self.list), "LGroup('P01,P03,P07')") - self.assertEqual(repr(self.slice_none_no_axis), "LGroup(':')") - target = \ - "LGroup(':', axis=Axis('lipro', ['P01', 'P02', 'P03', 'P04', " \ - "'P05', 'P06', 'P07', 'P08', " \ - "'P09']))" - self.assertEqual(repr(self.slice_none_wh_named_axis), - target) - self.assertEqual(repr(self.slice_none_wh_anonymous_axis), - "LGroup(':', axis=Axis(None, [0, 1, 2]))") - - -class TestAxisCollection(TestCase): - def setUp(self): - self.lipro = Axis('lipro', ['P%02d' % i for i in range(1, 5)]) - self.sex = Axis('sex', 'H,F') - self.sex2 = Axis('sex', 'F,H') - self.age = Axis('age', ':7') - self.geo = Axis('geo', 'A11,A12,A13') - self.value = Axis('value', ':10') - self.collection = AxisCollection((self.lipro, self.sex, self.age)) - - def test_eq(self): - col = self.collection - self.assertEqual(col, col) - self.assertEqual(col, AxisCollection((self.lipro, self.sex, self.age))) - self.assertEqual(col, (self.lipro, self.sex, self.age)) - self.assertNotEqual(col, (self.lipro, self.age, self.sex)) - - def test_getitem_name(self): - col = self.collection - self.assert_axis_eq(col['lipro'], self.lipro) - self.assert_axis_eq(col['sex'], self.sex) - self.assert_axis_eq(col['age'], self.age) - - def test_getitem_int(self): - col = self.collection - self.assert_axis_eq(col[0], self.lipro) - self.assert_axis_eq(col[-3], self.lipro) - self.assert_axis_eq(col[1], self.sex) - self.assert_axis_eq(col[-2], self.sex) - self.assert_axis_eq(col[2], self.age) - self.assert_axis_eq(col[-1], self.age) - - def test_getitem_slice(self): - col = self.collection[:2] - self.assertEqual(len(col), 2) - self.assert_axis_eq(col[0], self.lipro) - self.assert_axis_eq(col[1], self.sex) - - def test_setitem_name(self): - col = self.collection[:] - # replace an axis with one with another name - col['lipro'] = self.geo - self.assertEqual(len(col), 3) - self.assertEqual(col, [self.geo, self.sex, self.age]) - # replace an axis with one with the same name - col['sex'] = self.sex2 - self.assertEqual(col, [self.geo, self.sex2, self.age]) - col['geo'] = self.lipro - self.assertEqual(col, [self.lipro, self.sex2, self.age]) - col['age'] = self.geo - self.assertEqual(col, [self.lipro, self.sex2, self.geo]) - col['sex'] = self.sex - col['geo'] = self.age - self.assertEqual(col, self.collection) - - def test_setitem_int(self): - col = self.collection[:] - col[1] = self.geo - self.assertEqual(len(col), 3) - self.assertEqual(col, [self.lipro, self.geo, self.age]) - col[2] = self.sex - self.assertEqual(col, [self.lipro, self.geo, self.sex]) - col[-1] = self.age - self.assertEqual(col, [self.lipro, self.geo, self.age]) - - def test_setitem_list_replace(self): - col = self.collection[:] - col[['lipro', 'age']] = [self.geo, self.lipro] - self.assertEqual(col, [self.geo, self.sex, self.lipro]) - - def test_setitem_slice_replace(self): - col = self.collection[:] - # replace by list - col[1:] = [self.geo, self.sex] - self.assertEqual(col, [self.lipro, self.geo, self.sex]) - # replace by collection - col[1:] = self.collection[1:] - self.assertEqual(col, self.collection) - - def test_setitem_slice_insert(self): - col = self.collection[:] - col[1:1] = [self.geo] - self.assertEqual(col, [self.lipro, self.geo, self.sex, self.age]) - - def test_setitem_slice_delete(self): - col = self.collection[:] - col[1:2] = [] - self.assertEqual(col, [self.lipro, self.age]) - col[0:1] = [] - self.assertEqual(col, [self.age]) - - def assert_axis_eq(self, axis1, axis2): - self.assertTrue(axis1.equals(axis2)) - - def test_delitem(self): - col = self.collection[:] - self.assertEqual(len(col), 3) - del col[0] - self.assertEqual(len(col), 2) - self.assert_axis_eq(col[0], self.sex) - self.assert_axis_eq(col[1], self.age) - del col['age'] - self.assertEqual(len(col), 1) - self.assert_axis_eq(col[0], self.sex) - del col[self.sex] - self.assertEqual(len(col), 0) - - def test_delitem_slice(self): - col = self.collection[:] - self.assertEqual(len(col), 3) - del col[0:2] - self.assertEqual(len(col), 1) - self.assertEqual(col, [self.age]) - del col[:] - self.assertEqual(len(col), 0) - - def test_pop(self): - col = self.collection[:] - lipro, sex, age = col - self.assertEqual(len(col), 3) - self.assertIs(col.pop(), age) - self.assertEqual(len(col), 2) - self.assertIs(col[0], lipro) - self.assertIs(col[1], sex) - self.assertIs(col.pop(), sex) - self.assertEqual(len(col), 1) - self.assertIs(col[0], lipro) - self.assertIs(col.pop(), lipro) - self.assertEqual(len(col), 0) - - def test_replace(self): - col = self.collection[:] - newcol = col.replace('sex', self.geo) - # original collection is not modified - self.assertEqual(col, self.collection) - self.assertEqual(len(newcol), 3) - self.assertEqual(newcol.names, ['lipro', 'geo', 'age']) - newcol = newcol.replace(self.geo, self.sex) - self.assertEqual(len(newcol), 3) - self.assertEqual(newcol.names, ['lipro', 'sex', 'age']) - - def test_replace_multiple(self): - col = self.collection.replace(['lipro', 'age'], [self.geo, self.lipro]) - self.assertEqual(col, [self.geo, self.sex, self.lipro]) - - # TODO: add contains_test (using both axis name and axis objects) - def test_get(self): - col = self.collection - self.assert_axis_eq(col.get('lipro'), self.lipro) - self.assertIsNone(col.get('nonexisting')) - self.assertIs(col.get('nonexisting', self.value), self.value) - - def test_keys(self): - self.assertEqual(self.collection.keys(), ['lipro', 'sex', 'age']) - - def test_getattr(self): - col = self.collection - self.assert_axis_eq(col.lipro, self.lipro) - self.assert_axis_eq(col.sex, self.sex) - self.assert_axis_eq(col.age, self.age) - - def test_append(self): - col = self.collection - geo = Axis('geo', 'A11,A12,A13') - col.append(geo) - self.assertEqual(col, [self.lipro, self.sex, self.age, geo]) - - def test_extend(self): - col = self.collection - col.extend([self.geo, self.value]) - self.assertEqual(col, - [self.lipro, self.sex, self.age, self.geo, self.value]) - - def test_insert(self): - col = self.collection - col.insert(1, self.geo) - self.assertEqual(col, [self.lipro, self.geo, self.sex, self.age]) - - def test_add(self): - col = self.collection.copy() - lipro, sex, age = self.lipro, self.sex, self.age - geo, value = self.geo, self.value - - # 1) list - # a) no dupe - new = col + [self.geo, value] - self.assertEqual(new, [lipro, sex, age, geo, value]) - # check the original has not been modified - self.assertEqual(col, self.collection) - - # b) with compatible dupe - # the "new" age axis is ignored (because it is compatible) - new = col + [Axis('geo', 'A11,A12,A13'), Axis('age', ':7')] - self.assertEqual(new, [lipro, sex, age, geo]) - - # c) with incompatible dupe - # XXX: the "new" age axis is ignored. We might want to ignore it if it - # is the same but raise an exception if it is different - # new = col + [Axis('geo', 'A11,A12,A13'), Axis('age', ':6')] - self.assertRaises(ValueError, col.__add__, - [Axis('geo', 'A11,A12,A13'), Axis('age', ':6')]) - - # 2) other AxisCollection - new = col + AxisCollection([geo, value]) - self.assertEqual(new, [lipro, sex, age, geo, value]) - - def test_str(self): - self.assertEqual(str(self.collection), "{lipro, sex, age}") - - def test_repr(self): - self.assertEqual(repr(self.collection), """AxisCollection([ - Axis('lipro', ['P01', 'P02', 'P03', 'P04']), - Axis('sex', ['H', 'F']), - Axis('age', ['0', '1', '2', '3', '4', '5', '6', '7']) -])""") - - -class TestLArray(TestCase): - def setUp(self): - self.lipro = Axis('lipro', ['P%02d' % i for i in range(1, 16)]) - self.age = Axis('age', ':115') - self.sex = Axis('sex', 'H,F') - - vla = 'A11,A12,A13,A23,A24,A31,A32,A33,A34,A35,A36,A37,A38,A41,A42,' \ - 'A43,A44,A45,A46,A71,A72,A73' - wal = 'A25,A51,A52,A53,A54,A55,A56,A57,A61,A62,A63,A64,A65,A81,A82,' \ - 'A83,A84,A85,A91,A92,A93' - bru = 'A21' - self.vla_str = vla - self.wal_str = wal - # string without commas - self.bru_str = bru - # list of strings - self.belgium = union(vla, wal, bru) - - # belgium = vla + wal + bru # equivalent - # wal_bru = belgium - vla - # wal_bru = wal + bru # equivalent - - self.geo = Axis('geo', self.belgium) - - self.array = np.arange(116 * 44 * 2 * 15).reshape(116, 44, 2, 15) \ - .astype(float) - self.larray = LArray(self.array, - axes=(self.age, self.geo, self.sex, self.lipro)) - - self.small_data = np.arange(30).reshape(2, 15) - self.small = LArray(self.small_data, axes=(self.sex, self.lipro)) - - def test_zeros(self): - la = zeros((self.geo, self.age)) - self.assertEqual(la.shape, (44, 116)) - assert_array_equal(la, np.zeros((44, 116))) - - def test_zeros_like(self): - la = zeros_like(self.larray) - self.assertEqual(la.shape, (116, 44, 2, 15)) - assert_array_equal(la, np.zeros((116, 44, 2, 15))) - - def test_bool(self): - a = ones([2]) - # ValueError: The truth value of an array with more than one element - # is ambiguous. Use a.any() or a.all() - self.assertRaises(ValueError, bool, a) - - a = ones([1]) - self.assertTrue(bool(a)) - - a = zeros([1]) - self.assertFalse(bool(a)) - - a = LArray(np.array(2), []) - self.assertTrue(bool(a)) - - a = LArray(np.array(0), []) - self.assertFalse(bool(a)) - - def test_iter(self): - array = self.small - l = list(array) - assert_array_equal(l[0], array['H']) - assert_array_equal(l[1], array['F']) - - def test_rename(self): - la = self.larray - new = la.rename('sex', 'gender') - # old array axes names not modified - self.assertEqual(la.axes.names, ['age', 'geo', 'sex', 'lipro']) - self.assertEqual(new.axes.names, ['age', 'geo', 'gender', 'lipro']) - - new = la.rename(self.sex, 'gender') - # old array axes names not modified - self.assertEqual(la.axes.names, ['age', 'geo', 'sex', 'lipro']) - self.assertEqual(new.axes.names, ['age', 'geo', 'gender', 'lipro']) - - def test_info(self): - expected = """\ -116 x 44 x 2 x 15 - age [116]: '0' '1' '2' ... '113' '114' '115' - geo [44]: 'A11' 'A12' 'A13' ... 'A92' 'A93' 'A21' - sex [2]: 'H' 'F' - lipro [15]: 'P01' 'P02' 'P03' ... 'P13' 'P14' 'P15'""" - self.assertEqual(self.larray.info, expected) - - def test_str(self): - lipro = self.lipro - lipro3 = lipro['P01:P03'] - sex = self.sex - - # zero dimension / scalar - self.assertEqual(str(self.small[lipro['P01'], sex['F']]), "15") - - # empty / len 0 first dimension - self.assertEqual(str(self.small[sex[[]]]), "LArray([])") - - # one dimension - self.assertEqual(str(self.small[lipro3, sex['H']]), """\ -lipro | P01 | P02 | P03 - | 0 | 1 | 2""") - # two dimensions - self.assertEqual(str(self.small.filter(lipro=lipro3)), """\ -sex\lipro | P01 | P02 | P03 - H | 0 | 1 | 2 - F | 15 | 16 | 17""") - # four dimensions (too many rows) - self.assertEqual(str(self.larray.filter(lipro=lipro3)), """\ -age | geo | sex\lipro | P01 | P02 | P03 - 0 | A11 | H | 0.0 | 1.0 | 2.0 - 0 | A11 | F | 15.0 | 16.0 | 17.0 - 0 | A12 | H | 30.0 | 31.0 | 32.0 - 0 | A12 | F | 45.0 | 46.0 | 47.0 - 0 | A13 | H | 60.0 | 61.0 | 62.0 -... | ... | ... | ... | ... | ... -115 | A92 | F | 153045.0 | 153046.0 | 153047.0 -115 | A93 | H | 153060.0 | 153061.0 | 153062.0 -115 | A93 | F | 153075.0 | 153076.0 | 153077.0 -115 | A21 | H | 153090.0 | 153091.0 | 153092.0 -115 | A21 | F | 153105.0 | 153106.0 | 153107.0""") - # four dimensions (too many rows and columns) - self.assertEqual(str(self.larray), """\ -age | geo | sex\lipro | P01 | P02 | ... | P14 | P15 - 0 | A11 | H | 0.0 | 1.0 | ... | 13.0 | 14.0 - 0 | A11 | F | 15.0 | 16.0 | ... | 28.0 | 29.0 - 0 | A12 | H | 30.0 | 31.0 | ... | 43.0 | 44.0 - 0 | A12 | F | 45.0 | 46.0 | ... | 58.0 | 59.0 - 0 | A13 | H | 60.0 | 61.0 | ... | 73.0 | 74.0 -... | ... | ... | ... | ... | ... | ... | ... -115 | A92 | F | 153045.0 | 153046.0 | ... | 153058.0 | 153059.0 -115 | A93 | H | 153060.0 | 153061.0 | ... | 153073.0 | 153074.0 -115 | A93 | F | 153075.0 | 153076.0 | ... | 153088.0 | 153089.0 -115 | A21 | H | 153090.0 | 153091.0 | ... | 153103.0 | 153104.0 -115 | A21 | F | 153105.0 | 153106.0 | ... | 153118.0 | 153119.0""") - - def test_getitem(self): - raw = self.array - la = self.larray - age, geo, sex, lipro = la.axes - age159 = age['1,5,9'] - lipro159 = lipro['P01,P05,P09'] - - # LGroup at "correct" place - subset = la[age159] - self.assertEqual(subset.axes[1:], (geo, sex, lipro)) - self.assertTrue(subset.axes[0].equals(Axis('age', ['1', '5', '9']))) - assert_array_equal(subset, raw[[1, 5, 9]]) - - # LGroup at "incorrect" place - assert_array_equal(la[lipro159], raw[..., [0, 4, 8]]) - - # multiple LGroup key (in "incorrect" order) - assert_array_equal(la[lipro159, age159], - raw[[1, 5, 9]][..., [0, 4, 8]]) - - # mixed LGroup/positional key - assert_array_equal(la['1,5,9', lipro159], - raw[[1, 5, 9]][..., [0, 4, 8]]) - - # single None slice - assert_array_equal(la[:], raw) - - # only Ellipsis - assert_array_equal(la[...], raw) - - # Ellipsis and VG - assert_array_equal(la[..., lipro159], raw[..., [0, 4, 8]]) - - # key with duplicate axes - # la[[1, 5, 9], age['1,5,9']] - self.assertRaises(ValueError, la.__getitem__, ([1, 5], age['1,5'])) - - def test_getitem_abstract_axes(self): - raw = self.array - la = self.larray - age, geo, sex, lipro = la.axes - age159 = x.age['1,5,9'] - lipro159 = x.lipro['P01,P05,P09'] - - # LGroup at "correct" place - subset = la[age159] - self.assertEqual(subset.axes[1:], (geo, sex, lipro)) - self.assertTrue(subset.axes[0].equals(Axis('age', ['1', '5', '9']))) - assert_array_equal(subset, raw[[1, 5, 9]]) - - # LGroup at "incorrect" place - assert_array_equal(la[lipro159], raw[..., [0, 4, 8]]) - - # multiple LGroup key (in "incorrect" order) - assert_array_equal(la[lipro159, age159], - raw[[1, 5, 9]][..., [0, 4, 8]]) - - # mixed LGroup/positional key - assert_array_equal(la['1,5,9', lipro159], - raw[[1, 5, 9]][..., [0, 4, 8]]) - - # single None slice - assert_array_equal(la[:], raw) - - # only Ellipsis - assert_array_equal(la[...], raw) - - # Ellipsis and VG - assert_array_equal(la[..., lipro159], raw[..., [0, 4, 8]]) - - # key with duplicate axes - # la[[1, 5, 9], age['1,5,9']] - self.assertRaises(ValueError, la.__getitem__, ([1, 5], x.age['1,5'])) - - def test_getitem_anonymous_axes(self): - la = ndrange((3, 4)) - raw = la.data - assert_array_equal(la[x[0][1:]], raw[1:]) - assert_array_equal(la[x[1][2:]], raw[:, 2:]) - assert_array_equal(la[x[0][2:], x[1][1:]], raw[2:, 1:]) - assert_array_equal(la.i[2:, 1:], raw[2:, 1:]) - - def test_getitem_guess_axis(self): - raw = self.array - la = self.larray - age, geo, sex, lipro = la.axes - - # key at "correct" place - assert_array_equal(la[['1', '5', '9']], raw[[1, 5, 9]]) - subset = la['1,5,9'] - self.assertEqual(subset.axes[1:], (geo, sex, lipro)) - self.assertTrue(subset.axes[0].equals(Axis('age', ['1', '5', '9']))) - assert_array_equal(subset, raw[[1, 5, 9]]) - - # key at "incorrect" place - assert_array_equal(la['P01,P05,P09'], raw[..., [0, 4, 8]]) - assert_array_equal(la[['P01', 'P05', 'P09']], raw[..., [0, 4, 8]]) - - # multiple keys (in "incorrect" order) - assert_array_equal(la['P01,P05,P09', '1,5,9'], - raw[[1, 5, 9]][..., [0, 4, 8]]) - - # mixed LGroup/key - assert_array_equal(la[lipro['P01,P05,P09'], '1,5,9'], - raw[[1, 5, 9]][..., [0, 4, 8]]) - - # single None slice - assert_array_equal(la[:], raw) - - # only Ellipsis - assert_array_equal(la[...], raw) - - # Ellipsis and VG - assert_array_equal(la[..., 'P01,P05,P09'], raw[..., [0, 4, 8]]) - assert_array_equal(la[..., ['P01', 'P05', 'P09']], - raw[..., [0, 4, 8]]) - - # key with duplicate axes - # la[[1, 5, 9], age['1,5,9']] - self.assertRaises(ValueError, la.__getitem__, ([1, 5], x.age['1,5'])) - - def test_getitem_positional_group(self): - raw = self.array - la = self.larray - age, geo, sex, lipro = la.axes - age159 = age.i[1, 5, 9] - lipro159 = lipro.i[0, 4, 8] - - # LGroup at "correct" place - subset = la[age159] - self.assertEqual(subset.axes[1:], (geo, sex, lipro)) - self.assertTrue(subset.axes[0].equals(Axis('age', ['1', '5', '9']))) - assert_array_equal(subset, raw[[1, 5, 9]]) - - # LGroup at "incorrect" place - assert_array_equal(la[lipro159], raw[..., [0, 4, 8]]) - - # multiple LGroup key (in "incorrect" order) - assert_array_equal(la[lipro159, age159], - raw[[1, 5, 9]][..., [0, 4, 8]]) - - # mixed LGroup/positional key - assert_array_equal(la['1,5,9', lipro159], - raw[[1, 5, 9]][..., [0, 4, 8]]) - - # single None slice - assert_array_equal(la[:], raw) - - # only Ellipsis - assert_array_equal(la[...], raw) - - # Ellipsis and VG - assert_array_equal(la[..., lipro159], raw[..., [0, 4, 8]]) - - # key with duplicate axes - # la[[1, 5, 9], age['1,5,9']] - self.assertRaises(ValueError, la.__getitem__, ([1, 5], age.i[1, 5])) - - def test_getitem_abstract_positional(self): - raw = self.array - la = self.larray - age, geo, sex, lipro = la.axes - age159 = x.age.i[1, 5, 9] - lipro159 = x.lipro.i[0, 4, 8] - - # LGroup at "correct" place - subset = la[age159] - self.assertEqual(subset.axes[1:], (geo, sex, lipro)) - self.assertTrue(subset.axes[0].equals(Axis('age', ['1', '5', '9']))) - assert_array_equal(subset, raw[[1, 5, 9]]) - - # LGroup at "incorrect" place - assert_array_equal(la[lipro159], raw[..., [0, 4, 8]]) - - # multiple LGroup key (in "incorrect" order) - assert_array_equal(la[lipro159, age159], - raw[[1, 5, 9]][..., [0, 4, 8]]) - - # mixed LGroup/positional key - assert_array_equal(la['1,5,9', lipro159], - raw[[1, 5, 9]][..., [0, 4, 8]]) - - # single None slice - assert_array_equal(la[:], raw) - - # only Ellipsis - assert_array_equal(la[...], raw) - - # Ellipsis and VG - assert_array_equal(la[..., lipro159], raw[..., [0, 4, 8]]) - - # key with duplicate axes - # la[[1, 5, 9], age['1,5,9']] - self.assertRaises(ValueError, la.__getitem__, ([1, 5], x.age.i[1, 5])) - - def test_getitem_bool_larray_key(self): - raw = self.array - la = self.larray - - # all dimensions - res = la[la < 5] - self.assertTrue(isinstance(res, LArray)) - self.assertEqual(res.ndim, 1) - assert_array_equal(res, raw[raw < 5]) - - # missing dimension - res = la[la['H'] % 5 == 0] - self.assertTrue(isinstance(res, LArray)) - self.assertEqual(res.ndim, 2) - self.assertEqual(res.shape, (116 * 44 * 15 / 5, 2)) - raw_key = raw[:, :, 0, :] % 5 == 0 - raw_d1, raw_d2, raw_d4 = raw_key.nonzero() - assert_array_equal(res, raw[raw_d1, raw_d2, :, raw_d4]) - - def test_getitem_bool_ndarray_key(self): - raw = self.array - la = self.larray - - res = la[raw < 5] - self.assertTrue(isinstance(res, LArray)) - self.assertEqual(res.ndim, 1) - assert_array_equal(res, raw[raw < 5]) - - def test_getitem_bool_anonymous_axes(self): - a = ndrange((2, 3, 4, 5)) - mask = ones(a.axes[1, 3], dtype=bool) - res = a[mask] - self.assertEqual(res.ndim, 3) - self.assertEqual(res.shape, (15, 2, 4)) - - # XXX: we might want to transpose the result to always move - # combined axes to the front - a = ndrange((2, 3, 4, 5)) - mask = ones(a.axes[1, 2], dtype=bool) - res = a[mask] - self.assertEqual(res.ndim, 3) - self.assertEqual(res.shape, (2, 12, 5)) - - def test_getitem_int_larray_lgroup_key(self): - # e axis go from 0 to 3 - arr = ndrange((2, 2, 4)).rename(0, 'c').rename(1, 'd').rename(2, 'e') - # key values go from 0 to 3 - key = ndrange((2, 2)).rename(0, 'a').rename(1, 'b') - # this replaces 'e' axis by 'a' and 'b' axes - res = arr[x.e[key]] - self.assertEqual(res.shape, (2, 2, 2, 2)) - self.assertEqual(res.axes.names, ['c', 'd', 'a', 'b']) - - - def test_getitem_larray_key_guess(self): - a = Axis('a', ['a1', 'a2']) - b = Axis('b', ['b1', 'b2']) - c = Axis('c', ['c1', 'c2']) - d = Axis('d', ['d1', 'd2']) - e = Axis('e', ['e1', 'e2', 'e3', 'e4']) - - arr = ndrange([c, d, e]) - key = LArray([['e1', 'e2'], ['e3', 'e4']], [a, b]) - self.assertEqual(arr[key].axes, [c, d, a, b]) - - def test_getitem_ndarray_key_guess(self): - raw = self.array - la = self.larray - keys = ['P04', 'P01', 'P03', 'P02'] - key = np.array(keys) - res = la[key] - self.assertTrue(isinstance(res, LArray)) - self.assertEqual(res.axes, - la.axes.replace(x.lipro, Axis('lipro', keys))) - assert_array_equal(res, raw[:, :, :, [3, 0, 2, 1]]) - - def test_getitem_int_larray_key_guess(self): - a = Axis('a', [0, 1]) - b = Axis('b', [2, 3]) - c = Axis('c', [4, 5]) - d = Axis('d', [6, 7]) - e = Axis('e', [8, 9, 10, 11]) - - arr = ndrange([c, d, e]) - key = LArray([[8, 9], [10, 11]], [a, b]) - self.assertEqual(arr[key].axes, [c, d, a, b]) - - def test_getitem_int_ndarray_key_guess(self): - c = Axis('c', [4, 5]) - d = Axis('d', [6, 7]) - e = Axis('e', [8, 9, 10, 11]) - - arr = ndrange([c, d, e]) - # ND keys do not work yet - # key = np.array([[8, 11], [10, 9]]) - key = np.array([8, 11, 10]) - res = arr[key] - self.assertEqual(res.axes, [c, d, Axis('e', [8, 11, 10])]) - - def test_positional_indexer_getitem(self): - raw = self.array - la = self.larray - for key in [0, (0, 5, 1, 2), (slice(None), 5, 1), (0, 5), [1, 0], - ([1, 0], 5)]: - assert_array_equal(la.i[key], raw[key]) - assert_array_equal(la.i[[1, 0], [5, 4]], raw[np.ix_([1, 0], [5, 4])]) - self.assertRaises(IndexError, la.i.__getitem__, (0, 0, 0, 0, 0)) - - def test_positional_indexer_setitem(self): - for key in [0, (0, 2, 1, 2), (slice(None), 2, 1), (0, 2), [1, 0], - ([1, 0], 2)]: - la = self.larray.copy() - raw = self.array.copy() - la.i[key] = 42 - raw[key] = 42 - assert_array_equal(la, raw) - - la = self.larray.copy() - raw = self.array.copy() - la.i[[1, 0], [5, 4]] = 42 - raw[np.ix_([1, 0], [5, 4])] = 42 - assert_array_equal(la, raw) - - def test_setitem_larray(self): - """ - tests LArray.__setitem__(key, value) where value is an LArray - """ - age, geo, sex, lipro = self.larray.axes - - # 1) using a LGroup key - ages1_5_9 = age['1,5,9'] - - # a) value has exactly the same shape as the target slice - la = self.larray.copy() - raw = self.array.copy() - - la[ages1_5_9] = la[ages1_5_9] + 25.0 - raw[[1, 5, 9]] = raw[[1, 5, 9]] + 25.0 - assert_array_equal(la, raw) - - # b) value has exactly the same shape but VG at a "wrong" positions - la = self.larray.copy() - la[geo[:], ages1_5_9] = la[ages1_5_9] + 25.0 - # same raw as previous test - assert_array_equal(la, raw) - - # c) value has an extra length-1 axis - la = self.larray.copy() - raw = self.array.copy() - - raw_value = raw[[1, 5, 9], np.newaxis] + 26.0 - fake_axis = Axis('fake', ['label']) - age_axis = la[ages1_5_9].axes.age - value = LArray(raw_value, axes=(age_axis, fake_axis, self.geo, self.sex, - self.lipro)) - la[ages1_5_9] = value - raw[[1, 5, 9]] = raw[[1, 5, 9]] + 26.0 - assert_array_equal(la, raw) - - # d) value has the same axes than target but one has length 1 - # la = self.larray.copy() - # raw = self.array.copy() - # raw[[1, 5, 9]] = np.sum(raw[[1, 5, 9]], axis=1, keepdims=True) - # la[ages1_5_9] = la[ages1_5_9].sum(geo=(geo.all(),)) - # assert_array_equal(la, raw) - - # e) value has a missing dimension - la = self.larray.copy() - raw = self.array.copy() - la[ages1_5_9] = la[ages1_5_9].sum(geo) - raw[[1, 5, 9]] = np.sum(raw[[1, 5, 9]], axis=1, keepdims=True) - assert_array_equal(la, raw) - - # 2) using a string key - la = self.larray.copy() - raw = self.array.copy() - la['1,5,9'] = la['2,7,3'] + 27.0 - raw[[1, 5, 9]] = raw[[2, 7, 3]] + 27.0 - assert_array_equal(la, raw) - - # 3) using ellipsis keys - # only Ellipsis - la = self.larray.copy() - la[...] = 0 - assert_array_equal(la, np.zeros_like(raw)) - - # Ellipsis and VG - la = self.larray.copy() - raw = self.array.copy() - la[..., lipro['P01,P05,P09']] = 0 - raw[..., [0, 4, 8]] = 0 - assert_array_equal(la, raw) - - # 4) using a single slice(None) key - la = self.larray.copy() - la[:] = 0 - assert_array_equal(la, np.zeros_like(raw)) - - def test_setitem_ndarray(self): - """ - tests LArray.__setitem__(key, value) where value is a raw ndarray. - In that case, value.shape is more restricted as we rely on - numpy broadcasting. - """ - # a) value has exactly the same shape as the target slice - la = self.larray.copy() - raw = self.array.copy() - value = raw[[1, 5, 9]] + 25.0 - la['1,5,9'] = value - raw[[1, 5, 9]] = value - assert_array_equal(la, raw) - - # b) value has the same axes than target but one has length 1 - la = self.larray.copy() - raw = self.array.copy() - value = np.sum(raw[[1, 5, 9]], axis=1, keepdims=True) - la['1,5,9'] = value - raw[[1, 5, 9]] = value - assert_array_equal(la, raw) - - def test_setitem_scalar(self): - """ - tests LArray.__setitem__(key, value) where value is a scalar - """ - # a) list key (one dimension) - la = self.larray.copy() - raw = self.array.copy() - la[['1', '5', '9']] = 42 - raw[[1, 5, 9]] = 42 - assert_array_equal(la, raw) - - # b) full scalar key (ie set one cell) - la = self.larray.copy() - raw = self.array.copy() - la['0', 'P02', 'A12', 'H'] = 42 - raw[0, 1, 0, 1] = 42 - assert_array_equal(la, raw) - - def test_setitem_bool_array_key(self): - # XXX: this test is awfully slow (more than 1s) - age, geo, sex, lipro = self.larray.axes - - # LArray key - # a1) same shape, same order - la = self.larray.copy() - raw = self.array.copy() - la[la < 5] = 0 - raw[raw < 5] = 0 - assert_array_equal(la, raw) - - # a2) same shape, different order - la = self.larray.copy() - raw = self.array.copy() - key = (la < 5).T - la[key] = 0 - raw[raw < 5] = 0 - assert_array_equal(la, raw) - - # b) numpy-broadcastable shape - # la = self.larray.copy() - # raw = self.array.copy() - # key = la[sex['F,']] < 5 - # self.assertEqual(key.ndim, 4) - # la[key] = 0 - # raw[raw[:, :, [1]] < 5] = 0 - # assert_array_equal(la, raw) - - # c) LArray-broadcastable shape (missing axis) - la = self.larray.copy() - raw = self.array.copy() - key = la[sex['H']] < 5 - self.assertEqual(key.ndim, 3) - la[key] = 0 - - raw_key = raw[:, :, 0, :] < 5 - raw_d1, raw_d2, raw_d4 = raw_key.nonzero() - raw[raw_d1, raw_d2, :, raw_d4] = 0 - assert_array_equal(la, raw) - - # ndarray key - la = self.larray.copy() - raw = self.array.copy() - la[raw < 5] = 0 - raw[raw < 5] = 0 - assert_array_equal(la, raw) - - # d) LArray with extra axes - la = self.larray.copy() - raw = self.array.copy() - key = (la < 5).expand([Axis('extra', 2)]) - self.assertEqual(key.ndim, 5) - # TODO: make this work - self.assertRaises(ValueError, la.__setitem__, key, 0) - - def test_set(self): - age, geo, sex, lipro = self.larray.axes - - # 1) using a LGroup key - ages1_5_9 = age.group('1,5,9') - - # a) value has exactly the same shape as the target slice - la = self.larray.copy() - raw = self.array.copy() - - la.set(la[ages1_5_9] + 25.0, age=ages1_5_9) - raw[[1, 5, 9]] = raw[[1, 5, 9]] + 25.0 - assert_array_equal(la, raw) - - # b) same size but a different shape (extra length-1 axis) - la = self.larray.copy() - raw = self.array.copy() - - raw_value = raw[[1, 5, 9], np.newaxis] + 26.0 - fake_axis = Axis('fake', ['label']) - age_axis = la[ages1_5_9].axes.age - value = LArray(raw_value, axes=(age_axis, fake_axis, self.geo, self.sex, - self.lipro)) - la.set(value, age=ages1_5_9) - raw[[1, 5, 9]] = raw[[1, 5, 9]] + 26.0 - assert_array_equal(la, raw) - - # dimension of length 1 - # la = self.larray.copy() - # raw = self.array.copy() - # raw[[1, 5, 9]] = np.sum(raw[[1, 5, 9]], axis=1, keepdims=True) - # la.set(la[ages1_5_9].sum(geo=(geo.all(),)), age=ages1_5_9) - # assert_array_equal(la, raw) - - # c) missing dimension - la = self.larray.copy() - raw = self.array.copy() - la.set(la[ages1_5_9].sum(geo), age=ages1_5_9) - raw[[1, 5, 9]] = np.sum(raw[[1, 5, 9]], axis=1, keepdims=True) - assert_array_equal(la, raw) - - # 2) using a string key - la = self.larray.copy() - raw = self.array.copy() - la.set(la['2,7,3'] + 27.0, age='1,5,9') - raw[[1, 5, 9]] = raw[[2, 7, 3]] + 27.0 - assert_array_equal(la, raw) - - def test_filter(self): - la = self.larray - age, geo, sex, lipro = la.axes - - ages1_5_9 = age.group('1,5,9') - ages11 = age.group('11') - - # with LGroup - self.assertEqual(la.filter(age=ages1_5_9).shape, (3, 44, 2, 15)) - - # FIXME: this should raise a comprehensible error! - # self.assertEqual(la.filter(age=[ages1_5_9]).shape, (3, 44, 2, 15)) - - # VG with 1 value => collapse - self.assertEqual(la.filter(age=ages11).shape, (44, 2, 15)) - - # VG with a list of 1 value => do not collapse - self.assertEqual(la.filter(age=age.group(['11'])).shape, (1, 44, 2, 15)) - - # VG with a list of 1 value defined as a string => do not collapse - self.assertEqual(la.filter(age=age.group('11,')).shape, (1, 44, 2, 15)) - - # VG with 1 value - # XXX: this does not work. Do we want to make this work? - # filtered = la.filter(age=(ages11,)) - # self.assertEqual(filtered.shape, (1, 44, 2, 15)) - - # list - self.assertEqual(la.filter(age=['1', '5', '9']).shape, (3, 44, 2, 15)) - - # string - self.assertEqual(la.filter(age='1,5,9').shape, (3, 44, 2, 15)) - - # multiple axes at once - self.assertEqual(la.filter(age='1,5,9', lipro='P01,P02').shape, - (3, 44, 2, 2)) - - # multiple axes one after the other - self.assertEqual((la.filter(age='1,5,9').filter(lipro='P01,P02')).shape, - (3, 44, 2, 2)) - - # a single value for one dimension => collapse the dimension - self.assertEqual(la.filter(sex='H').shape, (116, 44, 15)) - - # but a list with a single value for one dimension => do not collapse - self.assertEqual(la.filter(sex=['H']).shape, (116, 44, 1, 15)) - - self.assertEqual(la.filter(sex='H,').shape, (116, 44, 1, 15)) - - # with duplicate keys - # XXX: do we want to support this? I don't see any value in that but - # I might be short-sighted. - # filtered = la.filter(lipro='P01,P02,P01') - - # XXX: we could abuse python to allow naming groups via Axis.__getitem__ - # (but I doubt it is a good idea). - # child = age[':17', 'child'] - - # slices - # ------ - - # VG slice - self.assertEqual(la.filter(age=age[':17']).shape, (18, 44, 2, 15)) - # string slice - self.assertEqual(la.filter(age=':17').shape, (18, 44, 2, 15)) - # raw slice - self.assertEqual(la.filter(age=slice('17')).shape, (18, 44, 2, 15)) - - # filter chain with a slice - self.assertEqual(la.filter(age=':17').filter(geo='A12,A13').shape, - (18, 2, 2, 15)) - - def test_filter_multiple_axes(self): - la = self.larray - - # multiple values in each group - self.assertEqual(la.filter(age='1,5,9', lipro='P01,P02').shape, - (3, 44, 2, 2)) - # with a group of one value - self.assertEqual(la.filter(age='1,5,9', sex='H,').shape, (3, 44, 1, 15)) - - # with a discarded axis (there is a scalar in the key) - self.assertEqual(la.filter(age='1,5,9', sex='H').shape, (3, 44, 15)) - - # with a discarded axis that is not adjacent to the ix_array axis - # ie with a sliced axis between the scalar axis and the ix_array axis - # since our array has a axes: age, geo, sex, lipro, any of the - # following should be tested: age+sex / age+lipro / geo+lipro - # additionally, if the ix_array axis was first (ie ix_array on age), - # it worked even before the issue was fixed, since the "indexing" - # subspace is tacked-on to the beginning (as the first dimension) - self.assertEqual(la.filter(age='57', sex='H,F').shape, - (44, 2, 15)) - self.assertEqual(la.filter(age='57', lipro='P01,P05').shape, - (44, 2, 2)) - self.assertEqual(la.filter(geo='A57', lipro='P01,P05').shape, - (116, 2, 2)) - - def test_sum_full_axes(self): - la = self.larray - age, geo, sex, lipro = la.axes - - # everything - self.assertEqual(la.sum(), np.asarray(la).sum()) - - # using axes numbers - self.assertEqual(la.sum(axis=2).shape, (116, 44, 15)) - self.assertEqual(la.sum(axis=(0, 2)).shape, (44, 15)) - - # using Axis objects - self.assertEqual(la.sum(age).shape, (44, 2, 15)) - self.assertEqual(la.sum(age, sex).shape, (44, 15)) - - # using axes names - self.assertEqual(la.sum('age', 'sex').shape, (44, 15)) - - # chained sum - self.assertEqual(la.sum(age, sex).sum(geo).shape, (15,)) - self.assertEqual(la.sum(age, sex).sum(lipro, geo), la.sum()) - - # getitem on aggregated - aggregated = la.sum(age, sex) - self.assertEqual(aggregated[self.vla_str].shape, (22, 15)) - - # filter on aggregated - self.assertEqual(aggregated.filter(geo=self.vla_str).shape, (22, 15)) - - def test_sum_full_axes_with_nan(self): - la = self.larray.copy() - la['H', 'P02', 'A12', '0'] = np.nan - raw = la.data - - # everything - self.assertEqual(la.sum(), np.nansum(raw)) - self.assertTrue(isnan(la.sum(skipna=False))) - - # using Axis objects - assert_array_nan_equal(la.sum(x.age), np.nansum(raw, 0)) - assert_array_nan_equal(la.sum(x.age, skipna=False), raw.sum(0)) - - assert_array_nan_equal(la.sum(x.age, x.sex), np.nansum(raw, (0, 2))) - assert_array_nan_equal(la.sum(x.age, x.sex, skipna=False), - raw.sum((0, 2))) - - def test_sum_full_axes_keep_axes(self): - la = self.larray - agg = la.sum(keepaxes=True) - self.assertEqual(agg.shape, (1, 1, 1, 1)) - for axis in agg.axes: - self.assertEqual(axis.labels, ['sum']) - - agg = la.sum(keepaxes='total') - self.assertEqual(agg.shape, (1, 1, 1, 1)) - for axis in agg.axes: - self.assertEqual(axis.labels, ['total']) - - def test_mean_full_axes(self): - la = self.larray - raw = self.array - - self.assertEqual(la.mean(), np.mean(raw)) - assert_array_nan_equal(la.mean(x.age), np.mean(raw, 0)) - assert_array_nan_equal(la.mean(x.age, x.sex), np.mean(raw, (0, 2))) - - def test_mean_groups(self): - # using int type to test that we get a float in return - la = self.larray.astype(int) - raw = self.array - res = la.mean(x.geo['A11', 'A13', 'A24', 'A31']) - assert_array_nan_equal(res, np.mean(raw[:, [0, 2, 4, 5]], 1)) - - def test_median_full_axes(self): - la = self.larray - raw = self.array - - self.assertEqual(la.median(), np.median(raw)) - assert_array_nan_equal(la.median(x.age), np.median(raw, 0)) - assert_array_nan_equal(la.median(x.age, x.sex), np.median(raw, (0, 2))) - - def test_median_groups(self): - la = self.larray - raw = self.array - - res = la.median(x.geo['A11', 'A13', 'A24']) - self.assertEqual(res.shape, (116, 2, 15)) - assert_array_nan_equal(res, np.median(raw[:, [0, 2, 4]], 1)) - - def test_percentile_full_axes(self): - la = self.larray - raw = self.array - - self.assertEqual(la.percentile(10), - np.percentile(raw, 10)) - assert_array_nan_equal(la.percentile(10, x.age), - np.percentile(raw, 10, 0)) - assert_array_nan_equal(la.percentile(10, x.age, x.sex), - np.percentile(raw, 10, (0, 2))) - - def test_percentile_groups(self): - la = self.larray - raw = self.array - - res = la.percentile(10, x.geo['A11', 'A13', 'A24']) - assert_array_nan_equal(res, np.percentile(raw[:, [0, 2, 4]], 10, 1)) - - def test_cumsum(self): - la = self.larray - - # using Axis objects - assert_array_equal(la.cumsum(x.age), self.array.cumsum(0)) - assert_array_equal(la.cumsum(x.lipro), self.array.cumsum(3)) - - # using axes numbers - assert_array_equal(la.cumsum(1), self.array.cumsum(1)) - - # using axes names - assert_array_equal(la.cumsum('sex'), self.array.cumsum(2)) - - def test_group_agg(self): - la = self.larray - age, geo, sex, lipro = la.axes - vla, wal, bru = self.vla_str, self.wal_str, self.bru_str - belgium = self.belgium - - # a) group aggregate on a fresh array - - # a.1) one group => collapse dimension - self.assertEqual(la.sum(sex['H']).shape, (116, 44, 15)) - self.assertEqual(la.sum(sex='H').shape, (116, 44, 15)) - self.assertEqual(la.sum(sex='H,F').shape, (116, 44, 15)) - - self.assertEqual(la.sum(geo='A11,A21,A25').shape, (116, 2, 15)) - self.assertEqual(la.sum(geo=['A11', 'A21', 'A25']).shape, (116, 2, 15)) - self.assertEqual(la.sum(geo=geo.group('A11,A21,A25')).shape, - (116, 2, 15)) - - self.assertEqual(la.sum(geo=geo.all()).shape, (116, 2, 15)) - self.assertEqual(la.sum(geo=':').shape, (116, 2, 15)) - self.assertEqual(la.sum(geo[':']).shape, (116, 2, 15)) - # Include everything between two labels. Since A11 is the first label - # and A21 is the last one, this should be equivalent to the previous - # tests. - self.assertEqual(la.sum(geo='A11:A21').shape, (116, 2, 15)) - assert_array_equal(la.sum(geo='A11:A21'), la.sum(geo=':')) - assert_array_equal(la.sum(geo['A11:A21']), la.sum(geo=':')) - - # a.2) a tuple of one group => do not collapse dimension - self.assertEqual(la.sum(geo=(geo.all(),)).shape, (116, 1, 2, 15)) - - # a.3) several groups - # string groups - self.assertEqual(la.sum(geo=(vla, wal, bru)).shape, (116, 3, 2, 15)) - # with one label in several groups - self.assertEqual(la.sum(sex=(['H'], ['H', 'F'])).shape, - (116, 44, 2, 15)) - self.assertEqual(la.sum(sex=('H', 'H,F')).shape, (116, 44, 2, 15)) - self.assertEqual(la.sum(sex='H;H,F').shape, (116, 44, 2, 15)) - - aggregated = la.sum(geo=(vla, wal, bru, belgium)) - self.assertEqual(aggregated.shape, (116, 4, 2, 15)) - - # a.4) several dimensions at the same time - self.assertEqual(la.sum(lipro='P01,P03;P02,P05;:', - geo=(vla, wal, bru, belgium)).shape, - (116, 4, 2, 3)) - - # b) both axis aggregate and group aggregate at the same time - # Note that you must list "full axes" aggregates first (Python does - # not allow non-kwargs after kwargs. - self.assertEqual(la.sum(age, sex, geo=(vla, wal, bru, belgium)).shape, - (4, 15)) - - # c) chain group aggregate after axis aggregate - reg = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) - self.assertEqual(reg.shape, (4, 15)) - - def test_group_agg_no_kwarg(self): - la = self.larray - age, geo, sex, lipro = la.axes - vla, wal, bru = self.vla_str, self.wal_str, self.bru_str - belgium = self.belgium - - # a) group aggregate on a fresh array - - # a.1) one group => collapse dimension - # not sure I should support groups with a single item in an aggregate - men = sex.i[[0]] - self.assertEqual(la.sum(men).shape, (116, 44, 15)) - self.assertEqual(la.sum('H').shape, (116, 44, 15)) - self.assertEqual(la.sum('H,').shape, (116, 44, 15)) - self.assertEqual(la.sum('H,F').shape, (116, 44, 15)) - self.assertEqual(la.sum(sex['H']).shape, (116, 44, 15)) - - self.assertEqual(la.sum('A11,A21,A25').shape, (116, 2, 15)) - self.assertEqual(la.sum(['A11', 'A21', 'A25']).shape, (116, 2, 15)) - self.assertEqual(la.sum(geo.group('A11,A21,A25')).shape, - (116, 2, 15)) - - self.assertEqual(la.sum(geo.all()).shape, (116, 2, 15)) - self.assertEqual(la.sum(geo[':']).shape, (116, 2, 15)) - # Include everything between two labels. Since A11 is the first label - # and A21 is the last one, this should be equivalent to the previous - # tests. - self.assertEqual(la.sum('A11:A21').shape, (116, 2, 15)) - assert_array_equal(la.sum('A11:A21'), la.sum(geo=':')) - assert_array_equal(la.sum(geo['A11:A21']), la.sum(geo=':')) - - # a.2) a tuple of one group => do not collapse dimension - self.assertEqual(la.sum((geo.all(),)).shape, (116, 1, 2, 15)) - - # a.3) several groups - # string groups - self.assertEqual(la.sum((vla, wal, bru)).shape, (116, 3, 2, 15)) - - # XXX: do we also want to support this? I do not really like it because - # it gets tricky when we have some other axes into play. For now the - # error message is unclear because it first aggregates on "vla", then - # tries to aggregate on "wal", but there is no "geo" dimension anymore. - # self.assertEqual(la.sum(vla, wal, bru).shape, (116, 3, 2, 15)) - - # with one label in several groups - self.assertEqual(la.sum((['H'], ['H', 'F'])).shape, - (116, 44, 2, 15)) - self.assertEqual(la.sum(('H', 'H,F')).shape, (116, 44, 2, 15)) - self.assertEqual(la.sum('H;H,F').shape, (116, 44, 2, 15)) - - aggregated = la.sum((vla, wal, bru, belgium)) - self.assertEqual(aggregated.shape, (116, 4, 2, 15)) - - # a.4) several dimensions at the same time - # : is ambiguous - # self.assertEqual(la.sum('P01,P03;P02,P05;:', - self.assertEqual(la.sum('P01,P03;P02,P05;P01:', - (vla, wal, bru, belgium)).shape, - (116, 4, 2, 3)) - - # b) both axis aggregate and group aggregate at the same time - # Note that you must list "full axes" aggregates first (Python does - # not allow non-kwargs after kwargs. - self.assertEqual(la.sum(age, sex, (vla, wal, bru, belgium)).shape, - (4, 15)) - - # c) chain group aggregate after axis aggregate - reg = la.sum(age, sex).sum((vla, wal, bru, belgium)) - self.assertEqual(reg.shape, (4, 15)) - - def test_group_agg_one_axis(self): - a = Axis('a', range(3)) - la = ndrange([a]) - raw = np.asarray(la) - - assert_array_equal(la.sum(a[0, 2]), raw[[0, 2]].sum()) - - # group aggregates on a group-aggregated array - def test_group_agg_on_group_agg(self): - la = self.larray - age, geo, sex, lipro = la.axes - vla, wal, bru = self.vla_str, self.wal_str, self.bru_str - belgium = self.belgium - - reg = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) - - # 1) one group => collapse dimension - self.assertEqual(reg.sum(lipro='P01,P02').shape, (4,)) - - # 2) a tuple of one group => do not collapse dimension - self.assertEqual(reg.sum(lipro=('P01,P02',)).shape, (4, 1)) - - # 3) several groups - self.assertEqual(reg.sum(lipro='P01;P02;:').shape, (4, 3)) - - # this is INVALID - # TODO: raise a nice exception - # regsum = reg.sum(lipro='P01,P02,:') - - # this is currently allowed even though it can be confusing: - # P01 and P02 are both groups with one element each. - self.assertEqual(reg.sum(lipro=('P01', 'P02', ':')).shape, (4, 3)) - self.assertEqual(reg.sum(lipro=('P01', 'P02', lipro.all())).shape, - (4, 3)) - - # explicit groups are better - self.assertEqual(reg.sum(lipro=('P01,', 'P02,', ':')).shape, (4, 3)) - self.assertEqual(reg.sum(lipro=(['P01'], ['P02'], ':')).shape, (4, 3)) - - # 4) groups on the aggregated dimension - - # self.assertEqual(reg.sum(geo=([vla, bru], [wal, bru])).shape, (2, 3)) - # vla, wal, bru - - # group aggregates on a group-aggregated array - def test_group_agg_on_group_agg_nokw(self): - la = self.larray - age, geo, sex, lipro = la.axes - vla, wal, bru = self.vla_str, self.wal_str, self.bru_str - belgium = self.belgium - - reg = la.sum(age, sex).sum((vla, wal, bru, belgium)) - # XXX: should this be supported too? (it currently fails) - # reg = la.sum(age, sex).sum(vla, wal, bru, belgium) - - # 1) one group => collapse dimension - self.assertEqual(reg.sum('P01,P02').shape, (4,)) - - # 2) a tuple of one group => do not collapse dimension - self.assertEqual(reg.sum(('P01,P02',)).shape, (4, 1)) - - # 3) several groups - # : is ambiguous - # self.assertEqual(reg.sum('P01;P02;:').shape, (4, 3)) - self.assertEqual(reg.sum('P01;P02;P01:').shape, (4, 3)) - - # this is INVALID - # TODO: raise a nice exception - # regsum = reg.sum(lipro='P01,P02,:') - - # this is currently allowed even though it can be confusing: - # P01 and P02 are both groups with one element each. - self.assertEqual(reg.sum(('P01', 'P02', 'P01:')).shape, (4, 3)) - self.assertEqual(reg.sum(('P01', 'P02', lipro.all())).shape, - (4, 3)) - - # explicit groups are better - self.assertEqual(reg.sum(('P01,', 'P02,', 'P01:')).shape, (4, 3)) - self.assertEqual(reg.sum((['P01'], ['P02'], 'P01:')).shape, (4, 3)) - - # 4) groups on the aggregated dimension - - # self.assertEqual(reg.sum(geo=([vla, bru], [wal, bru])).shape, (2, 3)) - # vla, wal, bru - - def test_getitem_on_group_agg(self): - la = self.larray - age, geo, sex, lipro = la.axes - vla, wal, bru = self.vla_str, self.wal_str, self.bru_str - belgium = self.belgium - - reg = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) - - # using a string - vla = self.vla_str - # the following are all equivalent - self.assertEqual(reg[vla].shape, (15,)) - self.assertEqual(reg[(vla,)].shape, (15,)) - self.assertEqual(reg[(vla, slice(None))].shape, (15,)) - self.assertEqual(reg[vla, slice(None)].shape, (15,)) - self.assertEqual(reg[vla, :].shape, (15,)) - - # one more level... - self.assertEqual(reg[vla]['P03'], 389049848.0) - - # using an anonymous LGroup - vla = self.geo.group(self.vla_str) - # the following are all equivalent - self.assertEqual(reg[vla].shape, (15,)) - self.assertEqual(reg[(vla,)].shape, (15,)) - self.assertEqual(reg[(vla, slice(None))].shape, (15,)) - self.assertEqual(reg[vla, slice(None)].shape, (15,)) - self.assertEqual(reg[vla, :].shape, (15,)) - - # using a named LGroup - vla = self.geo.group(self.vla_str, name='Vlaanderen') - # the following are all equivalent - self.assertEqual(reg[vla].shape, (15,)) - self.assertEqual(reg[(vla,)].shape, (15,)) - self.assertEqual(reg[(vla, slice(None))].shape, (15,)) - self.assertEqual(reg[vla, slice(None)].shape, (15,)) - self.assertEqual(reg[vla, :].shape, (15,)) - - def test_getitem_on_group_agg_nokw(self): - la = self.larray - age, geo, sex, lipro = la.axes - vla, wal, bru = self.vla_str, self.wal_str, self.bru_str - belgium = self.belgium - - reg = la.sum(age, sex).sum((vla, wal, bru, belgium)) - # using a string - vla = self.vla_str - # the following are all equivalent - self.assertEqual(reg[vla].shape, (15,)) - self.assertEqual(reg[(vla,)].shape, (15,)) - self.assertEqual(reg[(vla, slice(None))].shape, (15,)) - self.assertEqual(reg[vla, slice(None)].shape, (15,)) - self.assertEqual(reg[vla, :].shape, (15,)) - - # one more level... - self.assertEqual(reg[vla]['P03'], 389049848.0) - - # using an anonymous LGroup - vla = self.geo.group(self.vla_str) - # the following are all equivalent - self.assertEqual(reg[vla].shape, (15,)) - self.assertEqual(reg[(vla,)].shape, (15,)) - self.assertEqual(reg[(vla, slice(None))].shape, (15,)) - self.assertEqual(reg[vla, slice(None)].shape, (15,)) - self.assertEqual(reg[vla, :].shape, (15,)) - - # using a named LGroup - vla = self.geo.group(self.vla_str, name='Vlaanderen') - # the following are all equivalent - self.assertEqual(reg[vla].shape, (15,)) - self.assertEqual(reg[(vla,)].shape, (15,)) - self.assertEqual(reg[(vla, slice(None))].shape, (15,)) - self.assertEqual(reg[vla, slice(None)].shape, (15,)) - self.assertEqual(reg[vla, :].shape, (15,)) - - def test_filter_on_group_agg(self): - la = self.larray - age, geo, sex, lipro = la.axes - vla, wal, bru = self.vla_str, self.wal_str, self.bru_str - belgium = self.belgium - - reg = la.sum(age, sex).sum(geo=(vla, wal, bru, belgium)) - - # using a string - vla = self.vla_str - self.assertEqual(reg.filter(geo=vla).shape, (15,)) - # using an anonymous LGroup - vla = self.geo.group(self.vla_str) - self.assertEqual(reg.filter(geo=vla).shape, (15,)) - # using a named LGroup - vla = self.geo.group(self.vla_str, name='Vlaanderen') - self.assertEqual(reg.filter(geo=vla).shape, (15,)) - - # Note that reg.filter(geo=(vla,)) does NOT work. It might be a - # little confusing for users, because reg[(vla,)] works but it is - # normal because reg.filter(geo=(vla,)) is equivalent to: - # reg[((vla,),)] or reg[(vla,), :] - - # mixed VG/string slices - child = age[':17'] - working = age['18:64'] - retired = age['65:'] - - byage = la.sum(age=(child, '5', working, retired)) - self.assertEqual(byage.shape, (4, 44, 2, 15)) - - byage = la.sum(age=(child, '5:10', working, retired)) - self.assertEqual(byage.shape, (4, 44, 2, 15)) - - # filter on an aggregated larray created with mixed groups - self.assertEqual(byage.filter(age=child).shape, (44, 2, 15)) - self.assertEqual(byage.filter(age=':17').shape, (44, 2, 15)) - - # TODO: make this work - # self.assertEqual(byage.filter(age=slice('17')).shape, (44, 2, 15)) - # TODO: make it work for integer indices - # self.assertEqual(byage.filter(age=slice(18)).shape, (44, 2, 15)) - - # def test_sum_groups_vg_args(self): - # la = self.larray - # age, geo, sex, lipro = la.axes - # vla, wal, bru, belgium = self.vla, self.wal, self.bru, self.belgium - # - # # simple - # # ------ - # - # # a) one group aggregate (on a fresh array) - # - # # one group => collapse dimension - # self.assertEqual(la.sum(sex['H']).shape, (116, 44, 15)) - # self.assertEqual(la.sum(sex['H,F']).shape, (116, 44, 15)) - # self.assertEqual(la.sum(geo['A11,A21,A25']).shape, (116, 2, 15)) - - # # several groups - # self.assertEqual(la.sum((vla, wal, belgium)).shape, (116, 3, 2, 15)) - # - # # b) group aggregates on several dimensions at the same time - # - # # one group per dim => collapse - # self.assertEqual(la.sum(lipro['P01,P03'], vla).shape, (116, 4, 2, 3)) - # # several groups per dim - # lipro_groups = (lipro['P01,P02'], lipro['P05'], lipro['P07,P06']) - # self.assertEqual(la.sum(lipro_groups, (vla, wal, bru, belgium)).shape, - # (116, 4, 2, 3)) - - # # c) both axis aggregate and group aggregate at the same time - - # # In this version we do not need to list "full axes" aggregates first - # # since group aggregates are not kwargs - - # # one group - # self.assertEqual(la.sum(age, sex, vla).shape, (15,)) - # self.assertEqual(la.sum(vla, age, sex).shape, (15,)) - # self.assertEqual(la.sum(age, vla, sex).shape, (15,)) - # # tuple of groups - # self.assertEqual(la.sum(age, sex, (vla, belgium)).shape, (4, 15)) - # self.assertEqual(la.sum(age, (vla, belgium), sex).shape, (4, 15)) - # self.assertEqual(la.sum((vla, belgium), age, sex).shape, (4, 15)) - # self.assertEqual(la.sum((vla, belgium), age, sex).shape, (4, 15)) - # - # - # # d) mixing arg and kwarg group aggregates - # self.assertEqual(la.sum(lipro['P01,P02,P03,P05,P08'], - # geo=(vla, wal, bru)).shape, - # (116, 3, 2, 5)) - - def test_sum_several_vg_groups(self): - la, geo = self.larray, self.geo - fla = geo.group(self.vla_str, name='Flanders') - wal = geo.group(self.wal_str, name='Wallonia') - bru = geo.group(self.bru_str, name='Brussels') - - reg = la.sum(geo=(fla, wal, bru)) - self.assertEqual(reg.shape, (116, 3, 2, 15)) - - # the result is indexable - # a) by VG - self.assertEqual(reg.filter(geo=fla).shape, (116, 2, 15)) - self.assertEqual(reg.filter(geo=(fla, wal)).shape, (116, 2, 2, 15)) - - # b) by string (name of groups) - self.assertEqual(reg.filter(geo='Flanders').shape, (116, 2, 15)) - self.assertEqual(reg.filter(geo='Flanders,Wallonia').shape, - (116, 2, 2, 15)) - - # using string groups - reg = la.sum(geo=(self.vla_str, self.wal_str, self.bru_str)) - self.assertEqual(reg.shape, (116, 3, 2, 15)) - # the result is indexable - # a) by string (def) - self.assertEqual(reg.filter(geo=self.vla_str).shape, (116, 2, 15)) - self.assertEqual(reg.filter(geo=(self.vla_str, self.wal_str)).shape, - (116, 2, 2, 15)) - - # b) by VG - self.assertEqual(reg.filter(geo=fla).shape, (116, 2, 15)) - self.assertEqual(reg.filter(geo=(fla, wal)).shape, - (116, 2, 2, 15)) - - def test_sum_with_groups_from_other_axis(self): - small = self.small - - # use a group from another *compatible* axis - lipro2 = Axis('lipro', ['P%02d' % i for i in range(1, 16)]) - self.assertEqual(small.sum(lipro=lipro2['P01,P03']).shape, (2,)) - - # use group from another *incompatible* axis - # XXX: I am unsure whether or not this should be allowed. Maybe we - # should simply check that the group is valid in axis, but that - # will trigger a pretty meaningful error anyway - lipro3 = Axis('lipro', 'P01,P03,P05') - self.assertEqual(small.sum(lipro3['P01,P03']).shape, (2,)) - - # use a group (from another axis) which is incompatible with the axis of - # the same name in the array - lipro4 = Axis('lipro', 'P01,P03,P16') - self.assertRaises(KeyError, small.sum, lipro4['P01,P16']) - - def test_ratio(self): - la = self.larray - age, geo, sex, lipro = la.axes - - regions = (self.vla_str, self.wal_str, self.bru_str, self.belgium) - reg = la.sum(age, sex, regions) - self.assertEqual(reg.shape, (4, 15)) - - fla = geo.group(self.vla_str, name='Flanders') - wal = geo.group(self.wal_str, name='Wallonia') - bru = geo.group(self.bru_str, name='Brussels') - regions = (fla, wal, bru) - reg = la.sum(age, sex, regions) - - ratio = reg.ratio() - assert_array_equal(ratio, reg / reg.sum(geo, lipro)) - self.assertEqual(ratio.shape, (3, 15)) - - ratio = reg.ratio(geo) - assert_array_equal(ratio, reg / reg.sum(geo)) - self.assertEqual(ratio.shape, (3, 15)) - - ratio = reg.ratio(geo, lipro) - assert_array_equal(ratio, reg / reg.sum(geo, lipro)) - self.assertEqual(ratio.shape, (3, 15)) - self.assertEqual(ratio.sum(), 1.0) - - def test_percent(self): - la = self.larray - age, geo, sex, lipro = la.axes - - regions = (self.vla_str, self.wal_str, self.bru_str, self.belgium) - reg = la.sum(age, sex, regions) - self.assertEqual(reg.shape, (4, 15)) - - fla = geo.group(self.vla_str, name='Flanders') - wal = geo.group(self.wal_str, name='Wallonia') - bru = geo.group(self.bru_str, name='Brussels') - regions = (fla, wal, bru) - reg = la.sum(age, sex, regions) - - percent = reg.percent() - assert_array_equal(percent, reg * 100 / reg.sum(geo, lipro)) - self.assertEqual(percent.shape, (3, 15)) - - percent = reg.percent(geo) - assert_array_equal(percent, reg * 100 / reg.sum(geo)) - self.assertEqual(percent.shape, (3, 15)) - - percent = reg.percent(geo, lipro) - assert_array_equal(percent, reg * 100 / reg.sum(geo, lipro)) - self.assertEqual(percent.shape, (3, 15)) - self.assertAlmostEqual(percent.sum(), 100.0) - - def test_total(self): - la = self.larray - age, geo, sex, lipro = la.axes - # la = self.small - # sex, lipro = la.axes - - self.assertEqual(la.with_total().shape, (117, 45, 3, 16)) - self.assertEqual(la.with_total(sex).shape, (116, 44, 3, 15)) - self.assertEqual(la.with_total(lipro).shape, (116, 44, 2, 16)) - self.assertEqual(la.with_total(sex, lipro).shape, (116, 44, 3, 16)) - - fla = geo.group(self.vla_str, name='Flanders') - wal = geo.group(self.wal_str, name='Wallonia') - bru = geo.group(self.bru_str, name='Brussels') - bel = geo.all('Belgium') - - self.assertEqual(la.with_total(geo=(fla, wal, bru), op=mean).shape, - (116, 47, 2, 15)) - self.assertEqual(la.with_total((fla, wal, bru), op=mean).shape, - (116, 47, 2, 15)) - # works but "wrong" for x.geo (double what is expected because it - # includes fla wal & bru) - # TODO: we probably want to display a warning (or even an error?) in - # that case. If we really want that behavior, we can still split - # the operation: .with_total((fla, wal, bru)).with_total(x.geo) - # OR we might want to only sum the axis as it was before the op (but - # that does not play well when working with multiple axes). - a1 = la.with_total(x.sex, (fla, wal, bru), x.geo, x.lipro) - self.assertEqual(a1.shape, (116, 48, 3, 16)) - - # correct total but the order is not very nice - a2 = la.with_total(x.sex, x.geo, (fla, wal, bru), x.lipro) - self.assertEqual(a2.shape, (116, 48, 3, 16)) - - # the correct way to do it - a3 = la.with_total(x.sex, (fla, wal, bru, bel), x.lipro) - self.assertEqual(a3.shape, (116, 48, 3, 16)) - - # a4 = la.with_total((lipro[':P05'], lipro['P05:']), op=mean) - a4 = la.with_total((':P05', 'P05:'), op=mean) - self.assertEqual(a4.shape, (116, 44, 2, 17)) - - def test_transpose(self): - la = self.larray - age, geo, sex, lipro = la.axes - - reordered = la.transpose(geo, age, lipro, sex) - self.assertEqual(reordered.shape, (44, 116, 15, 2)) - - reordered = la.transpose(lipro, age) - self.assertEqual(reordered.shape, (15, 116, 44, 2)) - - self.assertEqual(la.transpose().axes.names, - ['lipro', 'sex', 'geo', 'age']) - - def test_transpose_anonymous(self): - a = ndrange((2, 3, 4)) - - # reordered = a.transpose(0, 2, 1) - # self.assertEqual(reordered.shape, (2, 4, 3)) - - # axes = self[1, 2] - # => union(axes, self) - # => axes.extend([self[0]]) - # => breaks because self[0] not compatible with axes[0] - # => breaks because self[0] not compatible with self[1] - - # a real union should not care and should return - # self[1, 2, 0] but will this break other stuff? My gut feeling is yes - - # when doing a binop between anonymous axes, we use union too (that - # might be the problem) and we need *that* union to match axes by - # position - reordered = a.transpose(1, 2) - self.assertEqual(reordered.shape, (3, 4, 2)) - - reordered = a.transpose(2, 0) - self.assertEqual(reordered.shape, (4, 2, 3)) - - reordered = a.transpose() - self.assertEqual(reordered.shape, (4, 3, 2)) - - def test_binary_ops(self): - raw = self.small_data - la = self.small - - assert_array_equal(la + la, raw + raw) - assert_array_equal(la + 1, raw + 1) - assert_array_equal(1 + la, 1 + raw) - - assert_array_equal(la - la, raw - raw) - assert_array_equal(la - 1, raw - 1) - assert_array_equal(1 - la, 1 - raw) - - assert_array_equal(la * la, raw * raw) - assert_array_equal(la * 2, raw * 2) - assert_array_equal(2 * la, 2 * raw) - - assert_array_nan_equal(la / la, raw / raw) - assert_array_equal(la / 2, raw / 2) - assert_array_equal(30 / la, 30 / raw) - assert_array_equal(30 / (la + 1), 30 / (raw + 1)) - - raw_int = raw.astype(int) - la_int = LArray(raw_int, axes=(self.sex, self.lipro)) - assert_array_equal(la_int / 2, raw_int / 2) - assert_array_equal(la_int // 2, raw_int // 2) - - # test adding two larrays with different axes order - assert_array_equal(la + la.transpose(), raw * 2) - - # mixed operations - raw2 = raw / 2 - la_raw2 = la - raw2 - self.assertEqual(la_raw2.axes, la.axes) - assert_array_equal(la_raw2, raw - raw2) - raw2_la = raw2 - la - self.assertEqual(raw2_la.axes, la.axes) - assert_array_equal(raw2_la, raw2 - raw) - - la_ge_raw2 = la >= raw2 - self.assertEqual(la_ge_raw2.axes, la.axes) - assert_array_equal(la_ge_raw2, raw >= raw2) - - raw2_ge_la = raw2 >= la - self.assertEqual(raw2_ge_la.axes, la.axes) - assert_array_equal(raw2_ge_la, raw2 >= raw) - - def test_binary_ops_no_name_axes(self): - raw = self.small_data - raw2 = self.small_data + 1 - la = ndrange(self.small.shape) - la2 = ndrange(self.small.shape) + 1 - - assert_array_equal(la + la2, raw + raw2) - assert_array_equal(la + 1, raw + 1) - assert_array_equal(1 + la, 1 + raw) - - assert_array_equal(la - la2, raw - raw2) - assert_array_equal(la - 1, raw - 1) - assert_array_equal(1 - la, 1 - raw) - - assert_array_equal(la * la2, raw * raw2) - assert_array_equal(la * 2, raw * 2) - assert_array_equal(2 * la, 2 * raw) - - assert_array_nan_equal(la / la2, raw / raw2) - assert_array_equal(la / 2, raw / 2) - assert_array_equal(30 / la, 30 / raw) - assert_array_equal(30 / (la + 1), 30 / (raw + 1)) - - raw_int = raw.astype(int) - la_int = LArray(raw_int) - assert_array_equal(la_int / 2, raw_int / 2) - assert_array_equal(la_int // 2, raw_int // 2) - - # adding two larrays with different axes order cannot work with - # unnamed axes - # assert_array_equal(la + la.transpose(), raw * 2) - - # mixed operations - raw2 = raw / 2 - la_raw2 = la - raw2 - self.assertEqual(la_raw2.axes, la.axes) - assert_array_equal(la_raw2, raw - raw2) - raw2_la = raw2 - la - self.assertEqual(raw2_la.axes, la.axes) - assert_array_equal(raw2_la, raw2 - raw) - - la_ge_raw2 = la >= raw2 - self.assertEqual(la_ge_raw2.axes, la.axes) - assert_array_equal(la_ge_raw2, raw >= raw2) - - raw2_ge_la = raw2 >= la - self.assertEqual(raw2_ge_la.axes, la.axes) - assert_array_equal(raw2_ge_la, raw2 >= raw) - - def test_broadcasting_no_name(self): - """ - >>> a = ndrange((2, 3)) - >>> b = ndrange(3) - >>> c = ndrange(2) - >>> a - {0}*\\{1}* | 0 | 1 | 2 - 0 | 0 | 1 | 2 - 1 | 3 | 4 | 5 - >>> b - {0}* | 0 | 1 | 2 - | 0 | 1 | 2 - >>> c - {0}* | 0 | 1 - | 0 | 1 - - >>> # it is unfortunate that the behavior is different from numpy - >>> # (even though I find our behavior more intuitive) - >>> # a * b - ValueError: incompatible axes: - Axis(None, [0, 1, 2]) - vs - Axis(None, [0, 1]) - - >>> a * c - {0}*\\{1}* | 0 | 1 | 2 - 0 | 0 | 0 | 0 - 1 | 3 | 4 | 5 - - >>> np.asarray(a) * np.asarray(b) - array([[ 0, 1, 4], - [ 0, 4, 10]]) - - >>> # np.asarray(a) * np.asarray(c) - ValueError: operands could not be broadcast together with shapes (2,3) (2,) - """ - - a = ndrange((2, 3)) - b = ndrange(3) - c = ndrange(2) - # axes objects are != and no common name => considered to be - # different axes - d = a * c - - self.assertEqual(d.shape, (2, 3)) - - def test_unary_ops(self): - raw = self.small_data - la = self.small - - # using numpy functions - assert_array_equal(np.abs(la - 10), np.abs(raw - 10)) - assert_array_equal(np.negative(la), np.negative(raw)) - assert_array_equal(np.invert(la), np.invert(raw)) - - # using python builtin ops - assert_array_equal(abs(la - 10), abs(raw - 10)) - assert_array_equal(-la, -raw) - assert_array_equal(+la, +raw) - assert_array_equal(~la, ~raw) - - def test_mean(self): - la = self.small - raw = self.small_data - - sex, lipro = la.axes - assert_array_equal(la.mean(lipro), raw.mean(1)) - - def test_append(self): - la = self.small - sex, lipro = la.axes - - la = la.append(lipro, la.sum(lipro), label='sum') - self.assertEqual(la.shape, (2, 16)) - la = la.append(sex, la.sum(sex), label='sum') - self.assertEqual(la.shape, (3, 16)) - - # crap the sex axis is different !!!! we don't have this problem with - # the kwargs syntax below - # la = la.append(la.mean(sex), axis=sex, label='mean') - # self.assertEqual(la.shape, (4, 16)) - - # another syntax (which implies we could not have an axis named "label") - # la = la.append(lipro=la.sum(lipro), label='sum') - # self.assertEqual(la.shape, (117, 44, 2, 15)) - - # the aim of this test is to drop the last value of an axis, but instead - # of dropping the last axis tick/label, drop the first one. - def test_shift_axis(self): - la = self.small - sex, lipro = la.axes - - # TODO: check how awful the syntax is with an axis that is not last - # or first - l2 = LArray(la[:, :'P14'], axes=[sex, Axis('lipro', lipro.labels[1:])]) - l2 = LArray(la[:, :'P14'], axes=[sex, lipro.subaxis(slice(1, None))]) - - # We can also modify the axis in-place (dangerous!) - # lipro.labels = np.append(lipro.labels[1:], lipro.labels[0]) - l2 = la[:, 'P02':] - l2.axes.lipro.labels = lipro.labels[1:] - - def test_extend(self): - la = self.small - sex, lipro = la.axes - - all_lipro = lipro[:] - tail = la.sum(lipro=(all_lipro,)) - la = la.extend(lipro, tail) - self.assertEqual(la.shape, (2, 16)) - # test with a string axis - la = la.extend('sex', la.sum(sex=(sex.all(),))) - self.assertEqual(la.shape, (3, 16)) - - # def test_excel_export(self): - # la = self.larray - # age, geo, sex, lipro = la.axes - # - # reg = la.sum(age, sex, geo=(self.vla, self.wal, self.bru, self.belgium)) - # self.assertEqual(reg.shape, (4, 15)) - # - # print("excel export", end='') - # reg.to_excel('c:\\tmp\\reg.xlsx', '_') - # #ages.to_excel('c:/tmp/ages.xlsx') - # print("done") - - def test_readcsv(self): - la = read_csv(abspath('test1d.csv')) - self.assertEqual(la.ndim, 1) - self.assertEqual(la.shape, (3,)) - self.assertEqual(la.axes.names, ['time']) - assert_array_equal(la, [3722, 3395, 3347]) - - la = read_csv(abspath('test2d.csv')) - self.assertEqual(la.ndim, 2) - self.assertEqual(la.shape, (5, 3)) - self.assertEqual(la.axes.names, ['age', 'time']) - assert_array_equal(la[0, :], [3722, 3395, 3347]) - - la = read_csv(abspath('test3d.csv')) - self.assertEqual(la.ndim, 3) - self.assertEqual(la.shape, (5, 2, 3)) - self.assertEqual(la.axes.names, ['age', 'sex', 'time']) - assert_array_equal(la[0, 'F', :], [3722, 3395, 3347]) - - la = read_csv(abspath('test5d.csv')) - self.assertEqual(la.ndim, 5) - self.assertEqual(la.shape, (2, 5, 2, 2, 3)) - self.assertEqual(la.axes.names, ['arr', 'age', 'sex', 'nat', 'time']) - assert_array_equal(la[x.arr[1], 0, 'F', x.nat[1], :], - [3722, 3395, 3347]) - - def test_df_aslarray(self): - dt = [('age', int), ('sex', 'U1'), - ('2007', int), ('2010', int), ('2013', int)] - data = np.array([ - (0, 'F', 3722, 3395, 3347), - (0, 'H', 338, 316, 323), - (1, 'F', 2878, 2791, 2822), - (1, 'H', 1121, 1037, 976), - (2, 'F', 4073, 4161, 4429), - (2, 'H', 1561, 1463, 1467), - (3, 'F', 3507, 3741, 3366), - (3, 'H', 2052, 2052, 2118), - ], dtype=dt) - df = pd.DataFrame(data) - df.set_index(['age', 'sex'], inplace=True) - df.columns.name = 'time' - - la = df_aslarray(df) - self.assertEqual(la.ndim, 3) - self.assertEqual(la.shape, (4, 2, 3)) - self.assertEqual(la.axes.names, ['age', 'sex', 'time']) - assert_array_equal(la[0, 'F', :], [3722, 3395, 3347]) - - def test_to_csv(self): - la = read_csv(abspath('test5d.csv')) - self.assertEqual(la.ndim, 5) - self.assertEqual(la.shape, (2, 5, 2, 2, 3)) - self.assertEqual(la.axes.names, ['arr', 'age', 'sex', 'nat', 'time']) - assert_array_equal(la[x.arr[1], 0, 'F', x.nat[1], :], - [3722, 3395, 3347]) - - la.to_csv('out.csv') - result = ['arr,age,sex,nat\\time,2007,2010,2013\n', - '1,0,F,1,3722,3395,3347\n', - '1,0,F,2,338,316,323\n'] - with open('out.csv') as f: - self.assertEqual(f.readlines()[:3], result) - - la.to_csv('out.csv', transpose=False) - result = ['arr,age,sex,nat,time,0\n', '1,0,F,1,2007,3722\n', - '1,0,F,1,2010,3395\n'] - with open('out.csv') as f: - self.assertEqual(f.readlines()[:3], result) - - la = ndrange([Axis('time', range(2015, 2018))]) - la.to_csv('test_out1d.csv') - result = ['time,2015,2016,2017\n', - ',0,1,2\n'] - with open('test_out1d.csv') as f: - self.assertEqual(f.readlines(), result) - - def test_ufuncs(self): - la = self.small - raw = self.small_data - - # simple one-argument ufunc - assert_array_equal(exp(la), np.exp(raw)) - - # with out= - la_out = zeros(la.axes) - raw_out = np.zeros(raw.shape) - - la_out2 = exp(la, la_out) - raw_out2 = np.exp(raw, raw_out) - - # FIXME: this is not the case currently - # self.assertIs(la_out2, la_out) - assert_array_equal(la_out2, la_out) - self.assertIs(raw_out2, raw_out) - - assert_array_equal(la_out, raw_out) - - # with out= and broadcasting - # we need to put the 'a' axis first because raw numpy only supports that - la_out = zeros([Axis('a', [0, 1, 2])] + list(la.axes)) - raw_out = np.zeros((3,) + raw.shape) - - la_out2 = exp(la, la_out) - raw_out2 = np.exp(raw, raw_out) - - # self.assertIs(la_out2, la_out) - # XXX: why is la_out2 transposed? - assert_array_equal(la_out2.transpose(x.a), la_out) - self.assertIs(raw_out2, raw_out) - - assert_array_equal(la_out, raw_out) - - sex, lipro = la.axes - - low = la.sum(sex) // 4 + 3 - raw_low = raw.sum(0) // 4 + 3 - high = la.sum(sex) // 4 + 13 - raw_high = raw.sum(0) // 4 + 13 - - # LA + scalars - assert_array_equal(la.clip(0, 10), raw.clip(0, 10)) - assert_array_equal(clip(la, 0, 10), np.clip(raw, 0, 10)) - - # LA + LA (no broadcasting) - assert_array_equal(clip(la, 21 - la, 9 + la // 2), - np.clip(raw, 21 - raw, 9 + raw // 2)) - - # LA + LA (with broadcasting) - assert_array_equal(clip(la, low, high), - np.clip(raw, raw_low, raw_high)) - - # where (no broadcasting) - assert_array_equal(where(la < 5, -5, la), - np.where(raw < 5, -5, raw)) - - # where (transposed no broadcasting) - assert_array_equal(where(la < 5, -5, la.T), - np.where(raw < 5, -5, raw)) - - # where (with broadcasting) - result = where(la['P01'] < 5, -5, la) - self.assertEqual(result.axes.names, ['sex', 'lipro']) - assert_array_equal(result, np.where(raw[:,[0]] < 5, -5, raw)) - - # round - small_float = self.small + 0.6 - rounded = round(small_float) - assert_array_equal(rounded, np.round(self.small_data + 0.6)) - - def test_diag(self): - # 2D -> 1D - a = ndrange((3, 3)) - d = diag(a) - self.assertEqual(d.ndim, 1) - self.assertEqual(d.i[0], a.i[0, 0]) - self.assertEqual(d.i[1], a.i[1, 1]) - self.assertEqual(d.i[2], a.i[2, 2]) - - # 1D -> 2D - a2 = diag(d) - self.assertEqual(a2.ndim, 2) - self.assertEqual(a2.i[0, 0], a.i[0, 0]) - self.assertEqual(a2.i[1, 1], a.i[1, 1]) - self.assertEqual(a2.i[2, 2], a.i[2, 2]) - - # 3D -> 2D - a = ndrange((3, 3, 3)) - d = diag(a) - self.assertEqual(d.ndim, 2) - self.assertEqual(d.i[0, 0], a.i[0, 0, 0]) - self.assertEqual(d.i[1, 1], a.i[1, 1, 1]) - self.assertEqual(d.i[2, 2], a.i[2, 2, 2]) - - # 3D -> 1D - d = diag(a, axes=(0, 1, 2)) - self.assertEqual(d.ndim, 1) - self.assertEqual(d.i[0], a.i[0, 0, 0]) - self.assertEqual(d.i[1], a.i[1, 1, 1]) - self.assertEqual(d.i[2], a.i[2, 2, 2]) - - # 1D (anon) -> 2D - d_anon = d.rename(0, None).drop_labels() - a2 = diag(d_anon) - self.assertEqual(a2.ndim, 2) - - # 1D (anon) -> 3D - a3 = diag(d_anon, ndim=3) - self.assertEqual(a2.ndim, 2) - self.assertEqual(a3.i[0, 0, 0], a.i[0, 0, 0]) - self.assertEqual(a3.i[1, 1, 1], a.i[1, 1, 1]) - self.assertEqual(a3.i[2, 2, 2], a.i[2, 2, 2]) - - # using Axis object - sex = Axis('sex', 'M,F') - a = eye(sex) - d = diag(a) - self.assertEqual(d.ndim, 1) - self.assertEqual(d.axes.names, ['sex,sex']) - assert_array_equal(d.axes.labels, [['M,M', 'F,F']]) - self.assertEqual(d.i[0], 1.0) - self.assertEqual(d.i[1], 1.0) - - # cannot use @ in the tests because that is an invalid syntax in Python 2 - def test_matmul(self): - a1 = eye(3) * 2 - a2 = ndrange((3, 3)) - - if sys.version >= '3': - # LArray value - assert_array_equal(a1.__matmul__(a2), ndrange((3, 3)) * 2) - - # ndarray value - assert_array_equal(a1.__matmul__(a2.data), ndrange((3, 3)) * 2) - - def test_rmatmul(self): - a1 = eye(3) * 2 - a2 = ndrange((3, 3)) - if sys.version >= '3': - # equivalent to a1.data @ a2 - res = a2.__rmatmul__(a1.data) - self.assertIsInstance(res, LArray) - assert_array_equal(res, ndrange((3, 3)) * 2) - - def test_plot(self): - pass - #small_h = small['H'] - #small_h.plot(kind='bar') - #small_h.plot() - #small_h.hist() - - #large_data = np.random.randn(1000) - #tick_v = np.random.randint(ord('a'), ord('z'), size=1000) - #ticks = [chr(c) for c in tick_v] - #large_axis = Axis('large', ticks) - #large = LArray(large_data, axes=[large_axis]) - #large.plot() - #large.hist() - - -if __name__ == "__main__": - import doctest - from larray import core - doctest.testmod(core) - unittest.main() diff --git a/larray/tests/test_session.py b/larray/tests/test_session.py index 34ea1f302..ebeb62e14 100644 --- a/larray/tests/test_session.py +++ b/larray/tests/test_session.py @@ -1,22 +1,79 @@ from __future__ import absolute_import, division, print_function +import os +import shutil from unittest import TestCase -import unittest import numpy as np -from larray import Session, Axis, LArray, ndrange, isnan, view, local_arrays -from larray.tests.test_la import assert_array_nan_equal +import pandas as pd +import pytest + +from larray.tests.common import assert_array_nan_equal, inputpath +from larray import (Session, Axis, LArray, isnan, larray_equal, zeros_like, ndtest, ones_like, + local_arrays, global_arrays, arrays) +from larray.util.misc import pickle + +try: + import xlwings as xw +except ImportError: + xw = None + + +def equal(o1, o2): + if isinstance(o1, LArray) or isinstance(o2, LArray): + return o1.equals(o2) + elif isinstance(o1, Axis) or isinstance(o2, Axis): + return o1.equals(o2) + else: + return o1 == o2 + +global_arr1 = ndtest((2, 2)) +_global_arr2 = ndtest((3, 3)) class TestSession(TestCase): def setUp(self): - self.a = Axis('a', []) - self.b = Axis('b', []) - self.e = ndrange((2, 3)).rename(0, 'a0').rename(1, 'a1') - self.f = ndrange((3, 2)).rename(0, 'a0').rename(1, 'a1') - self.g = ndrange((2, 4)).rename(0, 'a0').rename(1, 'a1') - self.session = Session(self.a, self.b, c='c', d={}, - e=self.e, f=self.f, g=self.g) + self.a = Axis([], 'a') + self.b = Axis([], 'b') + self.c = 'c' + self.d = {} + self.e = ndtest([(2, 'a0'), (3, 'a1')]) + self.e2 = ndtest(('a=a0..a2', 'b=b0..b2')) + self.f = ndtest([(3, 'a0'), (2, 'a1')]) + self.g = ndtest([(2, 'a0'), (4, 'a1')]) + self.session = Session([ + ('b', self.b), ('a', self.a), + ('c', self.c), ('d', self.d), + ('e', self.e), ('g', self.g), ('f', self.f), + ]) + + @pytest.fixture(autouse=True) + def output_dir(self, tmpdir_factory): + self.tmpdir = tmpdir_factory.mktemp('tmp_session').strpath + + def get_path(self, fname): + return os.path.join(self.tmpdir, fname) + + def assertObjListEqual(self, got, expected): + self.assertEqual(len(got), len(expected)) + for e1, e2 in zip(got, expected): + self.assertTrue(equal(e1, e2), "{} != {}".format(e1, e2)) + + def test_init(self): + s = Session(self.b, self.a, c=self.c, d=self.d, + e=self.e, f=self.f, g=self.g) + self.assertEqual(s.names, ['a', 'b', 'c', 'd', 'e', 'f', 'g']) + + s = Session(inputpath('test_session.h5')) + self.assertEqual(s.names, ['e', 'f', 'g']) + + # this needs xlwings installed + # s = Session('test_session_ef.xlsx') + # self.assertEqual(s.names, ['e', 'f']) + + # TODO: format autodetection does not work in this case + # s = Session('test_session_csv') + # self.assertEqual(s.names, ['e', 'f', 'g']) def test_getitem(self): s = self.session @@ -28,16 +85,18 @@ def test_getitem(self): def test_getitem_list(self): s = self.session self.assertEqual(list(s[[]]), []) + self.assertEqual(list(s[['b', 'a']]), [self.b, self.a]) self.assertEqual(list(s[['a', 'b']]), [self.a, self.b]) self.assertEqual(list(s[['a', 'e', 'g']]), [self.a, self.e, self.g]) + self.assertEqual(list(s[['g', 'a', 'e']]), [self.g, self.a, self.e]) def test_getitem_larray(self): s1 = self.session.filter(kind=LArray) s2 = Session({'e': self.e + 1, 'f': self.f}) - res_eq = s1[s1 == s2] - res_neq = s1[s1 != s2] - self.assertEqual(list(res_eq), [self.f]) - self.assertEqual(list(res_neq), [self.e, self.g]) + res_eq = s1[s1.array_equals(s2)] + res_neq = s1[~(s1.array_equals(s2))] + assert list(res_eq) == [self.f] + assert list(res_neq) == [self.e, self.g] def test_setitem(self): s = self.session @@ -58,26 +117,26 @@ def test_setattr(self): def test_add(self): s = self.session - h = Axis('h', []) + h = Axis([], 'h') s.add(h, i='i') self.assertTrue(h.equals(s.h)) self.assertEqual(s.i, 'i') def test_iter(self): - self.assertEqual(list(self.session), [self.a, self.b, 'c', {}, - self.e, self.f, self.g]) + expected = [self.b, self.a, self.c, self.d, self.e, self.g, self.f] + self.assertObjListEqual(self.session, expected) def test_filter(self): s = self.session s.ax = 'ax' - self.assertEqual(list(s.filter()), [self.a, 'ax', self.b, 'c', {}, - self.e, self.f, self.g]) + self.assertObjListEqual(s.filter(), [self.b, self.a, 'c', {}, + self.e, self.g, self.f, 'ax']) self.assertEqual(list(s.filter('a')), [self.a, 'ax']) self.assertEqual(list(s.filter('a', dict)), []) self.assertEqual(list(s.filter('a', str)), ['ax']) self.assertEqual(list(s.filter('a', Axis)), [self.a]) - self.assertEqual(list(s.filter(kind=Axis)), [self.a, self.b]) - self.assertEqual(list(s.filter(kind=LArray)), [self.e, self.f, self.g]) + self.assertEqual(list(s.filter(kind=Axis)), [self.b, self.a]) + self.assertObjListEqual(s.filter(kind=LArray), [self.e, self.g, self.f]) self.assertEqual(list(s.filter(kind=dict)), [{}]) def test_names(self): @@ -88,101 +147,321 @@ def test_names(self): s.add(h='h') self.assertEqual(s.names, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']) - def test_dump(self): - self.session.dump('test_session.h5') - self.session.dump('test_session.xlsx') - self.session.dump('test_session_ef.xlsx', ['e', 'f']) - self.session.dump_excel('test_session2.xlsx') - self.session.dump_csv('test_session_csv') + def test_h5_io(self): + fpath = self.get_path('test_session.h5') + self.session.save(fpath) - def test_load(self): s = Session() - s.load('test_session.h5', ['e', 'f']) - self.assertEqual(s.names, ['e', 'f']) + s.load(fpath) + # HDF does *not* keep ordering (ie, keys are always sorted) + self.assertEqual(list(s.keys()), ['e', 'f', 'g']) + + # update an array (overwrite=False) + Session(e=self.e2).save(fpath, overwrite=False) + s.load(fpath) + self.assertEqual(list(s.keys()), ['e', 'f', 'g']) + assert_array_nan_equal(s['e'], self.e2) s = Session() - s.load('test_session.h5') - self.assertEqual(s.names, ['e', 'f', 'g']) + s.load(fpath, ['e', 'f']) + self.assertEqual(list(s.keys()), ['e', 'f']) + + def test_xlsx_pandas_io(self): + fpath = self.get_path('test_session.xlsx') + self.session.save(fpath, engine='pandas_excel') s = Session() - s.load('test_session_ef.xlsx') - self.assertEqual(s.names, ['e', 'f']) + s.load(fpath, engine='pandas_excel') + self.assertEqual(list(s.keys()), ['e', 'g', 'f']) + # update an array (overwrite=False) + Session(e=self.e2).save(fpath, engine='pandas_excel', overwrite=False) + s.load(fpath, engine='pandas_excel') + self.assertEqual(list(s.keys()), ['e', 'g', 'f']) + assert_array_nan_equal(s['e'], self.e2) + + fpath = self.get_path('test_session_ef.xlsx') + self.session.save(fpath, ['e', 'f'], engine='pandas_excel') s = Session() - s.load('test_session_csv', fmt='csv') - self.assertEqual(s.names, ['e', 'f', 'g']) + s.load(fpath, engine='pandas_excel') + self.assertEqual(list(s.keys()), ['e', 'f']) - def test_eq(self): + @pytest.mark.skipif(xw is None, reason="xlwings is not available") + def test_xlsx_xlwings_io(self): + fpath = self.get_path('test_session_xw.xlsx') + # test save when Excel file does not exist + self.session.save(fpath, engine='xlwings_excel') + + s = Session() + s.load(fpath, engine='xlwings_excel') + # ordering is only kept if the file did not exist previously (otherwise the ordering is left intact) + self.assertEqual(list(s.keys()), ['e', 'g', 'f']) + + # update an array (overwrite=False) + Session(e=self.e2).save(fpath, engine='xlwings_excel', overwrite=False) + s.load(fpath, engine='xlwings_excel') + self.assertEqual(list(s.keys()), ['e', 'g', 'f']) + assert_array_nan_equal(s['e'], self.e2) + + fpath = self.get_path('test_session_ef_xw.xlsx') + self.session.save(fpath, ['e', 'f'], engine='xlwings_excel') + s = Session() + s.load(fpath, engine='xlwings_excel') + self.assertEqual(list(s.keys()), ['e', 'f']) + + def test_csv_io(self): + try: + fpath = self.get_path('test_session_csv') + self.session.to_csv(fpath) + + # test loading a directory + s = Session() + s.load(fpath, engine='pandas_csv') + # CSV cannot keep ordering (so we always sort keys) + self.assertEqual(list(s.keys()), ['e', 'f', 'g']) + + # test loading with a pattern + pattern = os.path.join(fpath, '*.csv') + s = Session(pattern) + # s = Session() + # s.load(pattern) + self.assertEqual(list(s.keys()), ['e', 'f', 'g']) + + # create an invalid .csv file + invalid_fpath = os.path.join(fpath, 'invalid.csv') + with open(invalid_fpath, 'w') as f: + f.write(',",') + + # try loading the directory with the invalid file + with pytest.raises(pd.errors.ParserError) as e_info: + s = Session(pattern) + + # test loading a pattern, ignoring invalid/unsupported files + s = Session() + s.load(pattern, ignore_exceptions=True) + self.assertEqual(list(s.keys()), ['e', 'f', 'g']) + finally: + shutil.rmtree(fpath) + + def test_pickle_io(self): + fpath = self.get_path('test_session.pkl') + self.session.save(fpath) + + s = Session() + s.load(fpath, engine='pickle') + self.assertEqual(list(s.keys()), ['e', 'g', 'f']) + + # update an array (overwrite=False) + Session(e=self.e2).save(fpath, overwrite=False) + s.load(fpath, engine='pickle') + self.assertEqual(list(s.keys()), ['e', 'g', 'f']) + assert_array_nan_equal(s['e'], self.e2) + + def test_to_globals(self): + with pytest.warns(RuntimeWarning) as caught_warnings: + self.session.to_globals() + assert len(caught_warnings) == 1 + assert caught_warnings[0].message.args[0] == "Session.to_globals should usually only be used in interactive " \ + "consoles and not in scripts. Use warn=False to deactivate this " \ + "warning." + assert caught_warnings[0].filename == __file__ + + self.assertIs(a, self.a) + self.assertIs(b, self.b) + self.assertIs(c, self.c) + self.assertIs(d, self.d) + self.assertIs(e, self.e) + self.assertIs(f, self.f) + self.assertIs(g, self.g) + + # test inplace + backup_dest = e + backup_value = self.session.e.copy() + self.session.e = zeros_like(e) + self.session.to_globals(inplace=True, warn=False) + # check the variable is correct (the same as before) + self.assertIs(e, backup_dest) + self.assertIsNot(e, self.session.e) + # check the content has changed + assert_array_nan_equal(e, self.session.e) + self.assertFalse(e.equals(backup_value)) + + def test_array_equals(self): sess = self.session.filter(kind=LArray) expected = Session([('e', self.e), ('f', self.f), ('g', self.g)]) - self.assertTrue(all(sess == expected)) + assert all(sess.array_equals(expected)) other = Session({'e': self.e, 'f': self.f}) - res = sess == other - self.assertEqual(res.ndim, 1) - self.assertEqual(res.axes.names, ['name']) - self.assertTrue(np.array_equal(res.axes.labels[0], ['e', 'f', 'g'])) - self.assertEqual(list(res), [True, True, False]) + res = sess.array_equals(other) + assert res.ndim == 1 + assert res.axes.names == ['name'] + assert np.array_equal(res.axes.labels[0], ['e', 'g', 'f']) + assert list(res) == [True, False, True] e2 = self.e.copy() e2.i[1, 1] = 42 other = Session({'e': e2, 'f': self.f}) + res = sess.array_equals(other) + assert res.axes.names == ['name'] + assert np.array_equal(res.axes.labels[0], ['e', 'g', 'f']) + assert list(res) == [False, False, True] + + def test_eq(self): + sess = self.session.filter(kind=LArray) + expected = Session([('e', self.e), ('f', self.f), ('g', self.g)]) + assert all([array.all() for array in (sess == expected).values()]) + + other = Session([('e', self.e), ('f', self.f)]) + res = sess == other + assert list(res.keys()) == ['e', 'g', 'f'] + assert [arr.all() for arr in res.values()] == [True, False, True] + + e2 = self.e.copy() + e2.i[1, 1] = 42 + other = Session([('e', e2), ('f', self.f)]) res = sess == other - self.assertEqual(res.axes.names, ['name']) - self.assertTrue(np.array_equal(res.axes.labels[0], ['e', 'f', 'g'])) - self.assertEqual(list(res), [False, True, False]) + assert [arr.all() for arr in res.values()] == [False, False, True] def test_ne(self): sess = self.session.filter(kind=LArray) expected = Session([('e', self.e), ('f', self.f), ('g', self.g)]) - self.assertFalse(any(sess != expected)) + assert ([(~array).all() for array in (sess != expected).values()]) - other = Session({'e': self.e, 'f': self.f}) + other = Session([('e', self.e), ('f', self.f)]) res = sess != other - self.assertEqual(res.axes.names, ['name']) - self.assertTrue(np.array_equal(res.axes.labels[0], ['e', 'f', 'g'])) - self.assertEqual(list(res), [False, False, True]) + assert [(~arr).all() for arr in res.values()] == [True, False, True] e2 = self.e.copy() e2.i[1, 1] = 42 - other = Session({'e': e2, 'f': self.f}) + other = Session([('e', e2), ('f', self.f)]) res = sess != other - self.assertEqual(res.axes.names, ['name']) - self.assertTrue(np.array_equal(res.axes.labels[0], ['e', 'f', 'g'])) - self.assertEqual(list(res), [True, False, True]) + assert [(~arr).all() for arr in res.values()] == [False, False, True] def test_sub(self): sess = self.session.filter(kind=LArray) - other = Session({'e': self.e - 1, 'f': 1}) + + # session - session + other = Session({'e': self.e - 1, 'f': ones_like(self.f)}) diff = sess - other assert_array_nan_equal(diff['e'], np.full((2, 3), 1, dtype=np.int32)) - assert_array_nan_equal(diff['f'], np.arange(-1, 5).reshape(3, 2)) - self.assertTrue(isnan(diff['g']).all()) + assert_array_nan_equal(diff['f'], self.f - ones_like(self.f)) + assert isnan(diff['g']).all() + + # session - scalar + diff = sess - 2 + assert_array_nan_equal(diff['e'], self.e - 2) + assert_array_nan_equal(diff['f'], self.f - 2) + assert_array_nan_equal(diff['g'], self.g - 2) + + # session - dict(LArray and scalar) + other = {'e': ones_like(self.e), 'f': 1} + diff = sess - other + assert_array_nan_equal(diff['e'], self.e - ones_like(self.e)) + assert_array_nan_equal(diff['f'], self.f - 1) + assert isnan(diff['g']).all() + + def test_rsub(self): + sess = self.session.filter(kind=LArray) + + # scalar - session + diff = 2 - sess + assert_array_nan_equal(diff['e'], 2 - self.e) + assert_array_nan_equal(diff['f'], 2 - self.f) + assert_array_nan_equal(diff['g'], 2 - self.g) + + # dict(LArray and scalar) - session + other = {'e': ones_like(self.e), 'f': 1} + diff = other - sess + assert_array_nan_equal(diff['e'], ones_like(self.e) - self.e) + assert_array_nan_equal(diff['f'], 1 - self.f) + assert isnan(diff['g']).all() def test_div(self): sess = self.session.filter(kind=LArray) other = Session({'e': self.e - 1, 'f': self.f + 1}) - res = sess / other - flat_e = np.arange(6) / np.arange(-1, 5) + with pytest.warns(RuntimeWarning) as caught_warnings: + res = sess / other + assert len(caught_warnings) == 1 + assert caught_warnings[0].message.args[0] == "divide by zero encountered during operation" + assert caught_warnings[0].filename == __file__ + + with np.errstate(divide='ignore', invalid='ignore'): + flat_e = np.arange(6) / np.arange(-1, 5) assert_array_nan_equal(res['e'], flat_e.reshape(2, 3)) flat_f = np.arange(6) / np.arange(1, 7) assert_array_nan_equal(res['f'], flat_f.reshape(3, 2)) self.assertTrue(isnan(res['g']).all()) - def test_init(self): - s = Session('test_session.h5') - self.assertEqual(s.names, ['e', 'f', 'g']) + def test_rdiv(self): + sess = self.session.filter(kind=LArray) - s = Session('test_session_ef.xlsx') - self.assertEqual(s.names, ['e', 'f']) + # scalar / session + res = 2 / sess + assert_array_nan_equal(res['e'], 2 / self.e) + assert_array_nan_equal(res['f'], 2 / self.f) + assert_array_nan_equal(res['g'], 2 / self.g) + + # dict(LArray and scalar) - session + other = {'e': self.e, 'f': self.f} + res = other / sess + assert_array_nan_equal(res['e'], self.e / self.e) + assert_array_nan_equal(res['f'], self.f / self.f) + + def test_summary(self): + sess = self.session.filter(kind=LArray) + self.assertEqual(sess.summary(), + "e: a0*, a1*\n \n\n" + "g: a0*, a1*\n \n\n" + "f: a0*, a1*\n \n") + + def test_pickle_roundtrip(self): + original = self.session + s = pickle.dumps(original) + res = pickle.loads(s) + assert res.equals(original) + + def test_local_arrays(self): + local_arr1 = ndtest(2) + _local_arr2 = ndtest(3) + + # exclude private local arrays + s = local_arrays() + s_expected = Session([('local_arr1', local_arr1)]) + assert s.equals(s_expected) + + # all local arrays + s = local_arrays(include_private=True) + s_expected = Session([('local_arr1', local_arr1), ('_local_arr2', _local_arr2)]) + assert s.equals(s_expected) + + def test_global_arrays(self): + # exclude private global arrays + s = global_arrays() + s_expected = Session([('global_arr1', global_arr1)]) + assert s.equals(s_expected) + + # all global arrays + s = global_arrays(include_private=True) + s_expected = Session([('global_arr1', global_arr1), ('_global_arr2', _global_arr2)]) + assert s.equals(s_expected) + + def test_arrays(self): + local_arr1 = ndtest(2) + _local_arr2 = ndtest(3) + + # exclude private arrays + s = arrays() + s_expected = Session([('local_arr1', local_arr1), ('global_arr1', global_arr1)]) + assert s.equals(s_expected) + + # all arrays + s = arrays(include_private=True) + s_expected = Session([('local_arr1', local_arr1), ('_local_arr2', _local_arr2), + ('global_arr1', global_arr1), ('_global_arr2', _global_arr2)]) + assert s.equals(s_expected) - # TODO: format autodetection does not work in this case - # s = Session('test_session_csv') - # self.assertEqual(s.names, ['e', 'f', 'g']) if __name__ == "__main__": - # import doctest - # doctest.testmod(larray.core) - unittest.main() + pytest.main() diff --git a/larray/ufuncs.py b/larray/ufuncs.py deleted file mode 100644 index 765a0c127..000000000 --- a/larray/ufuncs.py +++ /dev/null @@ -1,163 +0,0 @@ -# numpy ufuncs -# http://docs.scipy.org/doc/numpy/reference/routines.math.html - -import numpy as np - -from larray.core import LArray, make_numpy_broadcastable - - -def wrapper(func): - def wrapped(*args, **kwargs): - # TODO: normalize args/kwargs like in LIAM2 so that we can also - # broadcast if args are given via kwargs (eg out=) - args, combined_axes = make_numpy_broadcastable(args) - - # We pass only raw numpy arrays to the ufuncs even though numpy is - # normally meant to handle those case itself via __array_wrap__ - - # There is a problem with np.clip though (and possibly other ufuncs) - # np.clip is roughly equivalent to - # np.maximum(np.minimum(np.asarray(la), high), low) - # the np.asarray(la) is problematic because it lose original labels - # and then tries to get them back from high, where they are possibly - # incomplete if broadcasting happened - - # It fails on "np.minimum(ndarray, LArray)" because it calls - # __array_wrap__(high, result) which cannot work if there was - # broadcasting involved (high has potentially less labels than result). - # it does this because numpy calls __array_wrap__ on the argument with - # the highest __array_priority__ - raw_args = [np.asarray(a) if isinstance(a, LArray) else a - for a in args] - res_data = func(*raw_args, **kwargs) - if combined_axes: - return LArray(res_data, combined_axes) - else: - return res_data - # return func(*args, **kwargs) - wrapped.__name__ = func.__name__ - wrapped.__doc__ = func.__doc__ - return wrapped - - -# Trigonometric functions - -sin = wrapper(np.sin) -cos = wrapper(np.cos) -tan = wrapper(np.tan) -arcsin = wrapper(np.arcsin) -arccos = wrapper(np.arccos) -arctan = wrapper(np.arctan) -hypot = wrapper(np.hypot) -arctan2 = wrapper(np.arctan2) -degrees = wrapper(np.degrees) -radians = wrapper(np.radians) -unwrap = wrapper(np.unwrap) -# deg2rad = wrapper(np.deg2rad) -# rad2deg = wrapper(np.rad2deg) - -# Hyperbolic functions - -sinh = wrapper(np.sinh) -cosh = wrapper(np.cosh) -tanh = wrapper(np.tanh) -arcsinh = wrapper(np.arcsinh) -arccosh = wrapper(np.arccosh) -arctanh = wrapper(np.arctanh) - -# Rounding - -# all 3 are equivalent, I am unsure I should support around and round_ -round = wrapper(np.round) -around = wrapper(np.around) -round_ = wrapper(np.round_) -rint = wrapper(np.rint) -fix = wrapper(np.fix) -floor = wrapper(np.floor) -ceil = wrapper(np.ceil) -trunc = wrapper(np.trunc) - -# Sums, products, differences - -# prod = wrapper(np.prod) -# sum = wrapper(np.sum) -# nansum = wrapper(np.nansum) -# cumprod = wrapper(np.cumprod) -# cumsum = wrapper(np.cumsum) - -# cannot use a simple wrapped ufunc because those ufuncs do not preserve -# shape or dimensions so labels are wrong -# diff = wrapper(np.diff) -# ediff1d = wrapper(np.ediff1d) -# gradient = wrapper(np.gradient) -# cross = wrapper(np.cross) -# trapz = wrapper(np.trapz) - -# Exponents and logarithms - -exp = wrapper(np.exp) -expm1 = wrapper(np.expm1) -exp2 = wrapper(np.exp2) -log = wrapper(np.log) -log10 = wrapper(np.log10) -log2 = wrapper(np.log2) -log1p = wrapper(np.log1p) -logaddexp = wrapper(np.logaddexp) -logaddexp2 = wrapper(np.logaddexp2) - -# Other special functions - -i0 = wrapper(np.i0) -sinc = wrapper(np.sinc) - -# Floating point routines - -signbit = wrapper(np.signbit) -copysign = wrapper(np.copysign) -frexp = wrapper(np.frexp) -ldexp = wrapper(np.ldexp) - -# Arithmetic operations - -# add = wrapper(np.add) -# reciprocal = wrapper(np.reciprocal) -# negative = wrapper(np.negative) -# multiply = wrapper(np.multiply) -# divide = wrapper(np.divide) -# power = wrapper(np.power) -# subtract = wrapper(np.subtract) -# true_divide = wrapper(np.true_divide) -# floor_divide = wrapper(np.floor_divide) -# fmod = wrapper(np.fmod) -# mod = wrapper(np.mod) -modf = wrapper(np.modf) -# remainder = wrapper(np.remainder) - -# Handling complex numbers - -angle = wrapper(np.angle) -real = wrapper(np.real) -imag = wrapper(np.imag) -conj = wrapper(np.conj) - -# Miscellaneous - -convolve = wrapper(np.convolve) -clip = wrapper(np.clip) -sqrt = wrapper(np.sqrt) -# square = wrapper(np.square) -absolute = wrapper(np.absolute) -fabs = wrapper(np.fabs) -sign = wrapper(np.sign) -maximum = wrapper(np.maximum) -minimum = wrapper(np.minimum) -fmax = wrapper(np.fmax) -fmin = wrapper(np.fmin) -nan_to_num = wrapper(np.nan_to_num) -real_if_close = wrapper(np.real_if_close) -interp = wrapper(np.interp) -where = wrapper(np.where) -isnan = wrapper(np.isnan) -isinf = wrapper(np.isinf) - -inverse = wrapper(np.linalg.inv) \ No newline at end of file diff --git a/larray/util/__init__.py b/larray/util/__init__.py new file mode 100644 index 000000000..d1153d414 --- /dev/null +++ b/larray/util/__init__.py @@ -0,0 +1,2 @@ +from __future__ import absolute_import, division, print_function + diff --git a/larray/util/misc.py b/larray/util/misc.py new file mode 100644 index 000000000..edb2bcf8f --- /dev/null +++ b/larray/util/misc.py @@ -0,0 +1,734 @@ +""" +Misc tools +""" +from __future__ import absolute_import, division, print_function + +import __main__ +import math +import itertools +import sys +import operator +import warnings +from textwrap import wrap +from functools import reduce, wraps +from itertools import product +from collections import defaultdict + +try: + from itertools import izip +except ImportError: + izip = zip + +import numpy as np +try: + np.set_printoptions(legacy='1.13') +except TypeError: + pass + +if sys.version_info[0] < 3: + basestring = basestring + bytes = str + unicode = unicode + long = long + PY2 = True +else: + basestring = str + bytes = bytes + unicode = str + long = int + PY2 = False + +if PY2: + from StringIO import StringIO +else: + from io import StringIO + +if PY2: + import cPickle as pickle +else: + import pickle + + +def is_interactive_interpreter(): + try: + # When running using IPython, sys.ps1 is always defined, so we cannot use the standard "hasattr(sys, 'ps1')" + # Additionally, an InProcessInteractiveShell can have a __main__ module with a file + main_lacks_file = not hasattr(__main__, '__file__') + return main_lacks_file or get_ipython().__class__.__name__ == 'InProcessInteractiveShell' + except NameError: + return hasattr(sys, 'ps1') + + +def csv_open(filename, mode='r'): + assert 'b' not in mode and 't' not in mode + if sys.version < '3': + return open(filename, mode + 'b') + else: + return open(filename, mode, newline='', encoding='utf8') + + +def decode(s, encoding='utf-8', errors='strict'): + if isinstance(s, bytes): + return s.decode(encoding, errors) + else: + assert s is None or isinstance(s, unicode), "unexpected " + str(type(s)) + return s + + +def prod(values): + return reduce(operator.mul, values, 1) + + +def format_value(value, missing, fullinfo=False): + if isinstance(value, float) and not fullinfo: + # nans print as "-1.#J", let's use something nicer + if value != value: + return missing + else: + return '%2.f' % value + elif isinstance(value, np.ndarray) and value.shape: + # prevent numpy's default wrapping + return str(list(value)).replace(',', '') + else: + return str(value) + + +def get_col_width(table, index): + return max(len(row[index]) for row in table) + + +def longest_word(s): + """Return length of the longest word in the given string + + Parameters + ---------- + s : str + string to check + Returns + ------- + int + length of longest word + + Examples + -------- + >>> longest_word('12 123 1234') + 4 + >>> longest_word('12 1234 123') + 4 + >>> longest_word('123 12 123') + 3 + >>> longest_word('') + 0 + >>> longest_word(' ') + 0 + """ + return max(len(w) for w in s.split()) if s and not s.isspace() else 0 + + +def get_min_width(table, index): + return max(longest_word(row[index]) for row in table) + + +def table2str(table, missing, fullinfo=False, summarize=True, maxwidth=80, numedges='auto', sep=' ', cont='...', + keepcols=0): + """ + table is a list of lists + :type table: list of list + """ + if not table: + return '' + numcol = max(len(row) for row in table) + # pad rows that have too few columns + for row in table: + if len(row) < numcol: + row.extend([''] * (numcol - len(row))) + formatted = [[format_value(value, missing, fullinfo) for value in row] + for row in table] + maxwidths = [get_col_width(formatted, i) for i in range(numcol)] + + total_colwidth = sum(maxwidths) + sep_width = (numcol - 1) * len(sep) + if total_colwidth + sep_width > maxwidth: + minwidths = [get_min_width(formatted, i) for i in range(numcol)] + available_width = maxwidth - sep_width - sum(minwidths) + if available_width >= 0: + ratio = available_width / total_colwidth + colwidths = [minw + int(maxw * ratio) + for minw, maxw in zip(minwidths, maxwidths)] + else: + # need to exceed maxwidth or hide some data + if summarize: + if numedges == 'auto': + w = sum(minwidths[:keepcols]) + len(cont) + maxedges = (numcol - keepcols) // 2 + if maxedges: + maxi = 0 + for i in range(1, maxedges + 1): + w += minwidths[i] + minwidths[-i] + # + 1 for the "continuation" column + ncol = keepcols + i * 2 + 1 + sepw = (ncol - 1) * len(sep) + maxi = i + if w + sepw > maxwidth: + break + numedges = maxi - 1 + else: + numedges = 0 + head = keepcols+numedges + tail = -numedges if numedges else numcol + formatted = [row[:head] + [cont] + row[tail:] + for row in formatted] + colwidths = minwidths[:head] + [len(cont)] + minwidths[tail:] + else: + colwidths = minwidths + else: + colwidths = maxwidths + + lines = [] + for row in formatted: + wrapped_row = [wrap(value, width) if width > 0 else value + for value, width in zip(row, colwidths)] + maxlines = max(len(value) for value in wrapped_row) + newlines = [[] for _ in range(maxlines)] + for value, width in zip(wrapped_row, colwidths): + for i in range(maxlines): + chunk = value[i] if i < len(value) else '' + newlines[i].append(chunk.rjust(width)) + lines.extend(newlines) + return '\n'.join(sep.join(row) for row in lines) + + +# copied from itertools recipes +def unique(iterable): + """ + Yields all elements once, preserving order. Remember all elements ever seen. + >>> list(unique('AAAABBBCCDAABBB')) + ['A', 'B', 'C', 'D'] + """ + seen = set() + seen_add = seen.add + for element in iterable: + if element not in seen: + seen_add(element) + yield element + + +def unique_list(iterable, res=None, seen=None): + """ + Returns a list of all unique elements, preserving order. Remember all elements ever seen. + >>> unique_list('AAAABBBCCDAABBB') + ['A', 'B', 'C', 'D'] + """ + if res is None: + res = [] + res_append = res.append + if seen is None: + seen = set() + seen_add = seen.add + for element in iterable: + if element not in seen: + seen_add(element) + res_append(element) + return res + + +def duplicates(iterable): + """ + List duplicated elements once, preserving order. Remember all elements ever seen. + """ + # duplicates('AAAABBBCCDAABBB') --> A B C + counts = defaultdict(int) + for element in iterable: + counts[element] += 1 + if counts[element] == 2: + yield element + + +def rproduct(*i): + return product(*[x[::-1] for x in i]) + + +def light_product(*iterables, **kwargs): + """Cartesian product of input iterables, replacing repeated values by empty strings. + + Parameters + ---------- + *iterables : iterable + Input iterables + repeat : int, optional + Number of times to repeat (reuse) input iterables + + Returns + ------- + Generator + + Examples + -------- + >>> list(light_product('ab', range(3))) + [('a', 0), ('', 1), ('', 2), ('b', 0), ('', 1), ('', 2)] + >>> list(light_product('ab', repeat=2)) + [('a', 'a'), ('', 'b'), ('b', 'a'), ('', 'b')] + """ + repeat = kwargs.pop('repeat', 1) + p = product(*iterables, repeat=repeat) + prev_t = (None,) * len(iterables) * repeat + for t in p: + yield tuple(e if e != prev_e else '' + for e, prev_e in zip(t, prev_t)) + prev_t = t + + +def array_nan_equal(a, b): + if np.issubdtype(a.dtype, np.str) and np.issubdtype(b.dtype, np.str): + return np.array_equal(a, b) + else: + return np.all((a == b) | (np.isnan(a) & np.isnan(b))) + + +def unzip(iterable): + return list(zip(*iterable)) + + +class ReprString(str): + def __repr__(self): + return self + + +def array_lookup(array, mapping): + """pass all elements of an np.ndarray through a mapping""" + array = np.asarray(array) + # TODO: this must be cached in the Axis + # TODO: range axes should be optimized (reuse Pandas 0.18 indexes) + sorted_keys, sorted_values = tuple(zip(*sorted(mapping.items()))) + sorted_keys = np.array(sorted_keys) + # prevent an array of booleans from matching a integer axis (sorted_keys) + # XXX: we might want to allow signed and unsigned integers to match against each other + if array.dtype.kind != sorted_keys.dtype.kind: + raise KeyError('key has not the same dtype than axis') + # TODO: it is very important to fail quickly, so guess_axis should try this in chunks + # (first test first element of key, if several axes match, try [1:11] elements, [12:112], [113:1113], ... + if not np.all(np.in1d(array, sorted_keys)): + raise KeyError('all keys not in array') + + sorted_values = np.array(sorted_values) + if not len(array): + return np.empty(0, dtype=sorted_values.dtype) + indices = np.searchsorted(sorted_keys, array) + return sorted_values[indices] + + +def array_lookup2(array, sorted_keys, sorted_values): + """pass all elements of an np.ndarray through a "mapping" """ + if not len(array): + return np.empty(0, dtype=sorted_values.dtype) + + array = np.asarray(array) + # TODO: range axes should be optimized (reuse Pandas 0.18 indexes) + + # prevent an array of booleans from matching a integer axis (sorted_keys) + # XXX: we might want to allow signed and unsigned integers to match against each other + if array.dtype.kind != sorted_keys.dtype.kind: + raise KeyError('key has not the same dtype than axis') + # TODO: it is very important to fail quickly, so guess_axis should try this in chunks + # (first test first element of key, if several axes match, try [1:11] elements, [12:112], [113:1113], ... + if not np.all(np.in1d(array, sorted_keys)): + raise KeyError('all keys not in array') + + indices = np.searchsorted(sorted_keys, array) + return sorted_values[indices] + + +def split_on_condition(seq, condition): + """splits an iterable into two lists depending on a condition + + Parameters + ---------- + seq : iterable + condition : function(e) -> True or False + + Returns + ------- + a, b: list + + Notes + ----- + If the condition can be inlined into a list comprehension, a double list comprehension is faster than this function. + So if performance is crucial, you should inline this function with the condition itself inlined. + """ + a, b = [], [] + append_a, append_b = a.append, b.append + for e in seq: + append_a(e) if condition(e) else append_b(e) + return a, b + + +def split_on_values(seq, values): + """splits an iterable into two lists depending on a list of values + + Parameters + ---------- + seq : iterable + values : iterable + set of values which must go to the first list + + Returns + ------- + a, b: list + """ + values = set(values) + a, b = [], [] + append_a, append_b = a.append, b.append + for e in seq: + append_a(e) if e in values else append_b(e) + return a, b + + +def skip_comment_cells(lines): + def notacomment(v): + return not v.startswith('#') + for line in lines: + stripped_line = list(itertools.takewhile(notacomment, line)) + if stripped_line: + yield stripped_line + + +def strip_rows(lines): + """ + returns an iterator of lines with trailing blank (empty or + which contain only space) cells. + """ + def isblank(s): + return s == '' or s.isspace() + for line in lines: + rev_line = list(itertools.dropwhile(isblank, reversed(line))) + yield list(reversed(rev_line)) + + +def size2str(value): + """ + >>> size2str(0) + '0 bytes' + >>> size2str(100) + '100 bytes' + >>> size2str(1023) + '1023 bytes' + >>> size2str(1024) + '1.00 Kb' + >>> size2str(2000) + '1.95 Kb' + >>> size2str(10000000) + '9.54 Mb' + >>> size2str(1.27 * 1024 ** 3) + '1.27 Gb' + """ + units = ["bytes", "Kb", "Mb", "Gb", "Tb", "Pb"] + scale = int(math.log(value, 1024)) if value else 0 + fmt = "%.2f %s" if scale else "%d %s" + return fmt % (value / 1024.0 ** scale, units[scale]) + + +def find_closing_chr(s, start=0): + """ + + Parameters + ---------- + s : str + string to search the characters. s[start] must be in '({[' + start : int, optional + position in the string from which to start searching + + Returns + ------- + position of matching brace + + Examples + -------- + >>> find_closing_chr('(a) + (b)') + 2 + >>> find_closing_chr('(a) + (b)', 6) + 8 + >>> find_closing_chr('(a{b[c(d)e]f}g)') + 14 + >>> find_closing_chr('(a{b[c(d)e]f}g)', 2) + 12 + >>> find_closing_chr('(a{b[c(d)e]f}g)', 4) + 10 + >>> find_closing_chr('(a{b[c(d)e]f}g)', 6) + 8 + >>> find_closing_chr('((a) + (b))') + 10 + >>> find_closing_chr('((a) + (b))') + 10 + >>> find_closing_chr('((a) + (b))') + 10 + >>> find_closing_chr('({)}') + Traceback (most recent call last): + ... + ValueError: malformed expression: expected '}' but found ')' + >>> find_closing_chr('({}})') + Traceback (most recent call last): + ... + ValueError: malformed expression: expected ')' but found '}' + >>> find_closing_chr('}()') + Traceback (most recent call last): + ... + ValueError: malformed expression: found '}' before '{' + >>> find_closing_chr('(()') + Traceback (most recent call last): + ... + ValueError: malformed expression: reached end of string without finding the expected ')' + """ + opening, closing = '({[', ')}]' + match = {o: c for o, c in zip(opening, closing)} + match.update({c: o for o, c in zip(opening, closing)}) + opening_set, closing_set = set(opening), set(closing) + + needle = s[start] + assert needle in match + last_open = [] + for pos in range(start, len(s)): + c = s[pos] + if c in match: + if c in opening_set: + last_open.append(c) + if c in closing_set: + if not last_open: + raise ValueError("malformed expression: found '{}' before '{}'".format(c, match[c])) + expected = match[last_open.pop()] + if c != expected: + raise ValueError("malformed expression: expected '{}' but found '{}'".format(expected, c)) + if not last_open: + assert c == match[needle] + return pos + raise ValueError("malformed expression: reached end of string without finding the expected '{}'" + .format(match[needle])) + + +def float_error_handler_factory(stacklevel): + def error_handler(error, flag): + if error == 'invalid value': + error = 'invalid value (NaN)' + extra = ' (this is typically caused by a 0 / 0)' + else: + extra = '' + warnings.warn("{} encountered during operation{}".format(error, extra), RuntimeWarning, stacklevel=stacklevel) + return error_handler + + +def _isintstring(s): + """ + Return True if the passed string represents an integer. + Zero padded integers are considered as strings and not integers. + + Parameters + ---------- + s : str + string to test if representing an integer. + + Examples + -------- + >>> _isintstring('12') + True + >>> _isintstring('-12') + True + >>> _isintstring('a1') + False + >>> _isintstring('01') + False + """ + def isposint(s): + # exclude zero padded strings + return s.isdigit() and not (len(s) > 1 and s[0] == '0') + return isposint(s) or (len(s) > 1 and s[0] == '-' and isposint(s[1:])) + + +def _parse_bound(s, stack_depth=1, parse_int=True): + """Parse a string representing a single value, converting int-like strings to integers and evaluating expressions + within {}. + + Parameters + ---------- + s : str + string to evaluate + stack_depth : int + how deep to go in the stack to get local variables for evaluating {expressions}. + + Returns + ------- + any + + Examples + -------- + >>> _parse_bound(' a ') + 'a' + >>> # returns None + >>> _parse_bound(' ') + >>> ext = 1 + >>> _parse_bound(' {ext + 1} ') + 2 + >>> _parse_bound('42') + 42 + >>> _parse_bound('01') + '01' + """ + s = s.strip() + if s == '': + return None + elif s[0] == '{': + expr = s[1:find_closing_chr(s)] + return eval(expr, sys._getframe(stack_depth).f_locals) + elif parse_int and _isintstring(s): + return int(s) + else: + return s + + +def _isnoneslice(v): + """ + Checks if input is slice(None) object. + """ + return isinstance(v, slice) and v.start is None and v.stop is None and v.step is None + + +def _seq_summary(seq, n=3, repr_func=repr, sep=' '): + """ + Returns a string representing a sequence by showing only the n first and last elements. + + Examples + -------- + >>> _seq_summary(range(10), 2) + '0 1 ... 8 9' + """ + if len(seq) <= 2 * n: + short_seq = [repr_func(v) for v in seq] + else: + short_seq = [repr_func(v) for v in seq[:n]] + ['...'] + [repr_func(v) for v in seq[-n:]] + return sep.join(short_seq) + + +def index_by_id(seq, value): + """ + Returns position of an object in a sequence. + + Raises an error if the object is not in the list. + + Parameters + ---------- + seq : sequence + Any sequence (list, tuple, str, unicode). + + value : object + Object for which you want to retrieve its position in the sequence. + + Raises + ------ + ValueError + If `value` object is not contained in the sequence. + + Examples + -------- + >>> from larray import Axis + >>> age = Axis('age=0..9') + >>> sex = Axis('sex=M,F') + >>> time = Axis('time=2007..2010') + >>> index_by_id([age, sex, time], sex) + 1 + >>> gender = Axis('sex=M,F') + >>> index_by_id([age, sex, time], gender) + Traceback (most recent call last): + ... + ValueError: sex is not in list + >>> gender = sex + >>> index_by_id([age, sex, time], gender) + 1 + """ + for i, item in enumerate(seq): + if item is value: + return i + raise ValueError("%s is not in list" % value) + + +def renamed_to(newfunc, old_name, stacklevel=2): + def wrapper(*args, **kwargs): + msg = "{}() is deprecated. Use {}() instead.".format(old_name, newfunc.__name__) + warnings.warn(msg, FutureWarning, stacklevel=stacklevel) + return newfunc(*args, **kwargs) + return wrapper + +# deprecate_kwarg is derived from pandas.util._decorators (0.21) +def deprecate_kwarg(old_arg_name, new_arg_name, mapping=None, arg_converter=None, stacklevel=2): + if mapping is not None and not isinstance(mapping, dict): + raise TypeError("mapping from old to new argument values must be dict!") + def _deprecate_kwarg(func): + @wraps(func) + def wrapper(*args, **kwargs): + old_arg_value = kwargs.pop(old_arg_name, None) + if old_arg_value is not None: + if mapping is not None: + new_arg_value = mapping.get(old_arg_value, old_arg_value) + elif arg_converter is not None: + new_arg_value = arg_converter(old_arg_value) + else: + new_arg_value = old_arg_value + msg = "The {old_name}={old_val!r} keyword is deprecated, use {new_name}={new_val!r} instead"\ + .format(old_name=old_arg_name, old_val=old_arg_value, new_name=new_arg_name, + new_val=new_arg_value) + + warnings.warn(msg, FutureWarning, stacklevel=stacklevel) + if new_arg_name in kwargs: + msg = "Can only specify '{old_name}' or '{new_name}', not both"\ + .format(old_name=old_arg_name, new_name=new_arg_name) + raise ValueError(msg) + else: + kwargs[new_arg_name] = new_arg_value + return func(*args, **kwargs) + return wrapper + return _deprecate_kwarg + + +def inverseop(opname): + comparison_ops = { + 'lt': 'gt', + 'gt': 'lt', + 'le': 'ge', + 'ge': 'le', + 'eq': 'eq', + 'ne': 'ne' + } + if opname in comparison_ops: + return comparison_ops[opname] + else: + return 'r' + opname + + +_numeric_kinds = 'buifc' # Boolean, Unsigned integer, Integer, Float, Complex +_string_kinds = 'SU' # String, Unicode +_meta_kind = {k: 'str' for k in _string_kinds} +_meta_kind.update({k: 'numeric' for k in _numeric_kinds}) + + +def common_type(arrays): + """ + Returns a type which is common to the input arrays. + All input arrays can be safely cast to the returned dtype without loss of information. + + Notes + ----- + If list of arrays mixes 'numeric' and 'string' types, the function returns 'object' as common type. + """ + arrays = [np.asarray(a) for a in arrays] + dtypes = [a.dtype for a in arrays] + meta_kinds = [_meta_kind.get(dt.kind, 'other') for dt in dtypes] + # mixing string and numeric => object + if any(mk != meta_kinds[0] for mk in meta_kinds[1:]): + return object + elif meta_kinds[0] == 'numeric': + return np.find_common_type(dtypes, []) + elif meta_kinds[0] == 'str': + need_unicode = any(dt.kind == 'U' for dt in dtypes) + # unicode are coded with 4 bytes + max_size = max(dt.itemsize // 4 if dt.kind == 'U' else dt.itemsize + for dt in dtypes) + return np.dtype(('U' if need_unicode else 'S', max_size)) + else: + return object diff --git a/larray/util/oset.py b/larray/util/oset.py new file mode 100644 index 000000000..e99340980 --- /dev/null +++ b/larray/util/oset.py @@ -0,0 +1,105 @@ +# copy-pasted from SQLAlchemy util/_collections.py + +# Copyright (C) 2005-2015 the SQLAlchemy authors and contributors +# +# +# This module is part of SQLAlchemy and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php + +from larray.util.misc import unique_list + + +class OrderedSet(set): + def __init__(self, d=None): + set.__init__(self) + if d is not None: + self._list = unique_list(d) + set.update(self, self._list) + else: + self._list = [] + + def add(self, element): + if element not in self: + self._list.append(element) + set.add(self, element) + + def remove(self, element): + set.remove(self, element) + self._list.remove(element) + + def insert(self, pos, element): + if element not in self: + self._list.insert(pos, element) + set.add(self, element) + + def discard(self, element): + if element in self: + self._list.remove(element) + set.remove(self, element) + + def clear(self): + set.clear(self) + self._list = [] + + def __getitem__(self, key): + return self._list[key] + + def __iter__(self): + return iter(self._list) + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, self._list) + + __str__ = __repr__ + + def update(self, iterable): + for e in iterable: + if e not in self: + self._list.append(e) + set.add(self, e) + return self + __ior__ = update + + def union(self, other): + result = self.__class__(self) + result.update(other) + return result + __or__ = union + __add__ = union + + def intersection(self, other): + other = set(other) + return self.__class__(a for a in self if a in other) + __and__ = intersection + + def symmetric_difference(self, other): + other = set(other) + result = self.__class__(a for a in self if a not in other) + result.update(a for a in other if a not in self) + return result + __xor__ = symmetric_difference + + def difference(self, other): + other = set(other) + return self.__class__(a for a in self if a not in other) + __sub__ = difference + + def intersection_update(self, other): + other = set(other) + set.intersection_update(self, other) + self._list = [a for a in self._list if a in other] + return self + __iand__ = intersection_update + + def symmetric_difference_update(self, other): + set.symmetric_difference_update(self, other) + self._list = [a for a in self._list if a in self] + self._list += [a for a in other._list if a in self] + return self + __ixor__ = symmetric_difference_update + + def difference_update(self, other): + set.difference_update(self, other) + self._list = [a for a in self._list if a in self] + return self + __isub__ = difference_update diff --git a/larray/utils.py b/larray/utils.py deleted file mode 100644 index e03f23f1b..000000000 --- a/larray/utils.py +++ /dev/null @@ -1,310 +0,0 @@ -""" -Misc tools -""" -from __future__ import absolute_import, division, print_function - -import itertools -import sys -import operator -from textwrap import wrap -from functools import reduce -from itertools import product -from collections import defaultdict - -try: - from itertools import izip -except ImportError: - izip = zip - -import numpy as np - -if sys.version < '3': - basestring = basestring - bytes = str - long = long - PY3 = False -else: - basestring = str - unicode = str - long = int - PY3 = True - - -def csv_open(filename, mode='r'): - assert 'b' not in mode and 't' not in mode - if sys.version < '3': - return open(filename, mode + 'b') - else: - return open(filename, mode, newline='', encoding='utf8') - - -def decode(s, encoding='utf-8', errors='strict'): - if isinstance(s, bytes): - return s.decode(encoding, errors) - else: - assert s is None or isinstance(s, unicode), "unexpected " + str(type(s)) - return s - - -def prod(values): - return reduce(operator.mul, values, 1) - - -def format_value(value, missing, fullinfo=False): - if isinstance(value, float) and not fullinfo: - # nans print as "-1.#J", let's use something nicer - if value != value: - return missing - else: - return '%2.f' % value - elif isinstance(value, np.ndarray) and value.shape: - # prevent numpy's default wrapping - return str(list(value)).replace(',', '') - else: - return str(value) - - -def get_col_width(table, index): - return max(len(row[index]) for row in table) - - -def longest_word(s): - return max(len(w) for w in s.split()) if s else 0 - - -def get_min_width(table, index): - return max(longest_word(row[index]) for row in table) - - -def table2str(table, missing, fullinfo=False, summarize=True, - maxwidth=80, numedges='auto', sep=' | ', cont='...', keepcols=0): - """ - table is a list of lists - :type table: list of list - """ - if not table: - return '' - numcol = max(len(row) for row in table) - # pad rows that have too few columns - for row in table: - if len(row) < numcol: - row.extend([''] * (numcol - len(row))) - formatted = [[format_value(value, missing, fullinfo) for value in row] - for row in table] - maxwidths = [get_col_width(formatted, i) for i in range(numcol)] - - total_colwidth = sum(maxwidths) - sep_width = (numcol - 1) * len(sep) - if total_colwidth + sep_width > maxwidth: - minwidths = [get_min_width(formatted, i) for i in range(numcol)] - available_width = maxwidth - sep_width - sum(minwidths) - if available_width >= 0: - ratio = available_width / total_colwidth - colwidths = [minw + int(maxw * ratio) - for minw, maxw in zip(minwidths, maxwidths)] - else: - # need to exceed maxwidth or hide some data - if summarize: - if numedges == 'auto': - w = sum(minwidths[:keepcols]) + len(cont) - maxedges = (numcol - keepcols) // 2 - if maxedges: - maxi = 0 - for i in range(1, maxedges + 1): - w += minwidths[i] + minwidths[-i] - # + 1 for the "continuation" column - ncol = keepcols + i * 2 + 1 - sepw = (ncol - 1) * len(sep) - maxi = i - if w + sepw > maxwidth: - break - numedges = maxi - 1 - else: - numedges = 0 - head = keepcols+numedges - tail = -numedges if numedges else numcol - formatted = [row[:head] + [cont] + row[tail:] - for row in formatted] - colwidths = minwidths[:head] + [len(cont)] + minwidths[tail:] - else: - colwidths = minwidths - else: - colwidths = maxwidths - - lines = [] - for row in formatted: - wrapped_row = [wrap(value, width) - for value, width in zip(row, colwidths)] - maxlines = max(len(value) for value in wrapped_row) - newlines = [[] for _ in range(maxlines)] - for value, width in zip(wrapped_row, colwidths): - for i in range(maxlines): - chunk = value[i] if i < len(value) else '' - newlines[i].append(chunk.rjust(width)) - lines.extend(newlines) - return '\n'.join(sep.join(row) for row in lines) - - -# copied from itertools recipes -def unique(iterable): - """ - Yields all elements once, preserving order. Remember all elements ever - seen. - >>> list(unique('AAAABBBCCDAABBB')) - ['A', 'B', 'C', 'D'] - """ - seen = set() - seen_add = seen.add - for element in iterable: - if element not in seen: - seen_add(element) - yield element - - -def duplicates(iterable): - """ - List duplicated elements once, preserving order. Remember all elements ever - seen. - """ - # duplicates('AAAABBBCCDAABBB') --> A B C - counts = defaultdict(int) - for element in iterable: - counts[element] += 1 - if counts[element] == 2: - yield element - - -def rproduct(*i): - return product(*[x[::-1] for x in i]) - - -def array_nan_equal(a, b): - if np.issubdtype(a.dtype, np.str) and np.issubdtype(b.dtype, np.str): - return np.array_equal(a, b) - else: - return np.all((a == b) | (np.isnan(a) & np.isnan(b))) - - -def unzip(iterable): - return list(zip(*iterable)) - - -class ReprString(str): - def __repr__(self): - return self - - -def array_lookup(array, mapping): - """pass all elements of an np.ndarray through a mapping""" - array = np.asarray(array) - # TODO: this must be cached in the Axis - # TODO: range axes should be optimized (reuse Pandas 0.18 indexes) - sorted_keys, sorted_values = tuple(zip(*sorted(mapping.items()))) - sorted_keys = np.array(sorted_keys) - # prevent an array of booleans from matching a integer axis (sorted_keys) - # XXX: we might want to allow signed and unsigned integers to match - # against each other - if array.dtype.kind != sorted_keys.dtype.kind: - raise KeyError('key has not the same dtype than axis') - # TODO: it is very important to fail quickly, so guess_axis should try - # this in chunks (first test first element of key, if several axes match, - # try [1:11] elements, [12:112], [113:1113], ... - if not np.all(np.in1d(array, sorted_keys)): - raise KeyError('all keys not in array') - - sorted_values = np.array(sorted_values) - if not len(array): - return np.empty(0, dtype=sorted_values.dtype) - indices = np.searchsorted(sorted_keys, array) - return sorted_values[indices] - - -def array_lookup2(array, sorted_keys, sorted_values): - """pass all elements of an np.ndarray through a "mapping" """ - if not len(array): - return np.empty(0, dtype=sorted_values.dtype) - - array = np.asarray(array) - # TODO: this must be cached in the Axis - # TODO: range axes should be optimized (reuse Pandas 0.18 indexes) - - # prevent an array of booleans from matching a integer axis (sorted_keys) - # XXX: we might want to allow signed and unsigned integers to match - # against each other - if array.dtype.kind != sorted_keys.dtype.kind: - raise KeyError('key has not the same dtype than axis') - # TODO: it is very important to fail quickly, so guess_axis should try - # this in chunks (first test first element of key, if several axes match, - # try [1:11] elements, [12:112], [113:1113], ... - if not np.all(np.in1d(array, sorted_keys)): - raise KeyError('all keys not in array') - - indices = np.searchsorted(sorted_keys, array) - return sorted_values[indices] - - -def split_on_condition(seq, condition): - """splits an iterable into two lists depending on a condition - - Parameters - ---------- - seq : iterable - condition : function(e) -> True or False - - Returns - ------- - a, b: list - - Notes - ----- - If the condition can be inlined into a list comprehension, a double list - comprehension is faster than this function. So if performance is crucial, - you should inline this function with the condition itself inlined. - """ - a, b = [], [] - append_a, append_b = a.append, b.append - for e in seq: - append_a(e) if condition(e) else append_b(e) - return a, b - - -def split_on_values(seq, values): - """splits an iterable into two lists depending on a list of values - - Parameters - ---------- - seq : iterable - values : iterable - set of values which must go to the first list - - Returns - ------- - a, b: list - """ - values = set(values) - a, b = [], [] - append_a, append_b = a.append, b.append - for e in seq: - append_a(e) if e in values else append_b(e) - return a, b - - -def skip_comment_cells(lines): - def notacomment(v): - return not v.startswith('#') - for line in lines: - stripped_line = list(itertools.takewhile(notacomment, line)) - if stripped_line: - yield stripped_line - - -def strip_rows(lines): - """ - returns an iterator of lines with trailing blank (empty or - which contain only space) cells. - """ - def isblank(s): - return s == '' or s.isspace() - for line in lines: - rev_line = list(itertools.dropwhile(isblank, reversed(line))) - yield list(reversed(rev_line)) diff --git a/larray/viewer.py b/larray/viewer.py deleted file mode 100644 index 89e75356f..000000000 --- a/larray/viewer.py +++ /dev/null @@ -1,1968 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright © 2009-2012 Pierre Raybaut -# Copyright © 2015-2016 Gaëtan de Menten -# Licensed under the terms of the MIT License - -# based on -# github.com/spyder-ide/spyder/blob/master/spyderlib/widgets/arrayeditor.py - -""" -Array Editor Dialog based on Qt -""" - -# pylint: disable=C0103 -# pylint: disable=R0903 -# pylint: disable=R0911 -# pylint: disable=R0201 - -# Note that the canonical way to implement filters in a TableView would -# be to use a QSortFilterProxyModel. I would need to reimplement its -# filterAcceptsColumn and filterAcceptsRow methods, but that seems pretty -# doable, however I think it would be too slow on large arrays (because it -# suppose you have the whole array in your model) and would probably not play -# well with the partial/progressive load we have currently implemented. I have -# also read quite a few people complaining about speed issues with those. - -# TODO: -# * drag & drop to reorder axes -# http://zetcode.com/gui/pyqt4/dragdrop/ -# http://stackoverflow.com/questions/10264040/how-to-drag-and-drop-into-a-qtablewidget-pyqt -# http://stackoverflow.com/questions/3458542/multiple-drag-and-drop-in-pyqt4 -# * keep header columns & rows visible ("frozen") -# http://doc.qt.io/qt-5/qtwidgets-itemviews-frozencolumn-example.html -# * document default icons situation (limitations) -# * document paint speed experiments -# * filter on headers. In fact this is not a good idea, because that prevents -# selecting whole columns, which is handy. So a separate row for headers, -# like in Excel seems better. -# * tooltip on header with current filter - -# * selection change -> select headers too -# * nicer error on plot with more than one row/column -# OR -# * plotting a subset should probably (to think) go via LArray/pandas objects -# so that I have the headers info in the plots (and do not have to deal with -# them manually) -# > need to be generic -# * copy to clipboard possibly too -# ? automatic change digits on resize column -# => different format per column, which is problematic UI-wise -# * keep "headers" visible -# * keyboard shortcut for filter each dim -# * tab in a filter combo, brings up next filter combo -# * view/edit DataFrames too -# * view/edit LArray over Pandas -# * resubmit editor back for inclusion in Spyder -# * custom delegates for each type (spinner for int, checkbox for bool, ...) -# ? "light" headers (do not repeat the same header several times (on the screen) - -from __future__ import print_function - -from itertools import chain -import math -import sys - -from PyQt4.QtGui import (QApplication, QHBoxLayout, QColor, QTableView, - QItemDelegate, QListWidget, QSplitter, - QLineEdit, QCheckBox, QGridLayout, - QDoubleValidator, QIntValidator, - QDialog, QDialogButtonBox, QPushButton, - QMessageBox, QMenu, - QKeySequence, QLabel, - QSpinBox, QWidget, QVBoxLayout, - QFont, QAction, QItemSelection, - QItemSelectionModel, QItemSelectionRange, - QIcon, QStyle, QFontMetrics, QToolTip, QCursor) -from PyQt4.QtCore import (Qt, QModelIndex, QAbstractTableModel, QPoint, - QVariant, pyqtSlot as Slot) - -import numpy as np - -try: - import matplotlib - matplotlib.use('Qt4Agg') - del matplotlib - import matplotlib.pyplot as plt - from matplotlib.backends.backend_qt4agg import FigureCanvas as FigureCanvas - from matplotlib.backends.backend_qt4agg \ - import NavigationToolbar2QT as NavigationToolbar - matplotlib_present = True -except ImportError: - matplotlib_present = False - -try: - import xlwings as xw -except ImportError: - xw = None - -from larray.combo import FilterComboBox, FilterMenu -import larray as la - - -def _get_font(family, size, bold=False, italic=False): - weight = QFont.Bold if bold else QFont.Normal - font = QFont(family, size, weight) - if italic: - font.setItalic(True) - return to_qvariant(font) - -# Spyder compat -# ------------- - -PY2 = sys.version[0] == '2' - - -class IconManager(object): - def icon(self, ref): - # By default, only X11 will support themed icons. In order to use - # themed icons on Mac and Windows, you will have to bundle a compliant - # theme in one of your PySide.QtGui.QIcon.themeSearchPaths() and set the - # appropriate PySide.QtGui.QIcon.themeName() . - return QIcon.fromTheme(ref) -ima = IconManager() - - -def get_font(section): - return _get_font('Calibri', 11) - - -def to_qvariant(obj=None): - return obj - - -def from_qvariant(qobj=None, pytype=None): - # FIXME: force API level 2 instead of handling this - if isinstance(qobj, QVariant): - assert pytype is str - return pytype(qobj.toString()) - return qobj - - -def keybinding(attr): - """Return keybinding""" - ks = getattr(QKeySequence, attr) - return QKeySequence.keyBindings(ks)[0] - - -def create_action(parent, text, icon=None, triggered=None, shortcut=None): - """Create a QAction""" - action = QAction(text, parent) - if triggered is not None: - action.triggered.connect(triggered) - if icon is not None: - action.setIcon(icon) - if shortcut is not None: - action.setShortcut(shortcut) - action.setShortcutContext(Qt.WidgetShortcut) - return action - - -def _(text): - return text - - -def to_text_string(obj, encoding=None): - """Convert `obj` to (unicode) text string""" - if PY2: - # Python 2 - if encoding is None: - return unicode(obj) - else: - return unicode(obj, encoding) - else: - # Python 3 - if encoding is None: - return str(obj) - elif isinstance(obj, str): - # In case this function is not used properly, this could happen - return obj - else: - return str(obj, encoding) - - -def qapplication(): - return QApplication(sys.argv) - - -# ======================= - -# Note: string and unicode data types will be formatted with '%s' (see below) -SUPPORTED_FORMATS = { - 'object': '%s', - 'single': '%.2f', - 'double': '%.2f', - 'float_': '%.2f', - 'longfloat': '%.2f', - 'float32': '%.2f', - 'float64': '%.2f', - 'float96': '%.2f', - 'float128': '%.2f', - 'csingle': '%r', - 'complex_': '%r', - 'clongfloat': '%r', - 'complex64': '%r', - 'complex128': '%r', - 'complex192': '%r', - 'complex256': '%r', - 'byte': '%d', - 'short': '%d', - 'intc': '%d', - 'int_': '%d', - 'longlong': '%d', - 'intp': '%d', - 'int8': '%d', - 'int16': '%d', - 'int32': '%d', - 'int64': '%d', - 'ubyte': '%d', - 'ushort': '%d', - 'uintc': '%d', - 'uint': '%d', - 'ulonglong': '%d', - 'uintp': '%d', - 'uint8': '%d', - 'uint16': '%d', - 'uint32': '%d', - 'uint64': '%d', - 'bool_': '%r', - 'bool8': '%r', - 'bool': '%r', -} - - -LARGE_SIZE = 5e5 -LARGE_NROWS = 1e5 -LARGE_COLS = 60 - - -def clear_layout(layout): - for i in reversed(range(layout.count())): - item = layout.itemAt(i) - widget = item.widget() - if widget is not None: - # widget.setParent(None) - widget.deleteLater() - layout.removeItem(item) - - -class Product(object): - def __init__(self, arrays): - self.arrays = arrays - assert len(arrays) - shape = [len(a) for a in self.arrays] - self.div_mod = [(int(np.prod(shape[i + 1:])), shape[i]) - for i in range(len(shape))] - self.length = np.prod(shape) - - def to_tuple(self, key): - return tuple(key // div % mod for div, mod in self.div_mod) - - def __len__(self): - return self.length - - def __getitem__(self, key): - if isinstance(key, (int, np.integer)): - return tuple(array[i] - for array, i in zip(self.arrays, self.to_tuple(key))) - else: - assert isinstance(key, slice), \ - "key (%s) has invalid type (%s)" % (key, type(key)) - start, stop, step = key.start, key.stop, key.step - if start is None: - start = 0 - if stop is None: - stop = self.length - if step is None: - step = 1 - - return [tuple(array[i] - for array, i in zip(self.arrays, self.to_tuple(i))) - for i in range(start, stop, step)] - - -def is_float(dtype): - """Return True if datatype dtype is a float kind""" - return ('float' in dtype.name) or dtype.name in ['single', 'double'] - - -def is_number(dtype): - """Return True is datatype dtype is a number kind""" - return is_float(dtype) or ('int' in dtype.name) or ('long' in dtype.name) \ - or ('short' in dtype.name) - - -def get_idx_rect(index_list): - """Extract the boundaries from a list of indexes""" - rows = [i.row() for i in index_list] - cols = [i.column() for i in index_list] - return min(rows), max(rows), min(cols), max(cols) - - -class ArrayModel(QAbstractTableModel): - """Array Editor Table Model""" - - ROWS_TO_LOAD = 500 - COLS_TO_LOAD = 40 - - def __init__(self, data=None, format="%.3f", xlabels=None, ylabels=None, - readonly=False, font=None, parent=None, - bg_gradient=None, bg_value=None, minvalue=None, maxvalue=None): - QAbstractTableModel.__init__(self) - - self.dialog = parent - self.readonly = readonly - self._format = format - - # Backgroundcolor settings - # TODO: use LinearGradient - self.bg_gradient = bg_gradient - self.bg_value = bg_value - # self.bgfunc = bgfunc - huerange = [.66, .99] # Hue - self.sat = .7 # Saturation - self.val = 1. # Value - self.alp = .6 # Alpha-channel - self.hue0 = huerange[0] - self.dhue = huerange[1] - huerange[0] - self.bgcolor_enabled = True - # hue = self.hue0 - # color = QColor.fromHsvF(hue, self.sat, self.val, self.alp) - # self.color = to_qvariant(color) - - if font is None: - font = get_font("arreditor") - self.font = font - bold_font = get_font("arreditor") - bold_font.setBold(True) - self.bold_font = bold_font - - self.minvalue = minvalue - self.maxvalue = maxvalue - # TODO: check that data respects minvalue/maxvalue - self._set_data(data, xlabels, ylabels) - - def get_format(self): - """Return current format""" - # Avoid accessing the private attribute _format from outside - return self._format - - def get_data(self): - """Return data""" - return self._data - - def set_data(self, data, xlabels=None, ylabels=None, changes=None): - self._set_data(data, xlabels, ylabels, changes) - self.reset() - - def _set_data(self, data, xlabels, ylabels, changes=None): - if changes is None: - changes = {} - if data is None: - data = np.empty(0, dtype=np.int8).reshape(0, 0) - if data.dtype.names is None: - dtn = data.dtype.name - if dtn not in SUPPORTED_FORMATS and not dtn.startswith('str') \ - and not dtn.startswith('unicode'): - msg = _("%s arrays are currently not supported") - QMessageBox.critical(self.dialog, "Error", - msg % data.dtype.name) - return - assert data.ndim == 2 - self.test_array = np.array([0], dtype=data.dtype) - - # for complex numbers, shading will be based on absolute value - # but for all other types it will be the real part - if data.dtype in (np.complex64, np.complex128): - self.color_func = np.abs - else: - self.color_func = np.real - assert isinstance(changes, dict) - self.changes = changes - self._data = data - if xlabels is None: - xlabels = [[]] - self.xlabels = xlabels - if ylabels is None: - ylabels = [[]] - self.ylabels = ylabels - self.total_rows = self._data.shape[0] - self.total_cols = self._data.shape[1] - size = self.total_rows * self.total_cols - self.reset_minmax() - # Use paging when the total size, number of rows or number of - # columns is too large - if size > LARGE_SIZE: - self.rows_loaded = min(self.ROWS_TO_LOAD, self.total_rows) - self.cols_loaded = min(self.COLS_TO_LOAD, self.total_cols) - else: - if self.total_rows > LARGE_NROWS: - self.rows_loaded = self.ROWS_TO_LOAD - else: - self.rows_loaded = self.total_rows - if self.total_cols > LARGE_COLS: - self.cols_loaded = self.COLS_TO_LOAD - else: - self.cols_loaded = self.total_cols - - def reset_minmax(self): - # this will be awful to get right, because ideally, we should - # include self.changes.values() and ignore values corresponding to - # self.changes.keys() - data = self.get_values() - try: - color_value = self.color_func(data) - self.vmin = np.nanmin(color_value) - self.vmax = np.nanmax(color_value) - if self.vmax == self.vmin: - self.vmin -= 1 - self.bgcolor_enabled = True - # ValueError for empty arrays - except (TypeError, ValueError): - self.vmin = None - self.vmax = None - self.bgcolor_enabled = False - - def set_format(self, format): - """Change display format""" - self._format = format - self.reset() - - def columnCount(self, qindex=QModelIndex()): - """Array column number""" - return len(self.ylabels) - 1 + self.cols_loaded - - def rowCount(self, qindex=QModelIndex()): - """Array row number""" - return len(self.xlabels) - 1 + self.rows_loaded - - def fetch_more_rows(self): - if self.total_rows > self.rows_loaded: - remainder = self.total_rows - self.rows_loaded - items_to_fetch = min(remainder, self.ROWS_TO_LOAD) - self.beginInsertRows(QModelIndex(), self.rows_loaded, - self.rows_loaded + items_to_fetch - 1) - self.rows_loaded += items_to_fetch - self.endInsertRows() - - def fetch_more_columns(self): - if self.total_cols > self.cols_loaded: - remainder = self.total_cols - self.cols_loaded - items_to_fetch = min(remainder, self.COLS_TO_LOAD) - self.beginInsertColumns(QModelIndex(), self.cols_loaded, - self.cols_loaded + items_to_fetch - 1) - self.cols_loaded += items_to_fetch - self.endInsertColumns() - - def bgcolor(self, state): - """Toggle backgroundcolor""" - self.bgcolor_enabled = state > 0 - self.reset() - - def get_value(self, index): - i = index.row() - len(self.xlabels) + 1 - j = index.column() - len(self.ylabels) + 1 - if i < 0 and j < 0: - return "" - if i < 0: - return str(self.xlabels[i][j]) - if j < 0: - return str(self.ylabels[j][i]) - return self.changes.get((i, j), self._data[i, j]) - - def data(self, index, role=Qt.DisplayRole): - """Cell content""" - if not index.isValid(): - return to_qvariant() - # if role == Qt.DecorationRole: - # return ima.icon('editcopy') - # if role == Qt.DisplayRole: - # return "" - - if role == Qt.TextAlignmentRole: - if (index.row() < len(self.xlabels) - 1) or \ - (index.column() < len(self.ylabels) - 1): - return to_qvariant(int(Qt.AlignCenter | Qt.AlignVCenter)) - else: - return to_qvariant(int(Qt.AlignRight | Qt.AlignVCenter)) - - elif role == Qt.FontRole: - if (index.row() < len(self.xlabels) - 1) or \ - (index.column() < len(self.ylabels) - 1): - return self.bold_font - else: - return self.font - # row, column = index.row(), index.column() - value = self.get_value(index) - if role == Qt.DisplayRole: - # if column == 0: - # return to_qvariant(value) - if value is np.ma.masked: - return '' - # for headers - elif isinstance(value, str) and not isinstance(value, np.str_): - return value - else: - return to_qvariant(self._format % value) - - elif role == Qt.BackgroundColorRole: - if (index.row() < len(self.xlabels) - 1) or \ - (index.column() < len(self.ylabels) - 1): - color = QColor(Qt.lightGray) - color.setAlphaF(.4) - return color - elif self.bgcolor_enabled and value is not np.ma.masked: - if self.bg_gradient is None: - hue = self.hue0 + \ - self.dhue * (self.vmax - self.color_func(value)) \ - / (self.vmax - self.vmin) - hue = float(np.abs(hue)) - color = QColor.fromHsvF(hue, self.sat, self.val, self.alp) - return to_qvariant(color) - else: - bg_value = self.bg_value - x = index.row() - len(self.xlabels) + 1 - y = index.column() - len(self.ylabels) + 1 - # FIXME: this is buggy on filtered data. We should change - # bg_value when changing the filter. - idx = y + x * bg_value.shape[-1] - value = bg_value.data.flat[idx] - return self.bg_gradient[value] - elif role == Qt.ToolTipRole: - return to_qvariant(repr(value)) - return to_qvariant() - - def get_values(self, left=0, top=0, right=None, bottom=None): - changes = self.changes - width, height = self.total_rows, self.total_cols - if right is None: - right = width - if bottom is None: - bottom = height - values = self._data[left:right, top:bottom].copy() - # both versions get the same result, but depending on inputs, the - # speed difference can be large. - if values.size < len(changes): - for i in range(left, right): - for j in range(top, bottom): - pos = i, j - if pos in changes: - values[i - left, j - top] = changes[pos] - else: - for (i, j), value in changes.items(): - if left <= i < right and top <= j < bottom: - values[i - left, j - top] = value - return values - - def convert_value(self, value): - """ - Parameters - ---------- - value : str - """ - dtype = self._data.dtype - if dtype.name == "bool": - try: - return bool(float(value)) - except ValueError: - return value.lower() == "true" - elif dtype.name.startswith("string"): - return str(value) - elif dtype.name.startswith("unicode"): - return to_text_string(value) - elif is_float(dtype): - return float(value) - elif is_number(dtype): - return int(value) - else: - return complex(value) - - def convert_values(self, values): - values = np.asarray(values) - res = np.empty_like(values, dtype=self._data.dtype) - try: - # TODO: use array/vectorized conversion functions (but watch out - # for bool) - # new_data = str_array.astype(data.dtype) - for i, v in enumerate(values.flat): - res.flat[i] = self.convert_value(v) - except ValueError as e: - QMessageBox.critical(self.dialog, "Error", - "Value error: %s" % str(e)) - return None - except OverflowError as e: - QMessageBox.critical(self.dialog, "Error", - "Overflow error: %s" % e.message) - return None - return res - - def set_values(self, left, top, right, bottom, values): - """ - Parameters - ---------- - left : int - top : int - right : int - exclusive - bottom : int - exclusive - values : ndarray - must not be of the correct type - - Returns - ------- - tuple of QModelIndex or None - actual bounds (end bound is inclusive) if update was successful, - None otherwise - """ - values = self.convert_values(values) - if values is None: - return - values = np.atleast_2d(values) - vshape = values.shape - vwidth, vheight = vshape - width, height = right - left, bottom - top - assert vwidth == 1 or vwidth == width - assert vheight == 1 or vheight == height - - # Add change to self.changes - changes = self.changes - # requires numpy 1.10 - newvalues = np.broadcast_to(values, (width, height)) - oldvalues = np.empty_like(newvalues) - for i in range(width): - for j in range(height): - pos = left + i, top + j - old_value = changes.get(pos, self._data[pos]) - oldvalues[i, j] = old_value - val = newvalues[i, j] - if val != old_value: - changes[pos] = val - - # Update vmin/vmax if necessary - if self.vmin is not None and self.vmax is not None: - colorval = self.color_func(values) - old_colorval = self.color_func(oldvalues) - if np.any(((old_colorval == self.vmax) & (colorval < self.vmax)) | - ((old_colorval == self.vmin) & (colorval > self.vmin))): - self.reset_minmax() - if np.any(colorval > self.vmax): - self.vmax = np.nanmax(colorval) - if np.any(colorval < self.vmin): - self.vmin = np.nanmin(colorval) - - xoffset = len(self.xlabels) - 1 - yoffset = len(self.ylabels) - 1 - top_left = self.index(left + xoffset, top + yoffset) - # -1 because Qt index end bounds are inclusive - bottom_right = self.index(right + xoffset - 1, bottom + yoffset - 1) - self.dataChanged.emit(top_left, bottom_right) - return top_left, bottom_right - - def setData(self, index, value, role=Qt.EditRole): - """Cell content change""" - if not index.isValid() or self.readonly: - return False - i = index.row() - len(self.xlabels) + 1 - j = index.column() - len(self.ylabels) + 1 - result = self.set_values(i, j, i + 1, j + 1, from_qvariant(value, str)) - return result is not None - - def flags(self, index): - """Set editable flag""" - if not index.isValid(): - return Qt.ItemIsEnabled - if (index.row() < len(self.xlabels) - 1) or \ - (index.column() < len(self.ylabels) - 1): - return Qt.ItemIsEnabled #QAbstractTableModel.flags(self, index) - flags = QAbstractTableModel.flags(self, index) - if not self.readonly: - flags |= Qt.ItemIsEditable - return Qt.ItemFlags(flags) - - def headerData(self, section, orientation, role=Qt.DisplayRole): - """Set header data""" - horizontal = orientation == Qt.Horizontal - # if role == Qt.ToolTipRole: - # if horizontal: - # return to_qvariant("horiz %d" % section) - # else: - # return to_qvariant("vert %d" % section) - if role != Qt.DisplayRole: - # roles = {0: "display", 2: "edit", 8: "background", 9: "foreground", - # 13: "sizehint", 4: "statustip", 11: "accessibletext", - # 1: "decoration", 6: "font", 7: "textalign", - # 10: "checkstate"} - # print("section", section, "ori", orientation, - # "role", roles.get(role, role), "result", - # super(ArrayModel, self).headerData(section, orientation, - # role)) - return to_qvariant() - - labels, other = self.xlabels, self.ylabels - if not horizontal: - labels, other = other, labels - if labels is None: - shape = self._data.shape - # prefer a blank cell to one cell named "0" - if not shape or shape[int(horizontal)] == 1: - return to_qvariant() - else: - return to_qvariant(int(section)) - else: - if section < len(labels[0]): - return to_qvariant(labels[0][section]) - # #section = section - len(other) + 1 - else: - return to_qvariant() - - # return to_qvariant(labels[0][section]) - # if len(other) - 1 <= section < len(labels[0]): - # #section = section - len(other) + 1 - # else: - # return to_qvariant("a") - - def reset(self): - self.beginResetModel() - self.endResetModel() - - -class ArrayDelegate(QItemDelegate): - """Array Editor Item Delegate""" - def __init__(self, dtype, parent=None, font=None, - minvalue=None, maxvalue=None): - QItemDelegate.__init__(self, parent) - self.dtype = dtype - if font is None: - font = get_font('arrayeditor') - self.font = font - self.minvalue = minvalue - self.maxvalue = maxvalue - - # We must keep a count instead of the "current" one, because when - # switching from one cell to the next, the new editor is created - # before the old one is destroyed, which means it would be set to None - # when the old one is destroyed. - self.editor_count = 0 - - def createEditor(self, parent, option, index): - """Create editor widget""" - model = index.model() - value = model.get_value(index) - if self.dtype.name == "bool": - # toggle value - value = not value - model.setData(index, to_qvariant(value)) - return - elif value is not np.ma.masked: - minvalue, maxvalue = self.minvalue, self.maxvalue - if minvalue is not None and maxvalue is not None: - msg = "value must be between %s and %s" % (minvalue, maxvalue) - elif minvalue is not None: - msg = "value must be >= %s" % minvalue - elif maxvalue is not None: - msg = "value must be <= %s" % maxvalue - else: - msg = None - - # Not using a QSpinBox for integer inputs because I could not find - # a way to prevent the spinbox/editor from closing if the value is - # invalid. Using the builtin minimum/maximum of the spinbox works - # but that provides no message so it is less clear. - editor = QLineEdit(parent) - if is_number(self.dtype): - validator = QDoubleValidator(editor) if is_float(self.dtype) \ - else QIntValidator(editor) - if minvalue is not None: - validator.setBottom(minvalue) - if maxvalue is not None: - validator.setTop(maxvalue) - editor.setValidator(validator) - - def on_editor_text_edited(): - if not editor.hasAcceptableInput(): - QToolTip.showText(editor.mapToGlobal(QPoint()), msg) - else: - QToolTip.hideText() - if msg is not None: - editor.textEdited.connect(on_editor_text_edited) - - editor.setFont(self.font) - editor.setAlignment(Qt.AlignRight) - editor.destroyed.connect(self.on_editor_destroyed) - self.editor_count += 1 - return editor - - def on_editor_destroyed(self): - self.editor_count -= 1 - assert self.editor_count >= 0 - - def setEditorData(self, editor, index): - """Set editor widget's data""" - text = from_qvariant(index.model().data(index, Qt.DisplayRole), str) - editor.setText(text) - - -class ArrayView(QTableView): - """Array view class""" - def __init__(self, parent, model, dtype, shape): - QTableView.__init__(self, parent) - - self.setModel(model) - delegate = ArrayDelegate(dtype, self, - minvalue=model.minvalue, - maxvalue=model.maxvalue) - self.setItemDelegate(delegate) - self.setSelectionMode(QTableView.ContiguousSelection) - - self.shape = shape - self.context_menu = self.setup_context_menu() - - # make the grid a bit more compact - self.horizontalHeader().setDefaultSectionSize(64) - self.verticalHeader().setDefaultSectionSize(20) - - self.horizontalScrollBar().valueChanged.connect( - self.on_horizontal_scroll_changed) - self.verticalScrollBar().valueChanged.connect( - self.on_vertical_scroll_changed) - # self.horizontalHeader().sectionClicked.connect( - # self.on_horizontal_header_clicked) - - def on_horizontal_header_clicked(self, section_index): - menu = FilterMenu(self) - header = self.horizontalHeader() - headerpos = self.mapToGlobal(header.pos()) - posx = headerpos.x() + header.sectionPosition(section_index) - posy = headerpos.y() + header.height() - menu.exec_(QPoint(posx, posy)) - - def on_vertical_scroll_changed(self, value): - if value == self.verticalScrollBar().maximum(): - self.model().fetch_more_rows() - - def on_horizontal_scroll_changed(self, value): - if value == self.horizontalScrollBar().maximum(): - self.model().fetch_more_columns() - - def setup_context_menu(self): - """Setup context menu""" - self.copy_action = create_action(self, _('Copy'), - shortcut=keybinding('Copy'), - icon=ima.icon('edit-copy'), - triggered=self.copy) - self.excel_action = create_action(self, _('Copy to Excel'), - shortcut=QKeySequence("Ctrl+E"), - # icon=ima.icon('edit-copy'), - triggered=self.to_excel) - self.paste_action = create_action(self, _('Paste'), - shortcut=keybinding('Paste'), - icon=ima.icon('edit-paste'), - triggered=self.paste) - self.plot_action = create_action(self, _('Plot'), - shortcut=keybinding('Print'), - # icon=ima.icon('editcopy'), - triggered=self.plot) - menu = QMenu(self) - menu.addActions([self.copy_action, self.excel_action, self.plot_action, - self.paste_action]) - return menu - - def autofit_columns(self): - """Resize cells to contents""" - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - - # Spyder loads more columns before resizing, but since it does not - # load all columns anyway, I do not see the point - # self.model().fetch_more_columns() - self.resizeColumnsToContents() - QApplication.restoreOverrideCursor() - - def contextMenuEvent(self, event): - """Reimplement Qt method""" - self.context_menu.popup(event.globalPos()) - event.accept() - - def keyPressEvent(self, event): - """Reimplement Qt method""" - - # comparing with the keysequence and not with event directly as we - # did before because that only seems to work for shortcut - # defined using QKeySequence.StandardKey, which is not the case for - # Ctrl + E - keyseq = QKeySequence(event.modifiers() | event.key()) - if keyseq == QKeySequence.Copy: - self.copy() - elif keyseq == QKeySequence.Paste: - self.paste() - elif keyseq == QKeySequence.Print: - self.plot() - elif keyseq == QKeySequence("Ctrl+E"): - self.to_excel() - # allow to start editing cells by pressing Enter - elif event.key() == Qt.Key_Return and not self.model().readonly: - index = self.currentIndex() - if self.itemDelegate(index).editor_count == 0: - self.edit(index) - else: - QTableView.keyPressEvent(self, event) - - def _selection_bounds(self, none_selects_all=True): - """ - Returns - ------- - tuple - selection bounds. end bound is exclusive - """ - model = self.model() - selection_model = self.selectionModel() - assert isinstance(selection_model, QItemSelectionModel) - selection = selection_model.selection() - assert isinstance(selection, QItemSelection) - if not selection: - if none_selects_all: - return 0, model.total_rows, 0, model.total_cols - else: - return None - assert len(selection) == 1 - srange = selection[0] - assert isinstance(srange, QItemSelectionRange) - xoffset = len(self.model().xlabels) - 1 - yoffset = len(self.model().ylabels) - 1 - row_min = max(srange.top() - xoffset, 0) - row_max = max(srange.bottom() - xoffset, 0) - col_min = max(srange.left() - yoffset, 0) - col_max = max(srange.right() - yoffset, 0) - return row_min, row_max + 1, col_min, col_max + 1 - - def _selection_data(self, headers=True, none_selects_all=True): - bounds = self._selection_bounds(none_selects_all=none_selects_all) - if bounds is None: - return None - row_min, row_max, col_min, col_max = bounds - raw_data = self.model().get_values(row_min, col_min, row_max, col_max) - if headers: - xlabels = self.model().xlabels - ylabels = self.model().ylabels - # FIXME: this is extremely ad-hoc. We should either use - # model.data.ndim (orig_ndim?) or add a new concept (eg dim_names) - # in addition to xlabels & ylabels, - # TODO: in the future (pandas-based branch) we should use - # to_string(data[self._selection_filter()]) - dim_names = xlabels[0] - if len(dim_names) > 1: - dim_headers = dim_names[:-2] + [dim_names[-2] + ' \\ ' + - dim_names[-1]] - else: - dim_headers = dim_names - topheaders = [dim_headers + list(xlabels[i][col_min:col_max]) - for i in range(1, len(xlabels))] - if not dim_names: - return raw_data - elif len(dim_names) == 1: - # 1 dimension - return chain(topheaders, [chain([''], row) for row in raw_data]) - else: - # >1 dimension - assert len(dim_names) > 1 - return chain(topheaders, - [chain([ylabels[j][r + row_min] - for j in range(1, len(ylabels))], - row) - for r, row in enumerate(raw_data)]) - else: - return raw_data - - @Slot() - def copy(self): - """Copy array as text to clipboard""" - data = self._selection_data() - if data is None: - return - - # np.savetxt make things more complicated, especially on py3 - # XXX: why don't we use repr for everything? - def vrepr(v): - if isinstance(v, float): - return repr(v) - else: - return str(v) - text = '\n'.join('\t'.join(vrepr(v) for v in line) for line in data) - clipboard = QApplication.clipboard() - clipboard.setText(text) - - @Slot() - def to_excel(self): - """Copy array as text to clipboard""" - if xw is None: - raise Exception("to_excel() is not available because xlwings is " - "not installed") - data = self._selection_data() - if data is None: - return - # convert (row) generators to lists then array - a = np.array([list(r) for r in data]) - xw.view(a) - - @Slot() - def paste(self): - model = self.model() - bounds = self._selection_bounds() - if bounds is None: - return - row_min, row_max, col_min, col_max = bounds - clipboard = QApplication.clipboard() - text = str(clipboard.text()) - list_data = [line.split('\t') for line in text.splitlines()] - try: - # take the first cell which contains '\' - pos_last = next(i for i, v in enumerate(list_data[0]) if '\\' in v) - except StopIteration: - # if there isn't any, assume 1d array - pos_last = 0 - if pos_last: - # ndim > 1 - list_data = [line[pos_last + 1:] for line in list_data[1:]] - elif len(list_data) == 2 and list_data[1][0] == '': - # ndim == 1 - list_data = [list_data[1][1:]] - new_data = np.array(list_data) - if new_data.shape[0] > 1: - row_max = row_min + new_data.shape[0] - if new_data.shape[1] > 1: - col_max = col_min + new_data.shape[1] - - result = model.set_values(row_min, col_min, row_max, col_max, new_data) - if result is None: - return - - # TODO: when pasting near bottom/right boundaries and size of - # new_data exceeds destination size, we should either have an error - # or clip new_data - self.selectionModel().select(QItemSelection(*result), - QItemSelectionModel.ClearAndSelect) - - def plot(self): - if not matplotlib_present: - raise Exception("plot() is not available because matplotlib is not " - "installed") - # we use np.asarray to work around missing "newaxis" implementation - # in LArray - data = self._selection_data(headers=False) - - assert data.ndim == 2 - column = data.shape[0] == 1 - row = data.shape[1] == 1 - assert row or column - data = data[0] if column else data[:, 0] - - figure = plt.figure() - - # create an axis - ax = figure.add_subplot(111) - - # discards the old graph - ax.hold(False) - - x = np.arange(data.shape[0]) - ax.plot(x, data) - - main = PlotDialog(figure, self) - main.show() - - -class PlotDialog(QDialog): - def __init__(self, figure, parent=None): - super(PlotDialog, self).__init__(parent) - - canvas = FigureCanvas(figure) - toolbar = NavigationToolbar(canvas, self) - - # set the layout - layout = QVBoxLayout() - layout.addWidget(toolbar) - layout.addWidget(canvas) - self.setLayout(layout) - - canvas.draw() - - -def ndigits(value): - """ - number of integer digits - - >>> ndigits(1) - 1 - >>> ndigits(99) - 2 - >>> ndigits(-99.1) - 3 - """ - negative = value < 0 - value = abs(value) - log10 = math.log10(value) if value > 0 else 0 - if log10 == np.inf: - int_digits = 308 - else: - # max(1, ...) because there is at least one integer digit - # explicit conversion to int for Python2.x - int_digits = max(1, int(math.floor(log10)) + 1) - # one digit for sign if negative - return int_digits + negative - - -class ArrayEditorWidget(QWidget): - def __init__(self, parent, data, readonly=False, - xlabels=None, ylabels=None, bg_value=None, - bg_gradient=None, minvalue=None, maxvalue=None): - QWidget.__init__(self, parent) - if np.isscalar(data): - readonly = True - if not isinstance(data, (np.ndarray, la.LArray)): - data = np.array(data) - self.model = ArrayModel(None, readonly=readonly, parent=self, - bg_value=bg_value, bg_gradient=bg_gradient, - minvalue=minvalue, maxvalue=maxvalue) - self.view = ArrayView(self, self.model, data.dtype, data.shape) - - self.filters_layout = QHBoxLayout() - btn_layout = QHBoxLayout() - btn_layout.setAlignment(Qt.AlignLeft) - - label = QLabel("Digits") - btn_layout.addWidget(label) - spin = QSpinBox(self) - spin.valueChanged.connect(self.digits_changed) - self.digits_spinbox = spin - btn_layout.addWidget(spin) - - scientific = QCheckBox(_('Scientific')) - scientific.stateChanged.connect(self.scientific_changed) - self.scientific_checkbox = scientific - btn_layout.addWidget(scientific) - - bgcolor = QCheckBox(_('Background color')) - bgcolor.stateChanged.connect(self.model.bgcolor) - self.bgcolor_checkbox = bgcolor - btn_layout.addWidget(bgcolor) - - layout = QVBoxLayout() - layout.addLayout(self.filters_layout) - layout.addWidget(self.view) - layout.addLayout(btn_layout) - self.setLayout(layout) - self.set_data(data, xlabels, ylabels) - - def set_data(self, data, xlabels=None, ylabels=None, current_filter=None): - self.old_data_shape = None - if current_filter is None: - current_filter = {} - self.current_filter = current_filter - self.global_changes = {} - if isinstance(data, la.LArray): - self.la_data = data - filters_layout = self.filters_layout - clear_layout(filters_layout) - filters_layout.addWidget(QLabel(_("Filters"))) - for axis, display_name in zip(data.axes, data.axes.display_names): - filters_layout.addWidget(QLabel(display_name)) - filters_layout.addWidget(self.create_filter_combo(axis)) - filters_layout.addStretch() - data, xlabels, ylabels = larray_to_array_and_labels(data) - else: - if not isinstance(data, np.ndarray): - data = np.asarray(data) - self.la_data = None - self.filtered_data = self.la_data - if data.size == 0: - QMessageBox.critical(self, _("Error"), _("Array is empty")) - if data.ndim == 0: - self.old_data_shape = data.shape - data.shape = (1, 1) - elif data.ndim == 1: - self.old_data_shape = data.shape - data = data.reshape(1, data.shape[0]) - ylabels = [[]] - - if data.ndim > 2: - data = data.reshape(np.prod(data.shape[:-1]), data.shape[-1]) - - # if xlabels is not None and len(xlabels) != self.data.shape[1]: - # self.error(_("The 'xlabels' argument length do no match array " - # "column number")) - # return False - # if ylabels is not None and len(ylabels) != self.data.shape[0]: - # self.error(_("The 'ylabels' argument length do no match array row " - # "number")) - # return False - self._set_raw_data(data, xlabels, ylabels) - - def _set_raw_data(self, data, xlabels, ylabels, changes=None): - # FIXME: this method should be *FAST*, as it is used for each filter - # change - ndecimals, use_scientific = self.choose_format(data) - # XXX: self.ndecimals vs self.digits - self.digits = ndecimals - self.use_scientific = use_scientific - self.data = data - self.model.set_format(self.cell_format) - if changes is None: - changes = {} - self.model.set_data(data, xlabels, ylabels, changes) - - self.digits_spinbox.setValue(ndecimals) - self.digits_spinbox.setEnabled(is_float(data.dtype)) - - self.scientific_checkbox.setChecked(use_scientific) - self.scientific_checkbox.setEnabled(is_number(data.dtype)) - - self.bgcolor_checkbox.setChecked(self.model.bgcolor_enabled) - self.bgcolor_checkbox.setEnabled(self.model.bgcolor_enabled) - - def choose_scientific(self, data): - # max_digits = self.get_max_digits() - # default width can fit 8 chars - # FIXME: use max_digits? - avail_digits = 8 - if data.dtype.type in (np.str, np.str_, np.bool_, np.bool, np.object_): - return False - - frac_zeros, int_digits, _ = self.format_helper(data) - - # if there are more integer digits than we can display or we can - # display more information by using scientific format, do so - # (scientific format "uses" 4 digits, so we win if have >= 4 zeros - # -- *including the integer one*) - # TODO: only do so if we would actually display more information - # 0.00001 can be displayed with 8 chars - # 1e-05 - # would - return int_digits > avail_digits or frac_zeros >= 4 - - def choose_ndecimals(self, data, scientific): - if data.dtype.type in (np.str, np.str_, np.bool_, np.bool, np.object_): - return 0 - - # max_digits = self.get_max_digits() - # default width can fit 8 chars - # FIXME: use max_digits? - avail_digits = 8 - data_frac_digits = self._data_digits(data) - _, int_digits, negative = self.format_helper(data) - if scientific: - int_digits = 2 if negative else 1 - exp_digits = 4 - else: - exp_digits = 0 - # - 1 for the dot - ndecimals = avail_digits - 1 - int_digits - exp_digits - - if ndecimals < 0: - ndecimals = 0 - - if data_frac_digits < ndecimals: - ndecimals = data_frac_digits - return ndecimals - - def choose_format(self, data): - # TODO: refactor so that the expensive format_helper is not called - # twice (or the values are cached) - use_scientific = self.choose_scientific(data) - return self.choose_ndecimals(data, use_scientific), use_scientific - - def format_helper(self, data): - if not data.size: - return 0, 0, False - data = np.where(np.isfinite(data), data, 0) - vmin, vmax = np.nanmin(data), np.nanmax(data) - absmax = max(abs(vmin), abs(vmax)) - logabsmax = math.log10(absmax) if absmax else 0 - # minimum number of zeros before meaningful fractional part - frac_zeros = math.ceil(-logabsmax) - 1 if logabsmax < 0 else 0 - int_digits = max(ndigits(vmin), ndigits(vmax)) - return frac_zeros, int_digits, vmin < 0 - - def get_max_digits(self, need_sign=False, need_dot=False, scientific=False): - font = get_font("arreditor") # QApplication.font() - col_width = 60 - margin_width = 6 # a wild guess - avail_width = col_width - margin_width - metrics = QFontMetrics(font) - - def str_width(c): - return metrics.size(Qt.TextSingleLine, c).width() - - digit_width = max(str_width(str(i)) for i in range(10)) - dot_width = metrics.size(Qt.TextSingleLine, '.').width() - sign_width = max(str_width('+'), str_width('-')) - if need_sign: - avail_width -= sign_width - if need_dot: - avail_width -= dot_width - if scientific: - avail_width -= str_width('e') + sign_width + 2 * digit_width - return avail_width // digit_width - - def _data_digits(self, data, maxdigits=6): - if not data.size: - return 0 - threshold = 10 ** -(maxdigits + 1) - for ndigits in range(maxdigits): - maxdiff = np.max(np.abs(data - np.round(data, ndigits))) - if maxdiff < threshold: - return ndigits - return maxdigits - - @property - def dirty(self): - self.update_global_changes() - return len(self.global_changes) > 1 - - def accept_changes(self): - """Accept changes""" - self.update_global_changes() - la_data = self.la_data - for k, v in self.global_changes.items(): - la_data.i[la_data.axes.translate_full_key(k)] = v - # update model data & reset global_changes - self.set_data(self.la_data, current_filter=self.current_filter) - # XXX: shouldn't this be done only in the dialog? (if we continue - # editing...) - if self.old_data_shape is not None: - self.data.shape = self.old_data_shape - - def reject_changes(self): - """Reject changes""" - self.global_changes.clear() - # trigger view update - self.model.changes.clear() - self.model.reset_minmax() - self.model.reset() - # XXX: shouldn't this be done only in the dialog? (if we continue - # editing...) - if self.old_data_shape is not None: - self.data.shape = self.old_data_shape - - @property - def cell_format(self): - if self.data.dtype.type in (np.str, np.str_, np.bool_, np.bool, - np.object_): - return '%s' - else: - return '%%.%d%s' % (self.digits, 'e' if self.use_scientific else 'f') - - def scientific_changed(self, value): - self.use_scientific = value - self.digits = self.choose_ndecimals(self.data, value) - self.digits_spinbox.setValue(self.digits) - self.model.set_format(self.cell_format) - - def digits_changed(self, value): - self.digits = value - self.model.set_format(self.cell_format) - - def create_filter_combo(self, axis): - def filter_changed(checked_items): - self.change_filter(axis, checked_items) - combo = FilterComboBox(self) - combo.addItems([str(l) for l in axis.labels]) - combo.checkedItemsChanged.connect(filter_changed) - return combo - - def change_filter(self, axis, indices): - # must be done before changing self.current_filter - self.update_global_changes() - cur_filter = self.current_filter - # if index == 0: - if not indices or len(indices) == len(axis.labels): - if axis.name in cur_filter: - del cur_filter[axis.name] - else: - if len(indices) == 1: - cur_filter[axis.name] = axis.labels[indices[0]] - else: - cur_filter[axis.name] = axis.labels[indices] - filtered = self.la_data[cur_filter] - local_changes = self.get_local_changes(filtered) - self.filtered_data = filtered - if np.isscalar(filtered): - # no need to make the editor readonly as we can still propagate the - # .changes back into the original array. - data, xlabels, ylabels = np.array([[filtered]]), None, None - else: - data, xlabels, ylabels = larray_to_array_and_labels(filtered) - - self._set_raw_data(data, xlabels, ylabels, local_changes) - - def get_local_changes(self, filtered): - # we cannot apply the changes directly to data because it might be a - # view - changes = {} - for k, v in self.global_changes.items(): - local_key = self.map_global_to_filtered(k, filtered) - if local_key is not None: - changes[local_key] = v - return changes - - def update_global_changes(self): - # TODO: it would be a better idea to handle the filter in the model, - # and only store changes as "global changes". - for k, v in self.model.changes.items(): - self.global_changes[self.map_filtered_to_global(k)] = v - - def map_global_to_filtered(self, k, filtered): - """ - map global ND key to local (filtered) 2D key - """ - assert isinstance(k, tuple) and len(k) == self.la_data.ndim - - dkey = {axis.name: axis_key - for axis_key, axis in zip(k, self.la_data.axes)} - - # transform global dictionary key to "local" (filtered) key by removing - # the parts of the key which are redundant with the filter - for axis_name, axis_filter in self.current_filter.items(): - axis_key = dkey[axis_name] - if np.isscalar(axis_filter) and axis_key == axis_filter: - del dkey[axis_name] - elif not np.isscalar(axis_filter) and axis_key in axis_filter: - pass - else: - # that key is invalid for/outside the current filter - return None - - # transform local label key to local index key - try: - index_key = filtered.translated_key(dkey) - except ValueError: - return None - - # transform local index ND key to local index 2D key - mult = np.append(1, np.cumprod(filtered.shape[1:-1][::-1]))[::-1] - return (index_key[:-1] * mult).sum(), index_key[-1] - - def map_filtered_to_global(self, k): - """ - map local (filtered) 2D key to global ND key - """ - assert isinstance(k, tuple) and len(k) == 2 - - # transform local index key to local label key - model = self.model - ki, kj = k - xlabels = model.xlabels - ylabels = model.ylabels - xlabel = [xlabels[i][kj] for i in range(1, len(xlabels))] - ylabel = [ylabels[j][ki] for j in range(1, len(ylabels))] - label_key = tuple(ylabel + xlabel) - - # compute dictionary key out of it - data = self.filtered_data - axes_names = data.axes.names if isinstance(data, la.LArray) else [] - dkey = dict(zip(axes_names, label_key)) - - # add the "scalar" parts of the filter to it (ie the parts of the - # filter which removed dimensions) - dkey.update({k: v for k, v in self.current_filter.items() - if np.isscalar(v)}) - - # re-transform it to tuple (to make it hashable/to store it in .changes) - return tuple(dkey[axis.name] for axis in self.la_data.axes) - - -def larray_to_array_and_labels(data): - assert isinstance(data, la.LArray) - - xlabels = [data.axes.display_names, data.axes.labels[-1]] - - class LazyLabels(object): - def __init__(self, arrays): - self.prod = Product(arrays) - - def __getitem__(self, key): - return ' '.join(self.prod[key]) - - def __len__(self): - return len(self.prod) - - class LazyDimLabels(object): - def __init__(self, prod, i): - self.prod = prod - self.i = i - - def __iter__(self): - return iter(self.prod[:][self.i]) - - def __getitem__(self, key): - return self.prod[key][self.i] - - def __len__(self): - return len(self.prod) - - class LazyRange(object): - def __init__(self, length, offset): - self.length = length - self.offset = offset - - def __getitem__(self, key): - if key >= self.offset: - return key - self.offset - else: - return '' - - def __len__(self): - return self.length + self.offset - - class LazyNone(object): - def __init__(self, length): - self.length = length - - def __getitem__(self, key): - return ' ' - - def __len__(self): - return self.length - - otherlabels = data.axes.labels[:-1] - # ylabels = LazyLabels(otherlabels) - coldims = 1 - # ylabels = [str(i) for i in range(len(row_labels))] - data = data.data[:] - if data.ndim == 1: - data = data.reshape(1, data.shape[0]) - ylabels = [[]] - else: - prod = Product(otherlabels) - ylabels = [LazyNone(len(prod) + coldims)] + [ - LazyDimLabels(prod, i) for i in range(len(otherlabels))] - # ylabels = [LazyRange(len(prod), coldims)] + [ - # LazyDimLabels(prod, i) for i in range(len(otherlabels))] - - if data.ndim > 2: - data = data.reshape(np.prod(data.shape[:-1]), data.shape[-1]) - return data, xlabels, ylabels - - -class ArrayEditor(QDialog): - """Array Editor Dialog""" - def __init__(self, parent=None): - QDialog.__init__(self, parent) - - # Destroying the C++ object right after closing the dialog box, - # otherwise it may be garbage-collected in another QThread - # (e.g. the editor's analysis thread in Spyder), thus leading to - # a segmentation fault on UNIX or an application crash on Windows - self.setAttribute(Qt.WA_DeleteOnClose) - - self.data = None - self.arraywidget = None - - def setup_and_check(self, data, title='', readonly=False, - xlabels=None, ylabels=None, - minvalue=None, maxvalue=None): - """ - Setup ArrayEditor: - return False if data is not supported, True otherwise - """ - if np.isscalar(data): - readonly = True - if isinstance(data, la.LArray): - axes_info = ' x '.join("%s (%d)" % (display_name, len(axis)) - for display_name, axis - in zip(data.axes.display_names, data.axes)) - title = (title + ': ' + axes_info) if title else axes_info - - self.data = data - layout = QGridLayout() - self.setLayout(layout) - - icon = self.style().standardIcon(QStyle.SP_ComputerIcon) - if icon is not None: - self.setWindowIcon(icon) - - if not title: - title = _("Array viewer") if readonly else _("Array editor") - if readonly: - title += ' (' + _('read only') + ')' - self.setWindowTitle(title) - self.resize(800, 600) - self.setMinimumSize(400, 300) - - self.arraywidget = ArrayEditorWidget(self, data, readonly, - xlabels, ylabels, - minvalue=minvalue, - maxvalue=maxvalue) - layout.addWidget(self.arraywidget, 1, 0) - - # Buttons configuration - btn_layout = QHBoxLayout() - btn_layout.addStretch() - - # not using a QDialogButtonBox with standard Ok/Cancel buttons - # because that makes it impossible to disable the AutoDefault on them - # (Enter always "accepts"/close the dialog) which is annoying for edit() - ok_button = QPushButton("&OK") - ok_button.clicked.connect(self.accept) - ok_button.setAutoDefault(False) - btn_layout.addWidget(ok_button) - if not readonly: - cancel_button = QPushButton("Cancel") - cancel_button.clicked.connect(self.reject) - cancel_button.setAutoDefault(False) - btn_layout.addWidget(cancel_button) - # r_button = QPushButton("resize") - # r_button.clicked.connect(self.resize_to_contents) - # btn_layout.addWidget(r_button) - layout.addLayout(btn_layout, 2, 0) - - # Make the dialog act as a window - self.setWindowFlags(Qt.Window) - return True - - def autofit_columns(self): - self.arraywidget.view.autofit_columns() - - @Slot() - def accept(self): - """Reimplement Qt method""" - self.arraywidget.accept_changes() - QDialog.accept(self) - - @Slot() - def reject(self): - """Reimplement Qt method""" - self.arraywidget.reject_changes() - QDialog.reject(self) - - def get_value(self): - """Return modified array -- this is *not* a copy""" - # It is import to avoid accessing Qt C++ object as it has probably - # already been destroyed, due to the Qt.WA_DeleteOnClose attribute - return self.data - - -class SessionEditor(QDialog): - """Session Editor Dialog""" - def __init__(self, parent=None): - QDialog.__init__(self, parent) - - # Destroying the C++ object right after closing the dialog box, - # otherwise it may be garbage-collected in another QThread - # (e.g. the editor's analysis thread in Spyder), thus leading to - # a segmentation fault on UNIX or an application crash on Windows - self.setAttribute(Qt.WA_DeleteOnClose) - - self.data = None - self.arraywidget = None - - def setup_and_check(self, data, title='', readonly=False): - """ - Setup SessionEditor: - return False if data is not supported, True otherwise - """ - assert isinstance(data, la.Session) - self.data = data - - icon = self.style().standardIcon(QStyle.SP_ComputerIcon) - if icon is not None: - self.setWindowIcon(icon) - - if not title: - title = _("Session viewer") if readonly else _("Session editor") - if readonly: - title += ' (' + _('read only') + ')' - self.setWindowTitle(title) - - layout = QVBoxLayout() - self.setLayout(layout) - - self._listwidget = QListWidget(self) - self._listwidget.addItems(self.data.names) - self._listwidget.currentItemChanged.connect(self.on_item_changed) - - self.arraywidget = ArrayEditorWidget(self, data[0], readonly) - - splitter = QSplitter(Qt.Horizontal) - splitter.addWidget(self._listwidget) - splitter.addWidget(self.arraywidget) - splitter.setSizes([5, 95]) - splitter.setCollapsible(1, False) - - layout.addWidget(splitter) - - # Buttons configuration - btn_layout = QHBoxLayout() - btn_layout.addStretch() - - buttons = QDialogButtonBox.Ok - if not readonly: - buttons |= QDialogButtonBox.Cancel - bbox = QDialogButtonBox(buttons) - bbox.accepted.connect(self.accept) - if not readonly: - bbox.rejected.connect(self.reject) - btn_layout.addWidget(bbox) - layout.addLayout(btn_layout) - - self.resize(800, 600) - self.setMinimumSize(400, 300) - - # Make the dialog act as a window - self.setWindowFlags(Qt.Window) - return True - - def on_item_changed(self, curr, prev): - self.arraywidget.set_data(self.data[str(curr.text())]) - - @Slot() - def accept(self): - """Reimplement Qt method""" - self.arraywidget.accept_changes() - QDialog.accept(self) - - @Slot() - def reject(self): - """Reimplement Qt method""" - self.arraywidget.reject_changes() - QDialog.reject(self) - - def get_value(self): - """Return modified array -- this is *not* a copy""" - # It is import to avoid accessing Qt C++ object as it has probably - # already been destroyed, due to the Qt.WA_DeleteOnClose attribute - return self.data - - -class LinearGradient(object): - """ - I cannot believe I had to roll my own class for this when PyQt already - contains QLinearGradient... but you cannot get intermediate values out of - QLinearGradient! - """ - def __init__(self, stop_points=None): - if stop_points is None: - stop_points = [] - # sort by position - stop_points = sorted(stop_points, key=lambda x: x[0]) - positions, colors = zip(*stop_points) - self.positions = np.array(positions) - self.colors = np.array(colors) - - def __getitem__(self, key): - if key != key: - key = self.positions[0] - pos_idx = np.searchsorted(self.positions, key, side='right') - 1 - # if we are exactly on one of the bounds - if pos_idx > 0 and key in self.positions: - pos_idx -= 1 - pos0, pos1 = self.positions[pos_idx:pos_idx + 2] - col0, col1 = self.colors[pos_idx:pos_idx + 2] - color = col0 + (col1 - col0) * (key - pos0) / (pos1 - pos0) - return to_qvariant(QColor.fromHsvF(*color)) - - -class ArrayComparator(QDialog): - """Session Editor Dialog""" - def __init__(self, parent=None): - QDialog.__init__(self, parent) - - # Destroying the C++ object right after closing the dialog box, - # otherwise it may be garbage-collected in another QThread - # (e.g. the editor's analysis thread in Spyder), thus leading to - # a segmentation fault on UNIX or an application crash on Windows - self.setAttribute(Qt.WA_DeleteOnClose) - - self.data1 = None - self.data2 = None - self.array1widget = None - self.array2widget = None - - def setup_and_check(self, data1, data2, title=''): - """ - Setup SessionEditor: - return False if data is not supported, True otherwise - """ - assert isinstance(data1, la.LArray) - assert isinstance(data2, la.LArray) - self.data1 = data1 - self.data2 = data2 - - icon = self.style().standardIcon(QStyle.SP_ComputerIcon) - if icon is not None: - self.setWindowIcon(icon) - - if not title: - title = _("Array comparator") - title += ' (' + _('read only') + ')' - self.setWindowTitle(title) - - layout = QVBoxLayout() - self.setLayout(layout) - - diff = (data2 - data1) - vmax = np.nanmax(diff) - vmin = np.nanmin(diff) - absmax = max(abs(vmax), abs(vmin)) - # scale diff to 0-1 - if absmax: - bg_value = (diff / absmax) / 2 + 0.5 - else: - # TODO: implement full() and full_like() - bg_value = la.empty_like(diff) - bg_value[:] = 0.5 - gradient = LinearGradient([(0, [.66, .85, 1., .6]), - (0.5 - 1e-300, [.66, .15, 1., .6]), - (0.5, [1., 0., 1., 1.]), - (0.5 + 1e-300, [.99, .15, 1., .6]), - (1, [.99, .85, 1., .6])]) - - self.array1widget = ArrayEditorWidget(self, data1, readonly=True, - bg_value=bg_value, - bg_gradient=gradient) - self.diffwidget = ArrayEditorWidget(self, diff, readonly=True, - bg_value=bg_value, - bg_gradient=gradient) - self.array2widget = ArrayEditorWidget(self, data2, readonly=True, - bg_value=1 - bg_value, - bg_gradient=gradient) - - splitter = QHBoxLayout() - splitter.addWidget(self.array1widget) - splitter.addWidget(self.diffwidget) - splitter.addWidget(self.array2widget) - - layout.addLayout(splitter) - - # Buttons configuration - btn_layout = QHBoxLayout() - btn_layout.addStretch() - - buttons = QDialogButtonBox.Ok - bbox = QDialogButtonBox(buttons) - bbox.accepted.connect(self.accept) - btn_layout.addWidget(bbox) - layout.addLayout(btn_layout) - - self.resize(800, 600) - self.setMinimumSize(400, 300) - - # Make the dialog act as a window - self.setWindowFlags(Qt.Window) - return True - - -def find_names(obj, depth=1): - # noinspection PyProtectedMember - l = sys._getframe(depth).f_locals - return sorted(k for k, v in l.items() if v is obj) - - -def get_title(obj, depth=1): - names = find_names(obj, depth=depth + 1) - # names can be == [] if we compute an array just to view it - # eg. view(arr['H']) - if len(names) > 3: - names = names[:3] + ['...'] - return ', '.join(names) - - -def edit(array, title='', minvalue=None, maxvalue=None): - _app = qapplication() - if not title: - title = get_title(array, depth=2) - dlg = ArrayEditor() - if dlg.setup_and_check(array, title=title, - minvalue=minvalue, maxvalue=maxvalue): - dlg.exec_() - - -def view(obj, title=''): - _app = qapplication() - if not title: - title = get_title(obj, depth=2) - - if isinstance(obj, dict) and all(isinstance(o, la.LArray) for o in obj.values()): - obj = la.Session(obj) - - if isinstance(obj, la.Session): - dlg = SessionEditor() - else: - dlg = ArrayEditor() - if dlg.setup_and_check(obj, title=title, readonly=True): - dlg.exec_() - - -def compare(obj1, obj2, title=''): - _app = qapplication() - dlg = ArrayComparator() - if dlg.setup_and_check(obj1, obj2, title=title): - dlg.exec_() - - -if __name__ == "__main__": - """Array editor test""" - - lipro = la.Axis('lipro', ['P%02d' % i for i in range(1, 16)]) - age = la.Axis('age', range(116)) - sex = la.Axis('sex', 'H,F') - - vla = 'A11,A12,A13,A23,A24,A31,A32,A33,A34,A35,A36,A37,A38,A41,A42,' \ - 'A43,A44,A45,A46,A71,A72,A73' - wal = 'A25,A51,A52,A53,A54,A55,A56,A57,A61,A62,A63,A64,A65,A81,A82,' \ - 'A83,A84,A85,A91,A92,A93' - bru = 'A21' - # list of strings - belgium = la.union(vla, wal, bru) - - geo = la.Axis('geo', belgium) - - # data1 = np.arange(30).reshape(2, 15) - # arr1 = la.LArray(data1, axes=(sex, lipro)) - # edit(arr1) - - # data2 = np.arange(116 * 44 * 2 * 15).reshape(116, 44, 2, 15) \ - # .astype(float) - # data2 = np.random.random(116 * 44 * 2 * 15).reshape(116, 44, 2, 15) \ - # .astype(float) - # data2 = (np.random.randint(10, size=(116, 44, 2, 15)) - 5) / 17 - # data2 = np.random.randint(10, size=(116, 44, 2, 15)) / 100 + 1567 - # data2 = np.random.normal(51000000, 10000000, size=(116, 44, 2, 15)) - data2 = np.random.normal(0, 1, size=(116, 44, 2, 15)) - arr2 = la.LArray(data2, axes=(age, geo, sex, lipro)) - # arr2 = arr2['F', 'A11', 1] - - # view(arr2[0, 'A11', 'F', 'P01']) - # view(arr1) - # view(arr2[0, 'A11']) - # edit(arr1) - # print(arr2[0, 'A11', :, 'P01']) - # edit(arr2.astype(int), minvalue=-99, maxvalue=55.123456) - # edit(arr2.astype(int), minvalue=-99) - # arr2.i[0, 0, 0, 0] = np.inf - # arr2.i[0, 0, 1, 1] = -np.inf - # arr2 = [0.0000111, 0.0000222] - # arr2 = [0.00001, 0.00002] - # edit(arr2, minvalue=-99, maxvalue=25.123456) - # print(arr2[0, 'A11', :, 'P01']) - - # data2 = np.random.normal(0, 10.0, size=(5000, 20)) - # arr2 = la.LArray(data2, - # axes=(la.Axis('d0', list(range(5000))), - # la.Axis('d1', list(range(20))))) - edit(arr2) - - # view(['a', 'bb', 5599]) - # view(np.arange(12).reshape(2, 3, 2)) - # view([]) - - # data3 = np.random.normal(0, 1, size=(2, 15)) - # arr3 = la.LArray(data3, axes=(sex, lipro)) - # data4 = np.random.normal(0, 1, size=(2, 15)) - # arr4 = la.LArray(data4, axes=(sex, lipro)) - # arr4 = arr3.copy() - # arr4['F', 'P01':] = arr3['F', 'P01':] / 2 - # compare(arr3, arr4) - - # arr3 = la.ndrange((1000, 1000, 500)) - # print(arr3.nbytes * 1e-9 + 'Gb') - # edit(arr3, minvalue=-99, maxvalue=25.123456) diff --git a/larray/viewer/__init__.py b/larray/viewer/__init__.py new file mode 100644 index 000000000..4156f4b1f --- /dev/null +++ b/larray/viewer/__init__.py @@ -0,0 +1,107 @@ +from __future__ import absolute_import, division, print_function + + +def view(obj=None, title='', depth=0): + """ + Opens a new viewer window. Arrays are loaded in readonly mode and their content cannot be modified. + + Parameters + ---------- + obj : np.ndarray, LArray, Session, dict or str, optional + Object to visualize. If string, array(s) will be loaded from the file given as argument. + Defaults to the collection of all local variables where the function was called. + title : str, optional + Title for the current object. Defaults to the name of the first object found in the caller namespace which + corresponds to `obj` (it will use a combination of the 3 first names if several names correspond to the same + object). + depth : int, optional + Stack depth where to look for variables. Defaults to 0 (where this function was called). + + Examples + -------- + >>> a1 = ndtest(3) # doctest: +SKIP + >>> a2 = ndtest(3) + 1 # doctest: +SKIP + >>> # will open a viewer showing all the arrays available at this point + >>> # (a1 and a2 in this case) + >>> view() # doctest: +SKIP + >>> # will open a viewer showing only a1 + >>> view(a1) # doctest: +SKIP + """ + try: + from larray_editor import view + view(obj, title, depth + 1) + except ImportError: + raise Exception('view() is not available because the larray_editor package is not installed') + + +def edit(obj=None, title='', minvalue=None, maxvalue=None, readonly=False, depth=0): + """ + Opens a new editor window. + + Parameters + ---------- + obj : np.ndarray, LArray, Session, dict, str or REOPEN_LAST_FILE, optional + Object to visualize. If string, array(s) will be loaded from the file given as argument. + Passing the constant REOPEN_LAST_FILE loads the last opened file. + Defaults to the collection of all local variables where the function was called. + title : str, optional + Title for the current object. Defaults to the name of the first object found in the caller namespace which + corresponds to `obj` (it will use a combination of the 3 first names if several names correspond to the same + object). + minvalue : scalar, optional + Minimum value allowed. + maxvalue : scalar, optional + Maximum value allowed. + readonly : bool, optional + Whether or not editing array values is forbidden. Defaults to False. + depth : int, optional + Stack depth where to look for variables. Defaults to 0 (where this function was called). + + Examples + -------- + >>> a1 = ndtest(3) # doctest: +SKIP + >>> a2 = ndtest(3) + 1 # doctest: +SKIP + >>> # will open an editor with all the arrays available at this point + >>> # (a1 and a2 in this case) + >>> edit() # doctest: +SKIP + >>> # will open an editor for a1 only + >>> edit(a1) # doctest: +SKIP + """ + try: + from larray_editor import edit + + edit(obj, title, minvalue, maxvalue, readonly, depth + 1) + except ImportError: + raise Exception('edit() is not available because the larray_editor package is not installed') + + +def compare(*args, **kwargs): + """ + Opens a new comparator window, comparing arrays or sessions. + + Parameters + ---------- + *args : LArrays or Sessions + Arrays or sessions to compare. + title : str, optional + Title for the window. Defaults to ''. + names : list of str, optional + Names for arrays or sessions being compared. Defaults to the name of the first objects found in the caller + namespace which correspond to the passed objects. + depth : int, optional + Stack depth where to look for variables. Defaults to 0 (where this function was called). + + Examples + -------- + >>> a1 = ndtest(3) # doctest: +SKIP + >>> a2 = ndtest(3) + 1 # doctest: +SKIP + >>> compare(a1, a2, title='first comparison') # doctest: +SKIP + >>> compare(a1 + 1, a2, title='second comparison', names=['a1+1', 'a2']) # doctest: +SKIP + """ + try: + from larray_editor import compare + + depth = kwargs.pop('depth', 0) + compare(*args, depth=depth + 1, **kwargs) + except ImportError: + raise Exception('compare() is not available because the larray_editor package is not installed') diff --git a/make_release.py b/make_release.py index 61ff8aa16..822edaa52 100644 --- a/make_release.py +++ b/make_release.py @@ -1,377 +1,95 @@ #!/usr/bin/python # coding=utf-8 +# Release script for LArray # Licence: GPLv3 +# Requires: +# * git from __future__ import print_function, unicode_literals -import errno -import fnmatch -import os -import re -import stat -import subprocess import sys -import zipfile +from os.path import abspath, dirname, join -from datetime import date -from os import chdir, makedirs -from os.path import exists, getsize, abspath, dirname -from shutil import copytree, copy2, rmtree as _rmtree -from subprocess import check_output, STDOUT, CalledProcessError +from subprocess import check_call +from releaser import make_release, update_feedstock, short, no, chdir, doechocall, set_config +from releaser.make_release import steps_funcs as make_release_steps +from releaser.update_feedstock import steps_funcs as update_feedstock_steps -try: - input = raw_input -except NameError: - pass +TMP_PATH = r"c:\tmp\larray_new_release" +TMP_PATH_CONDA = r"c:\tmp\larray_conda_new_release" +PACKAGE_NAME = "larray" +SRC_CODE = "larray" +SRC_DOC = join('doc', 'source') +GITHUB_REP = "https://github.com/larray-project/larray" +CONDA_FEEDSTOCK_REP = "https://github.com/larray-project/larray-feedstock.git" -if sys.version < '3': - import io - # add support for encoding. Slow on Python2, but that is not a problem - # given what we do with it. - open = io.open +LARRAY_READTHEDOCS = "http://larray.readthedocs.io/en/stable/" +LARRAY_ANNOUNCE_MAILING_LIST = "larray-announce@googlegroups.com" +LARRAY_USERS_GROUP = "larray-users@googlegroups.com" -# ------------- # -# generic tools # -# ------------- # +def update_metapackage(context): + if not context['public_release']: + return -def size2str(value): - unit = "bytes" - if value > 1024.0: - value /= 1024.0 - unit = "Kb" - if value > 1024.0: - value /= 1024.0 - unit = "Mb" - return "%.2f %s" % (value, unit) - else: - return "%d %s" % (value, unit) - - -def generate(fname, **kwargs): - with open('%s.tmpl' % fname) as in_f, open(fname, 'w') as out_f: - out_f.write(in_f.read().format(**kwargs)) - - -def _remove_readonly(function, path, excinfo): - if function in (os.rmdir, os.remove) and excinfo[1].errno == errno.EACCES: - # add write permission to owner - os.chmod(path, stat.S_IWUSR) - # retry removing - function(path) - else: - raise - - -def rmtree(path): - _rmtree(path, onerror=_remove_readonly) - - -def call(*args, **kwargs): - try: - res = check_output(*args, stderr=STDOUT, **kwargs) - if sys.version >= '3' and 'universal_newlines' not in kwargs: - res = res.decode('utf8') - return res - except CalledProcessError as e: - print(e.output) - raise e - - -def echocall(*args, **kwargs): - print(' '.join(args)) - return call(*args, **kwargs) - - -def git_remote_last_rev(url, branch=None): - """ - :param url: url of the remote repository - :param branch: an optional branch (defaults to 'refs/heads/master') - :return: name/hash of the last revision - """ - if branch is None: - branch = 'refs/heads/master' - output = call('git ls-remote %s %s' % (url, branch)) - for line in output.splitlines(): - if line.endswith(branch): - return line.split()[0] - raise Exception("Could not determine revision number") - - -def yes(msg, default='y'): - choices = ' (%s/%s) ' % tuple(c.capitalize() if c == default else c - for c in ('y', 'n')) - answer = None - while answer not in ('', 'y', 'n'): - if answer is not None: - print("answer should be 'y', 'n', or ") - answer = input(msg + choices).lower() - return (default if answer == '' else answer) == 'y' - - -def no(msg, default='n'): - return not yes(msg, default) - - -def do(description, func, *args, **kwargs): - print(description + '...', end=' ') - func(*args, **kwargs) - print("done.") - - -def allfiles(pattern, path='.'): - """ - like glob.glob(pattern) but also include files in subdirectories - """ - return (os.path.join(dirpath, f) - for dirpath, dirnames, files in os.walk(path) - for f in fnmatch.filter(files, pattern)) - - -def zip_pack(archivefname, filepattern): - with zipfile.ZipFile(archivefname, 'w', zipfile.ZIP_DEFLATED) as f: - for fname in allfiles(filepattern): - f.write(fname) - - -def zip_unpack(archivefname, dest=None): - with zipfile.ZipFile(archivefname) as f: - f.extractall(dest) - - -def short(rel_name): - return rel_name[:-2] if rel_name.endswith('.0') else rel_name - - -def strip_pretags(release_name): - """ - removes pre-release tags from a version string - - >>> str(strip_pretags('0.8')) - '0.8' - >>> str(strip_pretags('0.8alpha25')) - '0.8' - >>> str(strip_pretags('0.8.1rc1')) - '0.8.1' - """ - # 'a' needs to be searched for after 'beta' - for tag in ('rc', 'c', 'beta', 'b', 'alpha', 'a'): - release_name = re.sub(tag + '\d+', '', release_name) - return release_name - - -def isprerelease(release_name): - """ - tests whether the release name contains any pre-release tag - - >>> isprerelease('0.8') - False - >>> isprerelease('0.8alpha25') - True - >>> isprerelease('0.8.1rc1') - True - """ - return any(tag in release_name - for tag in ('rc', 'c', 'beta', 'b', 'alpha', 'a')) - - -# -------------------- # -# end of generic tools # -# -------------------- # + chdir(context['repository']) + version = short(context['release_name']) -def relname2fname(release_name): - short_version = short(strip_pretags(release_name)) - return r"version_%s.rst.inc" % short_version.replace('.', '_') + def fill(s): + return s.format(version=version) + # TODO: this should be echocall(redirect_stdout=False) + print(fill('Updating larrayenv metapackage to version {version}')) + check_call(['conda', 'metapackage', 'larrayenv', version, '--dependencies', fill('larray =={version}'), + fill('larray-editor =={version}'), fill('larray_eurostat =={version}'), + 'qtconsole', 'matplotlib', 'pyqt', 'qtpy', 'pytables', 'xlsxwriter', 'xlrd', 'openpyxl', 'xlwings']) -def release_changes(release_name): - fpath = r"doc\source\changes\\" + relname2fname(release_name) - with open(fpath, encoding='utf-8-sig') as f: - return f.read() +# TODO : move to larrayenv project +def announce_new_release(release_name): + import win32com.client as win32 + version = short(release_name) + outlook = win32.Dispatch('outlook.application') + mail = outlook.CreateItem(0) + mail.To = LARRAY_ANNOUNCE_MAILING_LIST + mail.Subject = "LArray {} released".format(version) + mail.Body = """\ +Hello all, -def build_doc(): - chdir('doc') - call('buildall.bat') - chdir('..') +We are pleased to announce that version {version} of LArray is now available. +The complete description of changes including examples can be found at: +{readthedocs}changes.html#version-{version_doc} -def update_changelog(release_name): - fname = relname2fname(release_name) - # include version changelog in changes.rst - fpath = r'doc\source\changes.rst' - changelog_template = """{title} -{underline} -Released on {date}. +As always, *any* feedback is very welcome, preferably on the larray-users +mailing list: {larray_users_group} (you need to register to be able to post). +""".format(version=version, readthedocs=LARRAY_READTHEDOCS, version_doc=version.replace('.', '-'), + larray_users_group=LARRAY_USERS_GROUP) + mail.Display(True) -.. include:: {fpath} - - -""" - - with open(fpath) as f: - lines = f.readlines() - title = "Version %s" % short(release_name) - if lines[5] == title + '\n': - print("changes.rst not modified (it already contains %s)" % title) - return - variables = dict(title=title, - underline="=" * len(title), - date=date.today().isoformat(), - fpath='changes/' + fname) - this_version = changelog_template.format(**variables) - lines[5:5] = this_version.splitlines(True) - with open(fpath, 'w') as f: - f.writelines(lines) - with open(fpath, encoding='utf-8-sig') as f: - print() - print('\n'.join(f.read().splitlines()[:20])) - if no('Does the full changelog look right?'): - exit(1) - call('git commit -m "include release changes (%s) in changes.rst" %s' - % (fname, fpath)) - - -def run_tests(): - """ - assumes to be in build - """ - call('nosetests -v --with-doctest') - - -def make_release(release_name=None, branch='master'): - if release_name is not None: - if 'pre' in release_name: - raise ValueError("'pre' is not supported anymore, use 'alpha' or " - "'beta' instead") - if '-' in release_name: - raise ValueError("- is not supported anymore") - - # releasing from the local clone has the advantage I can prepare the - # release offline and only push and upload it when I get back online - repository = abspath(dirname(__file__)) - s = "Using local repository at: %s !" % repository - print("\n", s, "\n", "=" * len(s), "\n", sep='') - - status = call('git status -s') - lines = status.splitlines() - if lines: - uncommited = sum(1 for line in lines if line.startswith(' M')) - untracked = sum(1 for line in lines if line.startswith('??')) - print('Warning: there are %d files with uncommitted changes ' - 'and %d untracked files:' % (uncommited, untracked)) - print(status) - if no('Do you want to continue?'): - exit(1) - - ahead = call('git log --format=format:%%H origin/%s..%s' % (branch, branch)) - num_ahead = len(ahead.splitlines()) - print("Branch '%s' is %d commits ahead of 'origin/%s'" - % (branch, num_ahead, branch), end='') - if num_ahead: - if yes(', do you want to push?'): - do('Pushing changes', call, 'git push') - else: - print() - - rev = git_remote_last_rev(repository, 'refs/heads/%s' % branch) - - public_release = release_name is not None - if release_name is None: - # take first 7 digits of commit hash - release_name = rev[:7] - - if no('Release version %s (%s)?' % (release_name, rev)): - exit(1) - - chdir(r'c:\tmp') - if exists('larray_new_release'): - rmtree('larray_new_release') - makedirs('larray_new_release') - chdir('larray_new_release') - - # make a temporary clone in /tmp. The goal is to make sure we do not - # include extra/unversioned files. For the -src archive, I don't think - # there is a risk given that we do it via git, but the risk is there for - # the bundles (src/build is not always clean, examples, editor, ...) - - # Since this script updates files (update_changelog), we - # need to get those changes propagated to GitHub. I do that by updating the - # temporary clone then push twice: first from the temporary clone to the - # "working copy clone" (eg ~/devel/project) then to GitHub from there. The - # alternative to modify the "working copy clone" directly is worse because - # it needs more complicated path handling that the 2 push approach. - do('Cloning', call, 'git clone -b %s %s build' % (branch, repository)) - - # ---------- # - chdir('build') - # ---------- # - - print() - print(call('git log -1')) - print() - - if no('Does that last commit look right?'): - exit(1) - - if public_release: - print(release_changes(release_name)) - if no('Does the release changelog look right?'): - exit(1) - - if public_release: - test_release = True - else: - test_release = yes('Do you want to test the executables after they are ' - 'created?') - - if test_release: - do('Testing release', run_tests) - - if public_release: - do('Updating changelog', update_changelog, release_name) - - do('Building doc', build_doc) - - do('Creating source archive', call, - r'git archive --format zip --output ..\LARRAY-%s-src.zip %s' - % (release_name, rev)) - - # ------- # - chdir('..') - # ------- # - - if public_release: - if no('Is the release looking good? If so, the tag will be created and ' - 'pushed.'): - exit(1) - - # ---------- # - chdir('build') - # ---------- # - - do('Tagging release', call, - 'git tag -a v%(name)s -m "tag release %(name)s"' - % {'name': release_name}) - # push the changelog commits to the branch (usually master) - # and the release tag (which refers to the last commit) - do('Pushing to %s' % repository, call, - 'git push origin %s --follow-tags' % branch) - - # ------- # - chdir('..') - # ------- # - - if public_release: - chdir(repository) - do('Pushing to GitHub', call, - 'git push origin %s --follow-tags' % branch) if __name__ == '__main__': - from sys import argv - - # chdir(r'c:\tmp') - # chdir('larray_new_release') - make_release(*argv[1:]) + argv = sys.argv + if len(argv) < 2: + print("Usage: {} [-c|--conda] release_name|dev [step|startstep:stopstep] [branch]".format(argv[0])) + print("make release steps:", ', '.join(f.__name__ for f, _ in make_release_steps)) + print("update conda-forge feedstock steps:", ', '.join(f.__name__ for f, _ in update_feedstock_steps)) + print("or") + print("Usage: {} -a|--announce release_name".format(argv[0])) + print("Usage: {} -m release_name".format(argv[0])) + sys.exit() + + local_repository = abspath(dirname(__file__)) + if argv[1] == '-m': + config = set_config(local_repository, PACKAGE_NAME, SRC_CODE, argv[2], branch='master', + src_documentation=SRC_DOC, tmp_dir=TMP_PATH) + update_metapackage(config) + elif argv[1] == '-a' or argv[1] == '--announce': + no("Is metapackage larrayenv updated?") + announce_new_release(argv[2]) + elif argv[1] == '-c' or argv[1] == '--conda': + update_feedstock(GITHUB_REP, CONDA_FEEDSTOCK_REP, SRC_CODE, *argv[2:], tmp_dir=TMP_PATH_CONDA) + else: + make_release(local_repository, PACKAGE_NAME, SRC_CODE, *argv[1:], src_documentation=SRC_DOC, tmp_dir=TMP_PATH) diff --git a/next_release.py b/next_release.py index 695c40fce..53c9cc83c 100644 --- a/next_release.py +++ b/next_release.py @@ -1,21 +1,19 @@ #!/usr/bin/python -# coding=utf-8 +# encoding: utf-8 # script to start a new release cycle # Licence: GPLv3 -from os.path import join -from make_release import relname2fname - - -def add_release(release_name): - # create "empty" change file for that release - fname = relname2fname(release_name) - with open(r'doc\source\changes\template.rst.inc') as f: - changes_template = f.read() - with open(join(r'doc\source\changes', fname), 'w') as f: - f.write(changes_template) +from os.path import abspath, dirname +from make_release import PACKAGE_NAME, SRC_CODE, SRC_DOC +from releaser import add_release if __name__ == '__main__': - from sys import argv + import sys + + argv = sys.argv + if len(argv) < 2: + print("Usage: {} release_name [branch]".format(argv[0])) + sys.exit() - add_release(*argv[1:]) + local_repository = abspath(dirname(__file__)) + add_release(local_repository, PACKAGE_NAME, SRC_CODE, *argv[1:], src_documentation=SRC_DOC) diff --git a/readthedocs.yml b/readthedocs.yml new file mode 100644 index 000000000..0129abe15 --- /dev/null +++ b/readthedocs.yml @@ -0,0 +1,5 @@ +conda: + file: doc/environment.yml +python: + version: 3 + setup_py_install: true diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 000000000..a664e4e09 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,10 @@ +[aliases] +test=pytest + +[tool:pytest] +testpaths = larray +# exclude (doc)tests from ufuncs (because docstrings are copied from numpy +# and many of those doctests are failing +addopts = -v --doctest-modules --ignore=larray/core/ufuncs.py --ignore=larray/ipfp +#--maxfail=1 --cov (requires pytest-cov) --pep8 (requires pytest-pep8) +#pep8maxlinelength = 119 diff --git a/setup.py b/setup.py index 8ea5eda38..132bc7ab4 100644 --- a/setup.py +++ b/setup.py @@ -9,22 +9,22 @@ def readlocal(fname): DISTNAME = 'larray' -VERSION = '0.12' -AUTHOR = 'Gaetan de Menten, Geert Bryon' +VERSION = '0.28' +AUTHOR = 'Gaetan de Menten, Geert Bryon, Johan Duyck, Alix Damman' AUTHOR_EMAIL = 'gdementen@gmail.com' DESCRIPTION = "N-D labeled arrays in Python" LONG_DESCRIPTION = readlocal("README.rst") INSTALL_REQUIRES = ['numpy >= 1.10', 'pandas >= 0.13.1'] -TESTS_REQUIRE = ['nose >= 1.0'] -TEST_SUITE = 'nose.collector' +TESTS_REQUIRE = ['pytest', 'pytest-pep8'] +SETUP_REQUIRES = ['pytest-runner'] LICENSE = 'GPLv3' +URL = 'https://github.com/larray-project/larray' PACKAGE_DATA = {'larray': ['tests/data/*']} -URL = 'https://github.com/liam2/larray' CLASSIFIERS = [ - 'Development Status :: 4 - Beta' - 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)' + 'Development Status :: 4 - Beta', + 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', 'Operating System :: OS Independent', 'Intended Audience :: Science/Research', 'Intended Audience :: Developers', @@ -32,9 +32,9 @@ def readlocal(fname): 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', 'Topic :: Scientific/Engineering', 'Topic :: Software Development :: Libraries', ] @@ -50,8 +50,8 @@ def readlocal(fname): long_description=LONG_DESCRIPTION, install_requires=INSTALL_REQUIRES, tests_require=TESTS_REQUIRE, + setup_requires=SETUP_REQUIRES, url=URL, - test_suite=TEST_SUITE, packages=find_packages(), package_data=PACKAGE_DATA, )